new names
This commit is contained in:
parent
718b702877
commit
06b956a553
67 changed files with 798 additions and 764 deletions
|
|
@ -35,6 +35,7 @@ docker run -p 8888:8888 -p 9999:9999 \
|
|||
-e HINDSIGHT_API_LLM_PROVIDER=openai \
|
||||
-e HINDSIGHT_API_LLM_API_KEY=$OPENAI_API_KEY \
|
||||
-e HINDSIGHT_API_LLM_MODEL=gpt-4o-mini \
|
||||
-v $HOME/.hindsight-docker:/home/hindsight/.pg0 \
|
||||
ghcr.io/vectorize-io/hindsight
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ def upgrade() -> None:
|
|||
'banks',
|
||||
sa.Column('bank_id', sa.Text(), nullable=False),
|
||||
sa.Column('name', sa.Text(), nullable=True),
|
||||
sa.Column('personality', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=False),
|
||||
sa.Column('disposition', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=False),
|
||||
sa.Column('background', sa.Text(), nullable=True),
|
||||
sa.Column('created_at', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||
sa.Column('updated_at', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
"""Rename fact_type 'bank' to 'interactions'
|
||||
"""Rename fact_type 'bank' to 'experience'
|
||||
|
||||
Revision ID: d9f6a3b4c5e2
|
||||
Revises: c8e5f2a3b4d1
|
||||
|
|
@ -20,14 +20,16 @@ def upgrade():
|
|||
# Drop old check constraint FIRST (before updating data)
|
||||
op.drop_constraint('memory_units_fact_type_check', 'memory_units', type_='check')
|
||||
|
||||
# Update existing 'bank' values to 'interactions'
|
||||
op.execute("UPDATE memory_units SET fact_type = 'interactions' WHERE fact_type = 'bank'")
|
||||
# Update existing 'bank' values to 'experience'
|
||||
op.execute("UPDATE memory_units SET fact_type = 'experience' WHERE fact_type = 'bank'")
|
||||
# Also update any 'interactions' values (in case of partial migration)
|
||||
op.execute("UPDATE memory_units SET fact_type = 'experience' WHERE fact_type = 'interactions'")
|
||||
|
||||
# Create new check constraint with 'interactions' instead of 'bank'
|
||||
# Create new check constraint with 'experience' instead of 'bank'
|
||||
op.create_check_constraint(
|
||||
'memory_units_fact_type_check',
|
||||
'memory_units',
|
||||
"fact_type IN ('world', 'interactions', 'opinion', 'observation')"
|
||||
"fact_type IN ('world', 'experience', 'opinion', 'observation')"
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -35,8 +37,8 @@ def downgrade():
|
|||
# Drop new check constraint FIRST
|
||||
op.drop_constraint('memory_units_fact_type_check', 'memory_units', type_='check')
|
||||
|
||||
# Update 'interactions' back to 'bank'
|
||||
op.execute("UPDATE memory_units SET fact_type = 'bank' WHERE fact_type = 'interactions'")
|
||||
# Update 'experience' back to 'bank'
|
||||
op.execute("UPDATE memory_units SET fact_type = 'bank' WHERE fact_type = 'experience'")
|
||||
|
||||
# Recreate old check constraint
|
||||
op.create_check_constraint(
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ from .http import (
|
|||
ReflectRequest,
|
||||
ReflectResponse,
|
||||
CreateBankRequest,
|
||||
PersonalityTraits,
|
||||
DispositionTraits,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
|
|
@ -100,5 +100,5 @@ __all__ = [
|
|||
"ReflectRequest",
|
||||
"ReflectResponse",
|
||||
"CreateBankRequest",
|
||||
"PersonalityTraits",
|
||||
"DispositionTraits",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class RecallRequest(BaseModel):
|
|||
model_config = ConfigDict(json_schema_extra={
|
||||
"example": {
|
||||
"query": "What did Alice say about machine learning?",
|
||||
"types": ["world", "interactions"],
|
||||
"types": ["world", "experience"],
|
||||
"budget": "mid",
|
||||
"max_tokens": 4096,
|
||||
"trace": True,
|
||||
|
|
@ -131,7 +131,7 @@ class RecallResult(BaseModel):
|
|||
|
||||
id: str
|
||||
text: str
|
||||
type: Optional[str] = None # fact type: world, interactions, opinion, observation
|
||||
type: Optional[str] = None # fact type: world, experience, opinion, observation
|
||||
entities: Optional[List[str]] = None # Entity names mentioned in this fact
|
||||
context: Optional[str] = None
|
||||
occurred_start: Optional[str] = None # ISO format date when the event started
|
||||
|
|
@ -397,7 +397,7 @@ class ReflectFact(BaseModel):
|
|||
|
||||
id: Optional[str] = None
|
||||
text: str
|
||||
type: Optional[str] = None # fact type: world, interactions, opinion
|
||||
type: Optional[str] = None # fact type: world, experience, opinion
|
||||
context: Optional[str] = None
|
||||
occurred_start: Optional[str] = None
|
||||
occurred_end: Optional[str] = None
|
||||
|
|
@ -417,7 +417,7 @@ class ReflectResponse(BaseModel):
|
|||
{
|
||||
"id": "456",
|
||||
"text": "I discussed AI applications last week",
|
||||
"type": "interactions"
|
||||
"type": "experience"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -438,8 +438,8 @@ class BanksResponse(BaseModel):
|
|||
banks: List[str]
|
||||
|
||||
|
||||
class PersonalityTraits(BaseModel):
|
||||
"""Personality traits based on Big Five model."""
|
||||
class DispositionTraits(BaseModel):
|
||||
"""Disposition traits based on Big Five model."""
|
||||
model_config = ConfigDict(json_schema_extra={
|
||||
"example": {
|
||||
"openness": 0.8,
|
||||
|
|
@ -456,7 +456,7 @@ class PersonalityTraits(BaseModel):
|
|||
extraversion: float = Field(ge=0.0, le=1.0, description="Extraversion (0-1)")
|
||||
agreeableness: float = Field(ge=0.0, le=1.0, description="Agreeableness (0-1)")
|
||||
neuroticism: float = Field(ge=0.0, le=1.0, description="Neuroticism (0-1)")
|
||||
bias_strength: float = Field(ge=0.0, le=1.0, description="How strongly personality influences opinions (0-1)")
|
||||
bias_strength: float = Field(ge=0.0, le=1.0, description="How strongly disposition influences opinions (0-1)")
|
||||
|
||||
|
||||
class BankProfileResponse(BaseModel):
|
||||
|
|
@ -465,7 +465,7 @@ class BankProfileResponse(BaseModel):
|
|||
"example": {
|
||||
"bank_id": "user123",
|
||||
"name": "Alice",
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"openness": 0.8,
|
||||
"conscientiousness": 0.6,
|
||||
"extraversion": 0.5,
|
||||
|
|
@ -479,13 +479,13 @@ class BankProfileResponse(BaseModel):
|
|||
|
||||
bank_id: str
|
||||
name: str
|
||||
personality: PersonalityTraits
|
||||
disposition: DispositionTraits
|
||||
background: str
|
||||
|
||||
|
||||
class UpdatePersonalityRequest(BaseModel):
|
||||
"""Request model for updating personality traits."""
|
||||
personality: PersonalityTraits
|
||||
class UpdateDispositionRequest(BaseModel):
|
||||
"""Request model for updating disposition traits."""
|
||||
disposition: DispositionTraits
|
||||
|
||||
|
||||
class AddBackgroundRequest(BaseModel):
|
||||
|
|
@ -493,14 +493,14 @@ class AddBackgroundRequest(BaseModel):
|
|||
model_config = ConfigDict(json_schema_extra={
|
||||
"example": {
|
||||
"content": "I was born in Texas",
|
||||
"update_personality": True
|
||||
"update_disposition": True
|
||||
}
|
||||
})
|
||||
|
||||
content: str = Field(description="New background information to add or merge")
|
||||
update_personality: bool = Field(
|
||||
update_disposition: bool = Field(
|
||||
default=True,
|
||||
description="If true, infer Big Five personality traits from the merged background (default: true)"
|
||||
description="If true, infer Big Five disposition traits from the merged background (default: true)"
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -509,7 +509,7 @@ class BackgroundResponse(BaseModel):
|
|||
model_config = ConfigDict(json_schema_extra={
|
||||
"example": {
|
||||
"background": "I was born in Texas. I am a software engineer with 10 years of experience.",
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"openness": 0.7,
|
||||
"conscientiousness": 0.6,
|
||||
"extraversion": 0.5,
|
||||
|
|
@ -521,14 +521,14 @@ class BackgroundResponse(BaseModel):
|
|||
})
|
||||
|
||||
background: str
|
||||
personality: Optional[PersonalityTraits] = None
|
||||
disposition: Optional[DispositionTraits] = None
|
||||
|
||||
|
||||
class BankListItem(BaseModel):
|
||||
"""Bank list item with profile summary."""
|
||||
bank_id: str
|
||||
name: str
|
||||
personality: PersonalityTraits
|
||||
disposition: DispositionTraits
|
||||
background: str
|
||||
created_at: Optional[str] = None
|
||||
updated_at: Optional[str] = None
|
||||
|
|
@ -542,7 +542,7 @@ class BankListResponse(BaseModel):
|
|||
{
|
||||
"bank_id": "user123",
|
||||
"name": "Alice",
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"openness": 0.5,
|
||||
"conscientiousness": 0.5,
|
||||
"extraversion": 0.5,
|
||||
|
|
@ -566,7 +566,7 @@ class CreateBankRequest(BaseModel):
|
|||
model_config = ConfigDict(json_schema_extra={
|
||||
"example": {
|
||||
"name": "Alice",
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"openness": 0.8,
|
||||
"conscientiousness": 0.6,
|
||||
"extraversion": 0.5,
|
||||
|
|
@ -579,7 +579,7 @@ class CreateBankRequest(BaseModel):
|
|||
})
|
||||
|
||||
name: Optional[str] = None
|
||||
personality: Optional[PersonalityTraits] = None
|
||||
disposition: Optional[DispositionTraits] = None
|
||||
background: Optional[str] = None
|
||||
|
||||
|
||||
|
|
@ -833,7 +833,7 @@ def _register_routes(app: FastAPI):
|
|||
"/v1/default/banks/{bank_id}/graph",
|
||||
response_model=GraphDataResponse,
|
||||
summary="Get memory graph data",
|
||||
description="Retrieve graph data for visualization, optionally filtered by type (world/interactions/opinion). Limited to 1000 most recent items.",
|
||||
description="Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.",
|
||||
operation_id="get_graph"
|
||||
)
|
||||
async def api_graph(bank_id: str,
|
||||
|
|
@ -871,7 +871,7 @@ def _register_routes(app: FastAPI):
|
|||
|
||||
Args:
|
||||
bank_id: Memory Bank ID (from path)
|
||||
type: Filter by fact type (world, interactions, opinion)
|
||||
type: Filter by fact type (world, experience, opinion)
|
||||
q: Search query for full-text search (searches text and context)
|
||||
limit: Maximum number of results (default: 100)
|
||||
offset: Offset for pagination (default: 0)
|
||||
|
|
@ -901,7 +901,7 @@ def _register_routes(app: FastAPI):
|
|||
|
||||
The type parameter is optional and must be one of:
|
||||
- 'world': General knowledge about people, places, events, and things that happen
|
||||
- 'interactions': Memories about interactions, conversations, actions taken, and tasks performed
|
||||
- 'experience': Memories about experience, conversations, actions taken, and tasks performed
|
||||
- 'opinion': The bank's formed beliefs, perspectives, and viewpoints
|
||||
|
||||
Set include_entities=true to get entity observations alongside recall results.
|
||||
|
|
@ -914,10 +914,10 @@ def _register_routes(app: FastAPI):
|
|||
|
||||
try:
|
||||
# Validate types
|
||||
valid_fact_types = ["world", "interactions", "opinion"]
|
||||
valid_fact_types = ["world", "experience", "opinion"]
|
||||
|
||||
# Default to world, interactions, opinion if not specified (exclude observation by default)
|
||||
fact_types = request.types if request.types else ["world", "interactions", "opinion"]
|
||||
# Default to world, experience, opinion if not specified (exclude observation by default)
|
||||
fact_types = request.types if request.types else ["world", "experience", "opinion"]
|
||||
for ft in fact_types:
|
||||
if ft not in valid_fact_types:
|
||||
raise HTTPException(
|
||||
|
|
@ -1026,7 +1026,7 @@ def _register_routes(app: FastAPI):
|
|||
Reflect and formulate an answer using bank identity, world facts, and opinions.
|
||||
|
||||
This endpoint:
|
||||
1. Retrieves interactions (conversations and events)
|
||||
1. Retrieves experience (conversations and events)
|
||||
2. Retrieves world facts relevant to the query
|
||||
3. Retrieves existing opinions (bank's perspectives)
|
||||
4. Uses LLM to formulate a contextual answer
|
||||
|
|
@ -1579,19 +1579,19 @@ This operation cannot be undone.
|
|||
"/v1/default/banks/{bank_id}/profile",
|
||||
response_model=BankProfileResponse,
|
||||
summary="Get memory bank profile",
|
||||
description="Get personality traits and background for a memory bank. Auto-creates agent with defaults if not exists.",
|
||||
description="Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.",
|
||||
operation_id="get_bank_profile"
|
||||
)
|
||||
async def api_get_bank_profile(bank_id: str):
|
||||
"""Get memory bank profile (personality + background)."""
|
||||
"""Get memory bank profile (disposition + background)."""
|
||||
try:
|
||||
profile = await app.state.memory.get_bank_profile(bank_id)
|
||||
# Convert PersonalityTraits object to dict for Pydantic
|
||||
personality_dict = profile["personality"].model_dump() if hasattr(profile["personality"], 'model_dump') else dict(profile["personality"])
|
||||
# Convert DispositionTraits object to dict for Pydantic
|
||||
disposition_dict = profile["disposition"].model_dump() if hasattr(profile["disposition"], 'model_dump') else dict(profile["disposition"])
|
||||
return BankProfileResponse(
|
||||
bank_id=bank_id,
|
||||
name=profile["name"],
|
||||
personality=PersonalityTraits(**personality_dict),
|
||||
disposition=DispositionTraits(**disposition_dict),
|
||||
background=profile["background"]
|
||||
)
|
||||
except Exception as e:
|
||||
|
|
@ -1604,28 +1604,28 @@ This operation cannot be undone.
|
|||
@app.put(
|
||||
"/v1/default/banks/{bank_id}/profile",
|
||||
response_model=BankProfileResponse,
|
||||
summary="Update memory bank personality",
|
||||
description="Update bank's Big Five personality traits and bias strength",
|
||||
operation_id="update_bank_personality"
|
||||
summary="Update memory bank disposition",
|
||||
description="Update bank's Big Five disposition traits and bias strength",
|
||||
operation_id="update_bank_disposition"
|
||||
)
|
||||
async def api_update_bank_personality(bank_id: str,
|
||||
request: UpdatePersonalityRequest
|
||||
async def api_update_bank_disposition(bank_id: str,
|
||||
request: UpdateDispositionRequest
|
||||
):
|
||||
"""Update bank personality traits."""
|
||||
"""Update bank disposition traits."""
|
||||
try:
|
||||
# Update personality
|
||||
await app.state.memory.update_bank_personality(
|
||||
# Update disposition
|
||||
await app.state.memory.update_bank_disposition(
|
||||
bank_id,
|
||||
request.personality.model_dump()
|
||||
request.disposition.model_dump()
|
||||
)
|
||||
|
||||
# Get updated profile
|
||||
profile = await app.state.memory.get_bank_profile(bank_id)
|
||||
personality_dict = profile["personality"].model_dump() if hasattr(profile["personality"], 'model_dump') else dict(profile["personality"])
|
||||
disposition_dict = profile["disposition"].model_dump() if hasattr(profile["disposition"], 'model_dump') else dict(profile["disposition"])
|
||||
return BankProfileResponse(
|
||||
bank_id=bank_id,
|
||||
name=profile["name"],
|
||||
personality=PersonalityTraits(**personality_dict),
|
||||
disposition=DispositionTraits(**disposition_dict),
|
||||
background=profile["background"]
|
||||
)
|
||||
except Exception as e:
|
||||
|
|
@ -1639,23 +1639,23 @@ This operation cannot be undone.
|
|||
"/v1/default/banks/{bank_id}/background",
|
||||
response_model=BackgroundResponse,
|
||||
summary="Add/merge memory bank background",
|
||||
description="Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.",
|
||||
description="Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.",
|
||||
operation_id="add_bank_background"
|
||||
)
|
||||
async def api_add_bank_background(bank_id: str,
|
||||
request: AddBackgroundRequest
|
||||
):
|
||||
"""Add or merge bank background information. Optionally infer personality traits."""
|
||||
"""Add or merge bank background information. Optionally infer disposition traits."""
|
||||
try:
|
||||
result = await app.state.memory.merge_bank_background(
|
||||
bank_id,
|
||||
request.content,
|
||||
update_personality=request.update_personality
|
||||
update_disposition=request.update_disposition
|
||||
)
|
||||
|
||||
response = BackgroundResponse(background=result["background"])
|
||||
if "personality" in result:
|
||||
response.personality = PersonalityTraits(**result["personality"])
|
||||
if "disposition" in result:
|
||||
response.disposition = DispositionTraits(**result["disposition"])
|
||||
|
||||
return response
|
||||
except Exception as e:
|
||||
|
|
@ -1669,13 +1669,13 @@ This operation cannot be undone.
|
|||
"/v1/default/banks/{bank_id}",
|
||||
response_model=BankProfileResponse,
|
||||
summary="Create or update memory bank",
|
||||
description="Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.",
|
||||
description="Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.",
|
||||
operation_id="create_or_update_bank"
|
||||
)
|
||||
async def api_create_or_update_bank(bank_id: str,
|
||||
request: CreateBankRequest
|
||||
):
|
||||
"""Create or update an agent with personality and background."""
|
||||
"""Create or update an agent with disposition and background."""
|
||||
try:
|
||||
# Get existing profile or create with defaults
|
||||
profile = await app.state.memory.get_bank_profile(bank_id)
|
||||
|
|
@ -1696,13 +1696,13 @@ This operation cannot be undone.
|
|||
)
|
||||
profile["name"] = request.name
|
||||
|
||||
# Update personality if provided
|
||||
if request.personality is not None:
|
||||
await app.state.memory.update_bank_personality(
|
||||
# Update disposition if provided
|
||||
if request.disposition is not None:
|
||||
await app.state.memory.update_bank_disposition(
|
||||
bank_id,
|
||||
request.personality.model_dump()
|
||||
request.disposition.model_dump()
|
||||
)
|
||||
profile["personality"] = request.personality.model_dump()
|
||||
profile["disposition"] = request.disposition.model_dump()
|
||||
|
||||
# Update background if provided (replace, not merge)
|
||||
if request.background is not None:
|
||||
|
|
@ -1722,11 +1722,11 @@ This operation cannot be undone.
|
|||
|
||||
# Get final profile
|
||||
final_profile = await app.state.memory.get_bank_profile(bank_id)
|
||||
personality_dict = final_profile["personality"].model_dump() if hasattr(final_profile["personality"], 'model_dump') else dict(final_profile["personality"])
|
||||
disposition_dict = final_profile["disposition"].model_dump() if hasattr(final_profile["disposition"], 'model_dump') else dict(final_profile["disposition"])
|
||||
return BankProfileResponse(
|
||||
bank_id=bank_id,
|
||||
name=final_profile["name"],
|
||||
personality=PersonalityTraits(**personality_dict),
|
||||
disposition=DispositionTraits(**disposition_dict),
|
||||
background=final_profile["background"]
|
||||
)
|
||||
except Exception as e:
|
||||
|
|
@ -1852,11 +1852,11 @@ This operation cannot be undone.
|
|||
"/v1/default/banks/{bank_id}/memories",
|
||||
response_model=DeleteResponse,
|
||||
summary="Clear memory bank memories",
|
||||
description="Delete memory units for a memory bank. Optionally filter by type (world, interactions, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.",
|
||||
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.",
|
||||
operation_id="clear_bank_memories"
|
||||
)
|
||||
async def api_clear_bank_memories(bank_id: str,
|
||||
type: Optional[str] = Query(None, description="Optional fact type filter (world, interactions, opinion)")
|
||||
type: Optional[str] = Query(None, description="Optional fact type filter (world, experience, opinion)")
|
||||
):
|
||||
"""Clear memories for a memory bank, optionally filtered by type."""
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ def create_mcp_server(memory: MemoryEngine) -> FastMCP:
|
|||
search_result = await memory.recall_async(
|
||||
bank_id=bank_id,
|
||||
query=query,
|
||||
fact_type=["world", "interactions", "opinion"],
|
||||
fact_type=["world", "experience", "opinion"],
|
||||
budget=Budget.LOW
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class MemoryEngine:
|
|||
- Embedding generation for semantic search
|
||||
- Entity, temporal, and semantic link creation
|
||||
- Think operations for formulating answers with opinions
|
||||
- bank profile and personality management
|
||||
- bank profile and disposition management
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
|
|
@ -676,7 +676,7 @@ class MemoryEngine:
|
|||
context: Context about when/why this memory was formed
|
||||
event_date: When the event occurred (defaults to now)
|
||||
document_id: Optional document ID for tracking (always upserts if document already exists)
|
||||
fact_type_override: Override fact type ('world', 'interactions', 'opinion')
|
||||
fact_type_override: Override fact type ('world', 'experience', 'opinion')
|
||||
confidence_score: Confidence score for opinions (0.0 to 1.0)
|
||||
|
||||
Returns:
|
||||
|
|
@ -728,7 +728,7 @@ class MemoryEngine:
|
|||
- "document_id" (optional): Document ID for this specific content item
|
||||
document_id: **DEPRECATED** - Use "document_id" key in each content dict instead.
|
||||
Applies the same document_id to ALL content items that don't specify their own.
|
||||
fact_type_override: Override fact type for all facts ('world', 'interactions', 'opinion')
|
||||
fact_type_override: Override fact type for all facts ('world', 'experience', 'opinion')
|
||||
confidence_score: Confidence score for opinions (0.0 to 1.0)
|
||||
|
||||
Returns:
|
||||
|
|
@ -896,7 +896,7 @@ class MemoryEngine:
|
|||
Args:
|
||||
bank_id: bank ID to recall for
|
||||
query: Recall query
|
||||
fact_type: Required filter for fact type ('world', 'interactions', or 'opinion')
|
||||
fact_type: Required filter for fact type ('world', 'experience', or 'opinion')
|
||||
budget: Budget level for graph traversal (low=100, mid=300, high=600 units)
|
||||
max_tokens: Maximum tokens to return (counts only 'text' field, default 4096)
|
||||
enable_trace: If True, returns detailed trace object
|
||||
|
|
@ -936,7 +936,7 @@ class MemoryEngine:
|
|||
Args:
|
||||
bank_id: bank ID to recall for
|
||||
query: Recall query
|
||||
fact_type: List of fact types to recall (e.g., ['world', 'interactions'])
|
||||
fact_type: List of fact types to recall (e.g., ['world', 'experience'])
|
||||
budget: Budget level for graph traversal (low=100, mid=300, high=600 units)
|
||||
max_tokens: Maximum tokens to return (counts only 'text' field, default 4096)
|
||||
Results are returned until token budget is reached, stopping before
|
||||
|
|
@ -1682,7 +1682,7 @@ class MemoryEngine:
|
|||
|
||||
Args:
|
||||
bank_id: bank ID to delete
|
||||
fact_type: Optional fact type filter (world, bank, opinion). If provided, only deletes memories of that type.
|
||||
fact_type: Optional fact type filter (world, experience, opinion). If provided, only deletes memories of that type.
|
||||
|
||||
Returns:
|
||||
Dictionary with counts of deleted items
|
||||
|
|
@ -1738,7 +1738,7 @@ class MemoryEngine:
|
|||
|
||||
Args:
|
||||
bank_id: Filter by bank ID
|
||||
fact_type: Filter by fact type (world, bank, opinion)
|
||||
fact_type: Filter by fact type (world, experience, opinion)
|
||||
|
||||
Returns:
|
||||
Dict with nodes, edges, and table_rows
|
||||
|
|
@ -1912,7 +1912,7 @@ class MemoryEngine:
|
|||
|
||||
Args:
|
||||
bank_id: Filter by bank ID
|
||||
fact_type: Filter by fact type (world, bank, opinion)
|
||||
fact_type: Filter by fact type (world, experience, opinion)
|
||||
search_query: Full-text search query (searches text and context fields)
|
||||
limit: Maximum number of results to return
|
||||
offset: Offset for pagination
|
||||
|
|
@ -2485,55 +2485,55 @@ Guidelines:
|
|||
|
||||
async def get_bank_profile(self, bank_id: str) -> "bank_utils.BankProfile":
|
||||
"""
|
||||
Get bank profile (name, personality + background).
|
||||
Get bank profile (name, disposition + background).
|
||||
Auto-creates agent with default values if not exists.
|
||||
|
||||
Args:
|
||||
bank_id: bank IDentifier
|
||||
|
||||
Returns:
|
||||
BankProfile with name, typed PersonalityTraits, and background
|
||||
BankProfile with name, typed DispositionTraits, and background
|
||||
"""
|
||||
pool = await self._get_pool()
|
||||
return await bank_utils.get_bank_profile(pool, bank_id)
|
||||
|
||||
async def update_bank_personality(
|
||||
async def update_bank_disposition(
|
||||
self,
|
||||
bank_id: str,
|
||||
personality: Dict[str, float]
|
||||
disposition: Dict[str, float]
|
||||
) -> None:
|
||||
"""
|
||||
Update bank personality traits.
|
||||
Update bank disposition traits.
|
||||
|
||||
Args:
|
||||
bank_id: bank IDentifier
|
||||
personality: Dict with Big Five traits + bias_strength (all 0-1)
|
||||
disposition: Dict with Big Five traits + bias_strength (all 0-1)
|
||||
"""
|
||||
pool = await self._get_pool()
|
||||
await bank_utils.update_bank_personality(pool, bank_id, personality)
|
||||
await bank_utils.update_bank_disposition(pool, bank_id, disposition)
|
||||
|
||||
async def merge_bank_background(
|
||||
self,
|
||||
bank_id: str,
|
||||
new_info: str,
|
||||
update_personality: bool = True
|
||||
update_disposition: bool = True
|
||||
) -> dict:
|
||||
"""
|
||||
Merge new background information with existing background using LLM.
|
||||
Normalizes to first person ("I") and resolves conflicts.
|
||||
Optionally infers personality traits from the merged background.
|
||||
Optionally infers disposition traits from the merged background.
|
||||
|
||||
Args:
|
||||
bank_id: bank IDentifier
|
||||
new_info: New background information to add/merge
|
||||
update_personality: If True, infer Big Five traits from background (default: True)
|
||||
update_disposition: If True, infer Big Five traits from background (default: True)
|
||||
|
||||
Returns:
|
||||
Dict with 'background' (str) and optionally 'personality' (dict) keys
|
||||
Dict with 'background' (str) and optionally 'disposition' (dict) keys
|
||||
"""
|
||||
pool = await self._get_pool()
|
||||
return await bank_utils.merge_bank_background(
|
||||
pool, self._llm_config, bank_id, new_info, update_personality
|
||||
pool, self._llm_config, bank_id, new_info, update_disposition
|
||||
)
|
||||
|
||||
async def list_banks(self) -> list:
|
||||
|
|
@ -2541,7 +2541,7 @@ Guidelines:
|
|||
List all agents in the system.
|
||||
|
||||
Returns:
|
||||
List of dicts with bank_id, name, personality, background, created_at, updated_at
|
||||
List of dicts with bank_id, name, disposition, background, created_at, updated_at
|
||||
"""
|
||||
pool = await self._get_pool()
|
||||
return await bank_utils.list_banks(pool)
|
||||
|
|
@ -2559,7 +2559,7 @@ Guidelines:
|
|||
Reflect and formulate an answer using bank identity, world facts, and opinions.
|
||||
|
||||
This method:
|
||||
1. Retrieves interactions (conversations and events)
|
||||
1. Retrieves experience (conversations and events)
|
||||
2. Retrieves world facts (general knowledge)
|
||||
3. Retrieves existing opinions (bank's formed perspectives)
|
||||
4. Uses LLM to formulate an answer
|
||||
|
|
@ -2575,7 +2575,7 @@ Guidelines:
|
|||
Returns:
|
||||
ReflectResult containing:
|
||||
- text: Plain text answer (no markdown)
|
||||
- based_on: Dict with 'world', 'interactions', and 'opinion' fact lists (MemoryFact objects)
|
||||
- based_on: Dict with 'world', 'experience', and 'opinion' fact lists (MemoryFact objects)
|
||||
- new_opinions: List of newly formed opinions
|
||||
"""
|
||||
# Use cached LLM config
|
||||
|
|
@ -2589,7 +2589,7 @@ Guidelines:
|
|||
budget=budget,
|
||||
max_tokens=4096,
|
||||
enable_trace=False,
|
||||
fact_type=['interactions', 'world', 'opinion'],
|
||||
fact_type=['experience', 'world', 'opinion'],
|
||||
include_entities=True
|
||||
)
|
||||
|
||||
|
|
@ -2597,7 +2597,7 @@ Guidelines:
|
|||
logger.info(f"[THINK] Search returned {len(all_results)} results")
|
||||
|
||||
# Split results by fact type for structured response
|
||||
agent_results = [r for r in all_results if r.fact_type == 'interactions']
|
||||
agent_results = [r for r in all_results if r.fact_type == 'experience']
|
||||
world_results = [r for r in all_results if r.fact_type == 'world']
|
||||
opinion_results = [r for r in all_results if r.fact_type == 'opinion']
|
||||
|
||||
|
|
@ -2610,10 +2610,10 @@ Guidelines:
|
|||
|
||||
logger.info(f"[THINK] Formatted facts - agent: {len(agent_facts_text)} chars, world: {len(world_facts_text)} chars, opinion: {len(opinion_facts_text)} chars")
|
||||
|
||||
# Get bank profile (name, personality + background)
|
||||
# Get bank profile (name, disposition + background)
|
||||
profile = await self.get_bank_profile(bank_id)
|
||||
name = profile["name"]
|
||||
personality = profile["personality"] # Typed as PersonalityTraits
|
||||
disposition = profile["disposition"] # Typed as DispositionTraits
|
||||
background = profile["background"]
|
||||
|
||||
# Build the prompt
|
||||
|
|
@ -2623,14 +2623,14 @@ Guidelines:
|
|||
opinion_facts_text=opinion_facts_text,
|
||||
query=query,
|
||||
name=name,
|
||||
personality=personality,
|
||||
disposition=disposition,
|
||||
background=background,
|
||||
context=context,
|
||||
)
|
||||
|
||||
logger.info(f"[THINK] Full prompt length: {len(prompt)} chars")
|
||||
|
||||
system_message = think_utils.get_system_message(personality)
|
||||
system_message = think_utils.get_system_message(disposition)
|
||||
|
||||
answer_text = await self._llm_config.call(
|
||||
messages=[
|
||||
|
|
@ -2657,7 +2657,7 @@ Guidelines:
|
|||
text=answer_text,
|
||||
based_on={
|
||||
"world": world_results,
|
||||
"interactions": agent_results,
|
||||
"experience": agent_results,
|
||||
"opinion": opinion_results
|
||||
},
|
||||
new_opinions=[] # Opinions are being extracted asynchronously
|
||||
|
|
@ -2871,7 +2871,7 @@ Guidelines:
|
|||
JOIN unit_entities ue ON mu.id = ue.unit_id
|
||||
WHERE mu.bank_id = $1
|
||||
AND ue.entity_id = $2
|
||||
AND mu.fact_type IN ('world', 'interactions')
|
||||
AND mu.fact_type IN ('world', 'experience')
|
||||
ORDER BY mu.occurred_start DESC
|
||||
LIMIT 50
|
||||
""",
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ from typing import Optional, List, Dict, Any
|
|||
from pydantic import BaseModel, Field, ConfigDict
|
||||
|
||||
|
||||
class PersonalityTraits(BaseModel):
|
||||
class DispositionTraits(BaseModel):
|
||||
"""
|
||||
Personality traits for a bank using the Big Five model.
|
||||
Disposition traits for a bank using the Big Five model.
|
||||
|
||||
All traits are scored 0.0-1.0 where higher values indicate stronger presence of the trait.
|
||||
"""
|
||||
|
|
@ -21,7 +21,7 @@ class PersonalityTraits(BaseModel):
|
|||
extraversion: float = Field(description="Extraversion and sociability (0.0-1.0)")
|
||||
agreeableness: float = Field(description="Agreeableness and cooperation (0.0-1.0)")
|
||||
neuroticism: float = Field(description="Emotional sensitivity and neuroticism (0.0-1.0)")
|
||||
bias_strength: float = Field(description="How strongly personality influences thinking (0.0-1.0)")
|
||||
bias_strength: float = Field(description="How strongly disposition influences thinking (0.0-1.0)")
|
||||
|
||||
model_config = ConfigDict(json_schema_extra={
|
||||
"example": {
|
||||
|
|
@ -61,7 +61,7 @@ class MemoryFact(BaseModel):
|
|||
|
||||
id: str = Field(description="Unique identifier for the memory fact")
|
||||
text: str = Field(description="The actual text content of the memory")
|
||||
fact_type: str = Field(description="Type of fact: 'world', 'interactions', 'opinion', or 'observation'")
|
||||
fact_type: str = Field(description="Type of fact: 'world', 'experience', 'opinion', or 'observation'")
|
||||
entities: Optional[List[str]] = Field(None, description="Entity names mentioned in this fact")
|
||||
context: Optional[str] = Field(None, description="Additional context for the memory")
|
||||
occurred_start: Optional[str] = Field(None, description="ISO format date when the event started occurring")
|
||||
|
|
@ -142,7 +142,7 @@ class ReflectResult(BaseModel):
|
|||
"occurred_end": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
],
|
||||
"interactions": [],
|
||||
"experience": [],
|
||||
"opinion": []
|
||||
},
|
||||
"new_opinions": [
|
||||
|
|
@ -153,7 +153,7 @@ class ReflectResult(BaseModel):
|
|||
|
||||
text: str = Field(description="The formulated answer text")
|
||||
based_on: Dict[str, List[MemoryFact]] = Field(
|
||||
description="Facts used to formulate the answer, organized by type (world, interactions, opinion)"
|
||||
description="Facts used to formulate the answer, organized by type (world, experience, opinion)"
|
||||
)
|
||||
new_opinions: List[str] = Field(
|
||||
default_factory=list,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
bank profile utilities for personality and background management.
|
||||
bank profile utilities for disposition and background management.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
|
@ -8,11 +8,11 @@ import re
|
|||
from typing import Dict, Optional, TypedDict
|
||||
from pydantic import BaseModel, Field
|
||||
from ..db_utils import acquire_with_retry
|
||||
from ..response_models import PersonalityTraits
|
||||
from ..response_models import DispositionTraits
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_PERSONALITY = {
|
||||
DEFAULT_DISPOSITION = {
|
||||
"openness": 0.5,
|
||||
"conscientiousness": 0.5,
|
||||
"extraversion": 0.5,
|
||||
|
|
@ -25,19 +25,19 @@ DEFAULT_PERSONALITY = {
|
|||
class BankProfile(TypedDict):
|
||||
"""Type for bank profile data."""
|
||||
name: str
|
||||
personality: PersonalityTraits
|
||||
disposition: DispositionTraits
|
||||
background: str
|
||||
|
||||
|
||||
class BackgroundMergeResponse(BaseModel):
|
||||
"""LLM response for background merge with personality inference."""
|
||||
"""LLM response for background merge with disposition inference."""
|
||||
background: str = Field(description="Merged background in first person perspective")
|
||||
personality: PersonalityTraits = Field(description="Inferred Big Five personality traits")
|
||||
disposition: DispositionTraits = Field(description="Inferred Big Five disposition traits")
|
||||
|
||||
|
||||
async def get_bank_profile(pool, bank_id: str) -> BankProfile:
|
||||
"""
|
||||
Get bank profile (name, personality + background).
|
||||
Get bank profile (name, disposition + background).
|
||||
Auto-creates bank with default values if not exists.
|
||||
|
||||
Args:
|
||||
|
|
@ -45,13 +45,13 @@ async def get_bank_profile(pool, bank_id: str) -> BankProfile:
|
|||
bank_id: bank IDentifier
|
||||
|
||||
Returns:
|
||||
BankProfile with name, typed PersonalityTraits, and background
|
||||
BankProfile with name, typed DispositionTraits, and background
|
||||
"""
|
||||
async with acquire_with_retry(pool) as conn:
|
||||
# Try to get existing bank
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
SELECT name, personality, background
|
||||
SELECT name, disposition, background
|
||||
FROM banks WHERE bank_id = $1
|
||||
""",
|
||||
bank_id
|
||||
|
|
@ -59,48 +59,48 @@ async def get_bank_profile(pool, bank_id: str) -> BankProfile:
|
|||
|
||||
if row:
|
||||
# asyncpg returns JSONB as a string, so parse it
|
||||
personality_data = row["personality"]
|
||||
if isinstance(personality_data, str):
|
||||
personality_data = json.loads(personality_data)
|
||||
disposition_data = row["disposition"]
|
||||
if isinstance(disposition_data, str):
|
||||
disposition_data = json.loads(disposition_data)
|
||||
|
||||
return BankProfile(
|
||||
name=row["name"],
|
||||
personality=PersonalityTraits(**personality_data),
|
||||
disposition=DispositionTraits(**disposition_data),
|
||||
background=row["background"]
|
||||
)
|
||||
|
||||
# Bank doesn't exist, create with defaults
|
||||
await conn.execute(
|
||||
"""
|
||||
INSERT INTO banks (bank_id, name, personality, background)
|
||||
INSERT INTO banks (bank_id, name, disposition, background)
|
||||
VALUES ($1, $2, $3::jsonb, $4)
|
||||
ON CONFLICT (bank_id) DO NOTHING
|
||||
""",
|
||||
bank_id,
|
||||
bank_id, # Default name is the bank_id
|
||||
json.dumps(DEFAULT_PERSONALITY),
|
||||
json.dumps(DEFAULT_DISPOSITION),
|
||||
""
|
||||
)
|
||||
|
||||
return BankProfile(
|
||||
name=bank_id,
|
||||
personality=PersonalityTraits(**DEFAULT_PERSONALITY),
|
||||
disposition=DispositionTraits(**DEFAULT_DISPOSITION),
|
||||
background=""
|
||||
)
|
||||
|
||||
|
||||
async def update_bank_personality(
|
||||
async def update_bank_disposition(
|
||||
pool,
|
||||
bank_id: str,
|
||||
personality: Dict[str, float]
|
||||
disposition: Dict[str, float]
|
||||
) -> None:
|
||||
"""
|
||||
Update bank personality traits.
|
||||
Update bank disposition traits.
|
||||
|
||||
Args:
|
||||
pool: Database connection pool
|
||||
bank_id: bank IDentifier
|
||||
personality: Dict with Big Five traits + bias_strength (all 0-1)
|
||||
disposition: Dict with Big Five traits + bias_strength (all 0-1)
|
||||
"""
|
||||
# Ensure bank exists first
|
||||
await get_bank_profile(pool, bank_id)
|
||||
|
|
@ -109,12 +109,12 @@ async def update_bank_personality(
|
|||
await conn.execute(
|
||||
"""
|
||||
UPDATE banks
|
||||
SET personality = $2::jsonb,
|
||||
SET disposition = $2::jsonb,
|
||||
updated_at = NOW()
|
||||
WHERE bank_id = $1
|
||||
""",
|
||||
bank_id,
|
||||
json.dumps(personality)
|
||||
json.dumps(disposition)
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -123,53 +123,53 @@ async def merge_bank_background(
|
|||
llm_config,
|
||||
bank_id: str,
|
||||
new_info: str,
|
||||
update_personality: bool = True
|
||||
update_disposition: bool = True
|
||||
) -> dict:
|
||||
"""
|
||||
Merge new background information with existing background using LLM.
|
||||
Normalizes to first person ("I") and resolves conflicts.
|
||||
Optionally infers personality traits from the merged background.
|
||||
Optionally infers disposition traits from the merged background.
|
||||
|
||||
Args:
|
||||
pool: Database connection pool
|
||||
llm_config: LLM configuration for background merging
|
||||
bank_id: bank IDentifier
|
||||
new_info: New background information to add/merge
|
||||
update_personality: If True, infer Big Five traits from background (default: True)
|
||||
update_disposition: If True, infer Big Five traits from background (default: True)
|
||||
|
||||
Returns:
|
||||
Dict with 'background' (str) and optionally 'personality' (dict) keys
|
||||
Dict with 'background' (str) and optionally 'disposition' (dict) keys
|
||||
"""
|
||||
# Get current profile
|
||||
profile = await get_bank_profile(pool, bank_id)
|
||||
current_background = profile["background"]
|
||||
|
||||
# Use LLM to merge backgrounds and optionally infer personality
|
||||
# Use LLM to merge backgrounds and optionally infer disposition
|
||||
result = await _llm_merge_background(
|
||||
llm_config,
|
||||
current_background,
|
||||
new_info,
|
||||
infer_personality=update_personality
|
||||
infer_disposition=update_disposition
|
||||
)
|
||||
|
||||
merged_background = result["background"]
|
||||
inferred_personality = result.get("personality")
|
||||
inferred_disposition = result.get("disposition")
|
||||
|
||||
# Update in database
|
||||
async with acquire_with_retry(pool) as conn:
|
||||
if inferred_personality:
|
||||
# Update both background and personality
|
||||
if inferred_disposition:
|
||||
# Update both background and disposition
|
||||
await conn.execute(
|
||||
"""
|
||||
UPDATE banks
|
||||
SET background = $2,
|
||||
personality = $3::jsonb,
|
||||
disposition = $3::jsonb,
|
||||
updated_at = NOW()
|
||||
WHERE bank_id = $1
|
||||
""",
|
||||
bank_id,
|
||||
merged_background,
|
||||
json.dumps(inferred_personality)
|
||||
json.dumps(inferred_disposition)
|
||||
)
|
||||
else:
|
||||
# Update only background
|
||||
|
|
@ -185,8 +185,8 @@ async def merge_bank_background(
|
|||
)
|
||||
|
||||
response = {"background": merged_background}
|
||||
if inferred_personality:
|
||||
response["personality"] = inferred_personality
|
||||
if inferred_disposition:
|
||||
response["disposition"] = inferred_disposition
|
||||
|
||||
return response
|
||||
|
||||
|
|
@ -195,23 +195,23 @@ async def _llm_merge_background(
|
|||
llm_config,
|
||||
current: str,
|
||||
new_info: str,
|
||||
infer_personality: bool = False
|
||||
infer_disposition: bool = False
|
||||
) -> dict:
|
||||
"""
|
||||
Use LLM to intelligently merge background information.
|
||||
Optionally infer Big Five personality traits from the merged background.
|
||||
Optionally infer Big Five disposition traits from the merged background.
|
||||
|
||||
Args:
|
||||
llm_config: LLM configuration to use
|
||||
current: Current background text
|
||||
new_info: New information to merge
|
||||
infer_personality: If True, also infer personality traits
|
||||
infer_disposition: If True, also infer disposition traits
|
||||
|
||||
Returns:
|
||||
Dict with 'background' (str) and optionally 'personality' (dict) keys
|
||||
Dict with 'background' (str) and optionally 'disposition' (dict) keys
|
||||
"""
|
||||
if infer_personality:
|
||||
prompt = f"""You are helping maintain a memory bank's background/profile and infer their personality. You MUST respond with ONLY valid JSON.
|
||||
if infer_disposition:
|
||||
prompt = f"""You are helping maintain a memory bank's background/profile and infer their disposition. You MUST respond with ONLY valid JSON.
|
||||
|
||||
Current background: {current if current else "(empty)"}
|
||||
|
||||
|
|
@ -223,20 +223,20 @@ Instructions:
|
|||
3. Keep additions that don't conflict
|
||||
4. Output in FIRST PERSON ("I") perspective
|
||||
5. Be concise - keep merged background under 500 characters
|
||||
6. Infer Big Five personality traits from the merged background:
|
||||
6. Infer Big Five disposition traits from the merged background:
|
||||
- Openness: 0.0-1.0 (creativity, curiosity, openness to new ideas)
|
||||
- Conscientiousness: 0.0-1.0 (organization, discipline, goal-directed)
|
||||
- Extraversion: 0.0-1.0 (sociability, assertiveness, energy from others)
|
||||
- Agreeableness: 0.0-1.0 (cooperation, empathy, consideration)
|
||||
- Neuroticism: 0.0-1.0 (emotional sensitivity, anxiety, stress response)
|
||||
- Bias Strength: 0.0-1.0 (how much personality influences opinions)
|
||||
- Bias Strength: 0.0-1.0 (how much disposition influences opinions)
|
||||
|
||||
CRITICAL: You MUST respond with ONLY a valid JSON object. No markdown, no code blocks, no explanations. Just the JSON.
|
||||
|
||||
Format:
|
||||
{{
|
||||
"background": "the merged background text in first person",
|
||||
"personality": {{
|
||||
"disposition": {{
|
||||
"openness": 0.7,
|
||||
"conscientiousness": 0.6,
|
||||
"extraversion": 0.5,
|
||||
|
|
@ -274,8 +274,8 @@ Merged background:"""
|
|||
# Prepare messages
|
||||
messages = [{"role": "user", "content": prompt}]
|
||||
|
||||
if infer_personality:
|
||||
# Use structured output with Pydantic model for personality inference
|
||||
if infer_disposition:
|
||||
# Use structured output with Pydantic model for disposition inference
|
||||
try:
|
||||
parsed = await llm_config.call(
|
||||
messages=messages,
|
||||
|
|
@ -289,13 +289,13 @@ Merged background:"""
|
|||
# Convert Pydantic model to dict format
|
||||
return {
|
||||
"background": parsed.background,
|
||||
"personality": parsed.personality.model_dump()
|
||||
"disposition": parsed.disposition.model_dump()
|
||||
}
|
||||
except Exception as e:
|
||||
logger.warning(f"Structured output failed, falling back to manual parsing: {e}")
|
||||
# Fall through to manual parsing below
|
||||
|
||||
# Manual parsing fallback or non-personality merge
|
||||
# Manual parsing fallback or non-disposition merge
|
||||
content = await llm_config.call(
|
||||
messages=messages,
|
||||
scope="bank_background",
|
||||
|
|
@ -305,7 +305,7 @@ Merged background:"""
|
|||
|
||||
logger.info(f"LLM response for background merge (first 500 chars): {content[:500]}")
|
||||
|
||||
if infer_personality:
|
||||
if infer_disposition:
|
||||
# Parse JSON response - try multiple extraction methods
|
||||
result = None
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ Merged background:"""
|
|||
# Method 3: Find nested JSON structure
|
||||
if result is None:
|
||||
# Look for JSON object with nested structure
|
||||
json_match = re.search(r'\{[^{}]*"background"[^{}]*"personality"[^{}]*\{[^{}]*\}[^{}]*\}', content, re.DOTALL)
|
||||
json_match = re.search(r'\{[^{}]*"background"[^{}]*"disposition"[^{}]*\{[^{}]*\}[^{}]*\}', content, re.DOTALL)
|
||||
if json_match:
|
||||
try:
|
||||
result = json.loads(json_match.group())
|
||||
|
|
@ -341,23 +341,23 @@ Merged background:"""
|
|||
# All parsing methods failed - use fallback
|
||||
if result is None:
|
||||
logger.warning(f"Failed to extract JSON from LLM response. Raw content: {content[:200]}")
|
||||
# Fallback: use new_info as background with default personality
|
||||
# Fallback: use new_info as background with default disposition
|
||||
return {
|
||||
"background": new_info if new_info else current if current else "",
|
||||
"personality": DEFAULT_PERSONALITY.copy()
|
||||
"disposition": DEFAULT_DISPOSITION.copy()
|
||||
}
|
||||
|
||||
# Validate personality values
|
||||
personality = result.get("personality", {})
|
||||
# Validate disposition values
|
||||
disposition = result.get("disposition", {})
|
||||
for key in ["openness", "conscientiousness", "extraversion",
|
||||
"agreeableness", "neuroticism", "bias_strength"]:
|
||||
if key not in personality:
|
||||
personality[key] = 0.5 # Default to neutral
|
||||
if key not in disposition:
|
||||
disposition[key] = 0.5 # Default to neutral
|
||||
else:
|
||||
# Clamp to [0, 1]
|
||||
personality[key] = max(0.0, min(1.0, float(personality[key])))
|
||||
disposition[key] = max(0.0, min(1.0, float(disposition[key])))
|
||||
|
||||
result["personality"] = personality
|
||||
result["disposition"] = disposition
|
||||
|
||||
# Ensure background exists
|
||||
if "background" not in result or not result["background"]:
|
||||
|
|
@ -380,8 +380,8 @@ Merged background:"""
|
|||
merged = new_info
|
||||
|
||||
result = {"background": merged}
|
||||
if infer_personality:
|
||||
result["personality"] = DEFAULT_PERSONALITY.copy()
|
||||
if infer_disposition:
|
||||
result["disposition"] = DEFAULT_DISPOSITION.copy()
|
||||
return result
|
||||
|
||||
|
||||
|
|
@ -393,12 +393,12 @@ async def list_banks(pool) -> list:
|
|||
pool: Database connection pool
|
||||
|
||||
Returns:
|
||||
List of dicts with bank_id, name, personality, background, created_at, updated_at
|
||||
List of dicts with bank_id, name, disposition, background, created_at, updated_at
|
||||
"""
|
||||
async with acquire_with_retry(pool) as conn:
|
||||
rows = await conn.fetch(
|
||||
"""
|
||||
SELECT bank_id, name, personality, background, created_at, updated_at
|
||||
SELECT bank_id, name, disposition, background, created_at, updated_at
|
||||
FROM banks
|
||||
ORDER BY updated_at DESC
|
||||
"""
|
||||
|
|
@ -407,14 +407,14 @@ async def list_banks(pool) -> list:
|
|||
result = []
|
||||
for row in rows:
|
||||
# asyncpg returns JSONB as a string, so parse it
|
||||
personality_data = row["personality"]
|
||||
if isinstance(personality_data, str):
|
||||
personality_data = json.loads(personality_data)
|
||||
disposition_data = row["disposition"]
|
||||
if isinstance(disposition_data, str):
|
||||
disposition_data = json.loads(disposition_data)
|
||||
|
||||
result.append({
|
||||
"bank_id": row["bank_id"],
|
||||
"name": row["name"],
|
||||
"personality": personality_data,
|
||||
"disposition": disposition_data,
|
||||
"background": row["background"],
|
||||
"created_at": row["created_at"].isoformat() if row["created_at"] else None,
|
||||
"updated_at": row["updated_at"].isoformat() if row["updated_at"] else None,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class Fact(BaseModel):
|
|||
"""
|
||||
# Required fields
|
||||
fact: str = Field(description="Combined fact text: what | when | where | who | why")
|
||||
fact_type: Literal["world", "interactions", "opinion"] = Field(description="Perspective: world/interactions/opinion")
|
||||
fact_type: Literal["world", "experience", "opinion"] = Field(description="Perspective: world/experience/opinion")
|
||||
|
||||
# Optional temporal fields
|
||||
occurred_start: Optional[str] = None
|
||||
|
|
@ -164,7 +164,7 @@ class ExtractedFact(BaseModel):
|
|||
# Classification (CRITICAL - required)
|
||||
# Note: LLM uses "assistant" but we convert to "bank" for storage
|
||||
fact_type: Literal["world", "assistant"] = Field(
|
||||
description="'world' = about the user/others (background, experiences). 'assistant' = interactions with the assistant."
|
||||
description="'world' = about the user/others (background, experiences). 'assistant' = experience with the assistant."
|
||||
)
|
||||
|
||||
# Entities - extracted from 'who' field
|
||||
|
|
@ -581,20 +581,20 @@ Text:
|
|||
continue
|
||||
|
||||
# Critical field: fact_type
|
||||
# LLM uses "assistant" but we convert to "interactions" for storage
|
||||
# LLM uses "assistant" but we convert to "experience" for storage
|
||||
fact_type = llm_fact.get('fact_type')
|
||||
|
||||
# Convert "assistant" → "interactions" for storage
|
||||
# Convert "assistant" → "experience" for storage
|
||||
if fact_type == 'assistant':
|
||||
fact_type = 'interactions'
|
||||
fact_type = 'experience'
|
||||
|
||||
# Validate fact_type (after conversion)
|
||||
if fact_type not in ['world', 'interactions', 'opinion']:
|
||||
if fact_type not in ['world', 'experience', 'opinion']:
|
||||
# Try to fix common mistakes - check if they swapped fact_type and fact_kind
|
||||
fact_kind = llm_fact.get('fact_kind')
|
||||
if fact_kind == 'assistant':
|
||||
fact_type = 'interactions'
|
||||
elif fact_kind in ['world', 'interactions', 'opinion']:
|
||||
fact_type = 'experience'
|
||||
elif fact_kind in ['world', 'experience', 'opinion']:
|
||||
fact_type = fact_kind
|
||||
else:
|
||||
# Default to 'world' if we can't determine
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ async def ensure_bank_exists(conn, bank_id: str) -> None:
|
|||
"""
|
||||
await conn.execute(
|
||||
"""
|
||||
INSERT INTO banks (bank_id, personality, background)
|
||||
INSERT INTO banks (bank_id, disposition, background)
|
||||
VALUES ($1, $2::jsonb, $3)
|
||||
ON CONFLICT (bank_id) DO UPDATE
|
||||
SET updated_at = NOW()
|
||||
|
|
|
|||
|
|
@ -107,7 +107,18 @@ def compute_temporal_query_bounds(
|
|||
|
||||
|
||||
def _log(log_buffer, message, level='info'):
|
||||
"""Helper to log to buffer if available, otherwise use logger."""
|
||||
"""Helper to log to buffer if available, otherwise use logger.
|
||||
|
||||
Args:
|
||||
log_buffer: Buffer to append messages to (for main output)
|
||||
message: The log message
|
||||
level: 'info', 'debug', 'warning', or 'error'. Debug messages are not added to buffer.
|
||||
"""
|
||||
if level == 'debug':
|
||||
# Debug messages only go to logger, not to buffer
|
||||
logger.debug(message)
|
||||
return
|
||||
|
||||
if log_buffer is not None:
|
||||
log_buffer.append(message)
|
||||
else:
|
||||
|
|
@ -165,7 +176,7 @@ async def extract_entities_batch_optimized(
|
|||
all_entities.append(formatted_entities)
|
||||
|
||||
total_entities = sum(len(ents) for ents in all_entities)
|
||||
_log(log_buffer, f" [6.1] Process LLM entities: {total_entities} entities from {len(sentences)} facts in {time.time() - substep_start:.3f}s")
|
||||
_log(log_buffer, f" [6.1] Process LLM entities: {total_entities} entities from {len(sentences)} facts in {time.time() - substep_start:.3f}s", level='debug')
|
||||
|
||||
# Step 2: Resolve entities in BATCH (much faster!)
|
||||
substep_start = time.time()
|
||||
|
|
@ -187,7 +198,7 @@ async def extract_entities_batch_optimized(
|
|||
'nearby_entities': entities,
|
||||
})
|
||||
entity_to_unit.append((unit_id, local_idx, fact_date))
|
||||
_log(log_buffer, f" [6.2.1] Prepare entities: {len(all_entities_flat)} entities in {time.time() - substep_6_2_1_start:.3f}s")
|
||||
_log(log_buffer, f" [6.2.1] Prepare entities: {len(all_entities_flat)} entities in {time.time() - substep_6_2_1_start:.3f}s", level='debug')
|
||||
|
||||
# Resolve ALL entities in one batch call
|
||||
if all_entities_flat:
|
||||
|
|
@ -202,47 +213,36 @@ async def extract_entities_batch_optimized(
|
|||
entities_by_date[date_key] = []
|
||||
entities_by_date[date_key].append((idx, all_entities_flat[idx]))
|
||||
|
||||
_log(log_buffer, f" [6.2.2] Grouped into {len(entities_by_date)} date buckets, resolving in parallel...")
|
||||
_log(log_buffer, f" [6.2.2] Grouped into {len(entities_by_date)} date buckets, resolving sequentially...", level='debug')
|
||||
|
||||
# Resolve all date groups in PARALLEL using asyncio.gather
|
||||
# Resolve all date groups SEQUENTIALLY using main transaction connection
|
||||
# This prevents race conditions where parallel tasks create duplicate entities
|
||||
resolved_entity_ids = [None] * len(all_entities_flat)
|
||||
|
||||
# Prepare all resolution tasks
|
||||
async def resolve_date_bucket(date_idx, date_key, entities_group):
|
||||
for date_idx, (date_key, entities_group) in enumerate(entities_by_date.items(), 1):
|
||||
date_bucket_start = time.time()
|
||||
indices = [idx for idx, _ in entities_group]
|
||||
entities_data = [entity_data for _, entity_data in entities_group]
|
||||
# Use the first fact's date for this bucket (all should be in same hour)
|
||||
fact_date = entity_to_unit[indices[0]][2]
|
||||
|
||||
# Pass conn=None to let each parallel task acquire its own connection
|
||||
# Use main transaction connection to ensure consistency
|
||||
batch_resolved = await entity_resolver.resolve_entities_batch(
|
||||
bank_id=bank_id,
|
||||
entities_data=entities_data,
|
||||
context=context,
|
||||
unit_event_date=fact_date,
|
||||
conn=None # Each task gets its own connection from pool
|
||||
conn=conn # Use main transaction connection
|
||||
)
|
||||
|
||||
if len(entities_by_date) <= 10: # Only log individual buckets if there aren't too many
|
||||
_log(log_buffer, f" [6.2.2.{date_idx}] Resolved {len(entities_data)} entities in {time.time() - date_bucket_start:.3f}s")
|
||||
_log(log_buffer, f" [6.2.2.{date_idx}] Resolved {len(entities_data)} entities in {time.time() - date_bucket_start:.3f}s", level='debug')
|
||||
|
||||
return indices, batch_resolved
|
||||
|
||||
# Execute all resolution tasks in parallel
|
||||
import asyncio
|
||||
tasks = [
|
||||
resolve_date_bucket(date_idx, date_key, entities_group)
|
||||
for date_idx, (date_key, entities_group) in enumerate(entities_by_date.items(), 1)
|
||||
]
|
||||
results = await asyncio.gather(*tasks)
|
||||
|
||||
# Map results back to resolved_entity_ids
|
||||
for indices, batch_resolved in results:
|
||||
# Map results back to resolved_entity_ids
|
||||
for idx, entity_id in zip(indices, batch_resolved):
|
||||
resolved_entity_ids[idx] = entity_id
|
||||
|
||||
_log(log_buffer, f" [6.2.2] Resolve entities: {len(all_entities_flat)} entities across {len(entities_by_date)} buckets in {time.time() - substep_6_2_2_start:.3f}s")
|
||||
_log(log_buffer, f" [6.2.2] Resolve entities: {len(all_entities_flat)} entities across {len(entities_by_date)} buckets in {time.time() - substep_6_2_2_start:.3f}s", level='debug')
|
||||
|
||||
# [6.2.3] Create unit-entity links in BATCH
|
||||
substep_6_2_3_start = time.time()
|
||||
|
|
@ -259,12 +259,12 @@ async def extract_entities_batch_optimized(
|
|||
|
||||
# Batch insert all unit-entity links (MUCH faster!)
|
||||
await entity_resolver.link_units_to_entities_batch(unit_entity_pairs, conn=conn)
|
||||
_log(log_buffer, f" [6.2.3] Create unit-entity links (batched): {len(unit_entity_pairs)} links in {time.time() - substep_6_2_3_start:.3f}s")
|
||||
_log(log_buffer, f" [6.2.3] Create unit-entity links (batched): {len(unit_entity_pairs)} links in {time.time() - substep_6_2_3_start:.3f}s", level='debug')
|
||||
|
||||
_log(log_buffer, f" [6.2] Entity resolution (batched): {len(all_entities_flat)} entities resolved in {time.time() - step_6_2_start:.3f}s")
|
||||
_log(log_buffer, f" [6.2] Entity resolution (batched): {len(all_entities_flat)} entities resolved in {time.time() - step_6_2_start:.3f}s", level='debug')
|
||||
else:
|
||||
unit_to_entity_ids = {}
|
||||
_log(log_buffer, f" [6.2] Entity resolution (batched): 0 entities in {time.time() - step_6_2_start:.3f}s")
|
||||
_log(log_buffer, f" [6.2] Entity resolution (batched): 0 entities in {time.time() - step_6_2_start:.3f}s", level='debug')
|
||||
|
||||
# Step 3: Create entity links between units that share entities
|
||||
substep_start = time.time()
|
||||
|
|
@ -273,7 +273,7 @@ async def extract_entities_batch_optimized(
|
|||
for entity_ids in unit_to_entity_ids.values():
|
||||
all_entity_ids.update(entity_ids)
|
||||
|
||||
_log(log_buffer, f" [6.3] Creating entity links for {len(all_entity_ids)} unique entities...")
|
||||
_log(log_buffer, f" [6.3] Creating entity links for {len(all_entity_ids)} unique entities...", level='debug')
|
||||
|
||||
# Find all units that reference these entities (ONE batched query)
|
||||
entity_to_units = {}
|
||||
|
|
@ -289,7 +289,7 @@ async def extract_entities_batch_optimized(
|
|||
""",
|
||||
entity_id_list
|
||||
)
|
||||
_log(log_buffer, f" [6.3.1] Query unit_entities: {len(rows)} rows in {time.time() - query_start:.3f}s")
|
||||
_log(log_buffer, f" [6.3.1] Query unit_entities: {len(rows)} rows in {time.time() - query_start:.3f}s", level='debug')
|
||||
|
||||
# Group by entity_id
|
||||
group_start = time.time()
|
||||
|
|
@ -298,21 +298,38 @@ async def extract_entities_batch_optimized(
|
|||
if entity_id not in entity_to_units:
|
||||
entity_to_units[entity_id] = []
|
||||
entity_to_units[entity_id].append(row['unit_id'])
|
||||
_log(log_buffer, f" [6.3.2] Group by entity_id: {time.time() - group_start:.3f}s")
|
||||
_log(log_buffer, f" [6.3.2] Group by entity_id: {time.time() - group_start:.3f}s", level='debug')
|
||||
|
||||
# Create bidirectional links between units that share entities
|
||||
# OPTIMIZATION: Limit links per entity to avoid N² explosion
|
||||
# Only link each new unit to the most recent MAX_LINKS_PER_ENTITY units
|
||||
MAX_LINKS_PER_ENTITY = 50 # Limit to prevent explosion when entity appears in many facts
|
||||
link_gen_start = time.time()
|
||||
links = []
|
||||
new_unit_set = set(unit_ids) # Units from this batch
|
||||
|
||||
for entity_id, units_with_entity in entity_to_units.items():
|
||||
# For each pair of units with this entity, create bidirectional links
|
||||
for i, unit_id_1 in enumerate(units_with_entity):
|
||||
for unit_id_2 in units_with_entity[i+1:]:
|
||||
# Bidirectional links
|
||||
# Separate new units (from this batch) and existing units
|
||||
new_units = [u for u in units_with_entity if str(u) in new_unit_set or u in new_unit_set]
|
||||
existing_units = [u for u in units_with_entity if str(u) not in new_unit_set and u not in new_unit_set]
|
||||
|
||||
# Link new units to each other (within batch) - also limited
|
||||
# For very common entities, limit within-batch links too
|
||||
new_units_to_link = new_units[-MAX_LINKS_PER_ENTITY:] if len(new_units) > MAX_LINKS_PER_ENTITY else new_units
|
||||
for i, unit_id_1 in enumerate(new_units_to_link):
|
||||
for unit_id_2 in new_units_to_link[i+1:]:
|
||||
links.append((unit_id_1, unit_id_2, 'entity', 1.0, entity_id))
|
||||
links.append((unit_id_2, unit_id_1, 'entity', 1.0, entity_id))
|
||||
|
||||
_log(log_buffer, f" [6.3.3] Generate {len(links)} links: {time.time() - link_gen_start:.3f}s")
|
||||
_log(log_buffer, f" [6.3] Entity link creation: {len(links)} links for {len(all_entity_ids)} unique entities in {time.time() - substep_start:.3f}s")
|
||||
# Link new units to LIMITED existing units (most recent)
|
||||
existing_to_link = existing_units[-MAX_LINKS_PER_ENTITY:] # Take most recent
|
||||
for new_unit in new_units:
|
||||
for existing_unit in existing_to_link:
|
||||
links.append((new_unit, existing_unit, 'entity', 1.0, entity_id))
|
||||
links.append((existing_unit, new_unit, 'entity', 1.0, entity_id))
|
||||
|
||||
_log(log_buffer, f" [6.3.3] Generate {len(links)} links: {time.time() - link_gen_start:.3f}s", level='debug')
|
||||
_log(log_buffer, f" [6.3] Entity link creation: {len(links)} links for {len(all_entity_ids)} unique entities in {time.time() - substep_start:.3f}s", level='debug')
|
||||
|
||||
return links
|
||||
|
||||
|
|
@ -546,8 +563,12 @@ async def insert_entity_links_batch(conn, links: List[tuple], chunk_size: int =
|
|||
return
|
||||
|
||||
import uuid as uuid_mod
|
||||
import time as time_mod
|
||||
|
||||
total_start = time_mod.time()
|
||||
|
||||
# Create temp table for bulk loading
|
||||
create_start = time_mod.time()
|
||||
await conn.execute("""
|
||||
CREATE TEMP TABLE IF NOT EXISTS _temp_entity_links (
|
||||
from_unit_id uuid,
|
||||
|
|
@ -557,11 +578,15 @@ async def insert_entity_links_batch(conn, links: List[tuple], chunk_size: int =
|
|||
entity_id uuid
|
||||
) ON COMMIT DROP
|
||||
""")
|
||||
logger.debug(f" [9.1] Create temp table: {time_mod.time() - create_start:.3f}s")
|
||||
|
||||
# Clear any existing data in temp table
|
||||
truncate_start = time_mod.time()
|
||||
await conn.execute("TRUNCATE _temp_entity_links")
|
||||
logger.debug(f" [9.2] Truncate temp table: {time_mod.time() - truncate_start:.3f}s")
|
||||
|
||||
# Convert links to proper format for COPY
|
||||
convert_start = time_mod.time()
|
||||
records = []
|
||||
for from_id, to_id, link_type, weight, entity_id in links:
|
||||
records.append((
|
||||
|
|
@ -571,21 +596,27 @@ async def insert_entity_links_batch(conn, links: List[tuple], chunk_size: int =
|
|||
weight,
|
||||
uuid_mod.UUID(str(entity_id)) if entity_id and not isinstance(entity_id, uuid_mod.UUID) else entity_id
|
||||
))
|
||||
logger.debug(f" [9.3] Convert {len(records)} records: {time_mod.time() - convert_start:.3f}s")
|
||||
|
||||
# Bulk load using COPY (fastest method)
|
||||
copy_start = time_mod.time()
|
||||
await conn.copy_records_to_table(
|
||||
'_temp_entity_links',
|
||||
records=records,
|
||||
columns=['from_unit_id', 'to_unit_id', 'link_type', 'weight', 'entity_id']
|
||||
)
|
||||
logger.debug(f" [9.4] COPY {len(records)} records to temp table: {time_mod.time() - copy_start:.3f}s")
|
||||
|
||||
# Insert from temp table with ON CONFLICT (single query for all rows)
|
||||
insert_start = time_mod.time()
|
||||
await conn.execute("""
|
||||
INSERT INTO memory_links (from_unit_id, to_unit_id, link_type, weight, entity_id)
|
||||
SELECT from_unit_id, to_unit_id, link_type, weight, entity_id
|
||||
FROM _temp_entity_links
|
||||
ON CONFLICT (from_unit_id, to_unit_id, link_type, COALESCE(entity_id, '00000000-0000-0000-0000-000000000000'::uuid)) DO NOTHING
|
||||
""")
|
||||
logger.debug(f" [9.5] INSERT from temp table: {time_mod.time() - insert_start:.3f}s")
|
||||
logger.debug(f" [9.TOTAL] Entity links batch insert: {time_mod.time() - total_start:.3f}s")
|
||||
|
||||
|
||||
async def create_causal_links_batch(
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class ExtractedFact:
|
|||
This is the raw output from fact extraction before processing.
|
||||
"""
|
||||
fact_text: str
|
||||
fact_type: str # "world", "interactions", "opinion", "observation"
|
||||
fact_type: str # "world", "experience", "opinion", "observation"
|
||||
entities: List[str] = field(default_factory=list)
|
||||
occurred_start: Optional[datetime] = None
|
||||
occurred_end: Optional[datetime] = None
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from datetime import datetime, timezone
|
|||
from typing import Dict, List, Any
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ..response_models import ReflectResult, MemoryFact, PersonalityTraits
|
||||
from ..response_models import ReflectResult, MemoryFact, DispositionTraits
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -42,16 +42,16 @@ def describe_trait(name: str, value: float) -> str:
|
|||
return f"very low {name}"
|
||||
|
||||
|
||||
def build_personality_description(personality: PersonalityTraits) -> str:
|
||||
"""Build a personality description string from personality traits."""
|
||||
return f"""Your personality traits:
|
||||
- {describe_trait('openness to new ideas', personality.openness)}
|
||||
- {describe_trait('conscientiousness and organization', personality.conscientiousness)}
|
||||
- {describe_trait('extraversion and sociability', personality.extraversion)}
|
||||
- {describe_trait('agreeableness and cooperation', personality.agreeableness)}
|
||||
- {describe_trait('emotional sensitivity', personality.neuroticism)}
|
||||
def build_disposition_description(disposition: DispositionTraits) -> str:
|
||||
"""Build a disposition description string from disposition traits."""
|
||||
return f"""Your disposition traits:
|
||||
- {describe_trait('openness to new ideas', disposition.openness)}
|
||||
- {describe_trait('conscientiousness and organization', disposition.conscientiousness)}
|
||||
- {describe_trait('extraversion and sociability', disposition.extraversion)}
|
||||
- {describe_trait('agreeableness and cooperation', disposition.agreeableness)}
|
||||
- {describe_trait('emotional sensitivity', disposition.neuroticism)}
|
||||
|
||||
Personality influence strength: {int(personality.bias_strength * 100)}% (how much your personality shapes your opinions)"""
|
||||
Disposition influence strength: {int(disposition.bias_strength * 100)}% (how much your disposition shapes your opinions)"""
|
||||
|
||||
|
||||
def format_facts_for_prompt(facts: List[MemoryFact]) -> str:
|
||||
|
|
@ -93,12 +93,12 @@ def build_think_prompt(
|
|||
opinion_facts_text: str,
|
||||
query: str,
|
||||
name: str,
|
||||
personality: PersonalityTraits,
|
||||
disposition: DispositionTraits,
|
||||
background: str,
|
||||
context: str = None,
|
||||
) -> str:
|
||||
"""Build the think prompt for the LLM."""
|
||||
personality_desc = build_personality_description(personality)
|
||||
disposition_desc = build_disposition_description(disposition)
|
||||
|
||||
name_section = f"""
|
||||
|
||||
|
|
@ -132,24 +132,24 @@ WHAT I KNOW ABOUT THE WORLD:
|
|||
MY EXISTING OPINIONS & BELIEFS:
|
||||
{opinion_facts_text}
|
||||
|
||||
{context_section}{name_section}{personality_desc}{background_section}
|
||||
{context_section}{name_section}{disposition_desc}{background_section}
|
||||
|
||||
QUESTION: {query}
|
||||
|
||||
Based on everything I know, believe, and who I am (including my name, personality and background), here's what I genuinely think about this question. I'll draw on my experiences, knowledge, opinions, and personal traits to give you my honest perspective."""
|
||||
Based on everything I know, believe, and who I am (including my name, disposition and background), here's what I genuinely think about this question. I'll draw on my experiences, knowledge, opinions, and personal traits to give you my honest perspective."""
|
||||
|
||||
|
||||
def get_system_message(personality: PersonalityTraits) -> str:
|
||||
def get_system_message(disposition: DispositionTraits) -> str:
|
||||
"""Get the system message for the think LLM call."""
|
||||
bias_strength = personality.bias_strength
|
||||
bias_strength = disposition.bias_strength
|
||||
if bias_strength >= 0.7:
|
||||
personality_instruction = "Your personality strongly influences your thinking. Let your traits guide how you interpret facts and form opinions. Don't be afraid to be biased based on your personality."
|
||||
disposition_instruction = "Your disposition strongly influences your thinking. Let your traits guide how you interpret facts and form opinions. Don't be afraid to be biased based on your disposition."
|
||||
elif bias_strength >= 0.4:
|
||||
personality_instruction = "Your personality moderately influences your thinking. Balance your personal traits with objective analysis."
|
||||
disposition_instruction = "Your disposition moderately influences your thinking. Balance your personal traits with objective analysis."
|
||||
else:
|
||||
personality_instruction = "Your personality has minimal influence on your thinking. Focus primarily on facts while keeping your traits in mind."
|
||||
disposition_instruction = "Your disposition has minimal influence on your thinking. Focus primarily on facts while keeping your traits in mind."
|
||||
|
||||
return f"You are a person with your own thoughts, experiences, opinions, and personality. When asked a question, respond naturally like a human would - share what you genuinely think based on what you know and have experienced. {personality_instruction} Be direct, express your views confidently, and use 'I think', 'I believe', 'in my view', etc. Respond in plain text without markdown formatting."
|
||||
return f"You are a person with your own thoughts, experiences, opinions, and disposition. When asked a question, respond naturally like a human would - share what you genuinely think based on what you know and have experienced. {disposition_instruction} Be direct, express your views confidently, and use 'I think', 'I believe', 'in my view', etc. Respond in plain text without markdown formatting."
|
||||
|
||||
|
||||
async def extract_opinions_from_text(
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class RetrievalResult(BaseModel):
|
|||
text: str = Field(description="Memory unit text content")
|
||||
context: str = Field(default="", description="Memory unit context")
|
||||
event_date: Optional[datetime] = Field(default=None, description="When the memory occurred")
|
||||
fact_type: Optional[str] = Field(default=None, description="Fact type (world, bank, opinion)")
|
||||
fact_type: Optional[str] = Field(default=None, description="Fact type (world, experience, opinion)")
|
||||
score: float = Field(description="Score from this retrieval method")
|
||||
score_name: str = Field(description="Name of the score (e.g., 'similarity', 'bm25_score', 'activation')")
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class MemoryUnit(Base):
|
|||
name="memory_units_document_fkey",
|
||||
ondelete="CASCADE",
|
||||
),
|
||||
CheckConstraint("fact_type IN ('world', 'interactions', 'opinion', 'observation')"),
|
||||
CheckConstraint("fact_type IN ('world', 'experience', 'opinion', 'observation')"),
|
||||
CheckConstraint("confidence_score IS NULL OR (confidence_score >= 0.0 AND confidence_score <= 1.0)"),
|
||||
CheckConstraint(
|
||||
"(fact_type = 'opinion' AND confidence_score IS NOT NULL) OR "
|
||||
|
|
@ -284,11 +284,11 @@ class MemoryLink(Base):
|
|||
|
||||
|
||||
class Bank(Base):
|
||||
"""Memory bank profiles with personality traits and background."""
|
||||
"""Memory bank profiles with disposition traits and background."""
|
||||
__tablename__ = "banks"
|
||||
|
||||
bank_id: Mapped[str] = mapped_column(Text, primary_key=True)
|
||||
personality: Mapped[dict] = mapped_column(
|
||||
disposition: Mapped[dict] = mapped_column(
|
||||
JSONB,
|
||||
nullable=False,
|
||||
server_default=sql_text(
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Tests for agent management API (profile, personality, background).
|
|||
import pytest
|
||||
import uuid
|
||||
from hindsight_api import MemoryEngine
|
||||
from hindsight_api.api import CreateBankRequest, PersonalityTraits
|
||||
from hindsight_api.api import CreateBankRequest, DispositionTraits
|
||||
from hindsight_api.engine.memory_engine import Budget
|
||||
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ class TestAgentEndpoint:
|
|||
bank_id = unique_agent_id("test_put_create")
|
||||
|
||||
request = CreateBankRequest(
|
||||
personality=PersonalityTraits(
|
||||
personality=DispositionTraits(
|
||||
openness=0.8,
|
||||
conscientiousness=0.6,
|
||||
extraversion=0.5,
|
||||
|
|
|
|||
|
|
@ -98,18 +98,18 @@ impl ApiClient {
|
|||
let request = types::CreateBankRequest {
|
||||
name: Some(name.to_string()),
|
||||
background: None,
|
||||
personality: None,
|
||||
disposition: None,
|
||||
};
|
||||
let response = self.client.create_or_update_bank(agent_id, &request).await?;
|
||||
Ok(response.into_inner())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_background(&self, agent_id: &str, content: &str, update_personality: bool, _verbose: bool) -> Result<types::BackgroundResponse> {
|
||||
pub fn add_background(&self, agent_id: &str, content: &str, update_disposition: bool, _verbose: bool) -> Result<types::BackgroundResponse> {
|
||||
self.runtime.block_on(async {
|
||||
let request = types::AddBackgroundRequest {
|
||||
content: content.to_string(),
|
||||
update_personality,
|
||||
update_disposition,
|
||||
};
|
||||
let response = self.client.add_bank_background(agent_id, &request).await?;
|
||||
Ok(response.into_inner())
|
||||
|
|
|
|||
|
|
@ -198,11 +198,11 @@ pub fn update_background(
|
|||
client: &ApiClient,
|
||||
bank_id: &str,
|
||||
content: &str,
|
||||
no_update_personality: bool,
|
||||
no_update_disposition: bool,
|
||||
verbose: bool,
|
||||
output_format: OutputFormat
|
||||
) -> Result<()> {
|
||||
let current_profile = if !no_update_personality {
|
||||
let current_profile = if !no_update_disposition {
|
||||
client.get_profile(bank_id, verbose).ok()
|
||||
} else {
|
||||
None
|
||||
|
|
@ -214,7 +214,7 @@ pub fn update_background(
|
|||
None
|
||||
};
|
||||
|
||||
let response = client.add_background(bank_id, content, !no_update_personality, verbose);
|
||||
let response = client.add_background(bank_id, content, !no_update_disposition, verbose);
|
||||
|
||||
if let Some(sp) = spinner {
|
||||
sp.finish_and_clear();
|
||||
|
|
@ -226,11 +226,11 @@ pub fn update_background(
|
|||
ui::print_success("Background updated successfully");
|
||||
println!("\n{}", profile.background);
|
||||
|
||||
if !no_update_personality {
|
||||
if !no_update_disposition {
|
||||
if let (Some(old_p), Some(new_p)) =
|
||||
(current_profile.as_ref().map(|p| p.personality.clone()), &profile.personality)
|
||||
(current_profile.as_ref().map(|p| p.disposition.clone()), &profile.disposition)
|
||||
{
|
||||
println!("\nPersonality changes:");
|
||||
println!("\nDisposition changes:");
|
||||
println!(" Openness: {:.2} → {:.2}", old_p.openness, new_p.openness);
|
||||
println!(" Conscientiousness: {:.2} → {:.2}", old_p.conscientiousness, new_p.conscientiousness);
|
||||
println!(" Extraversion: {:.2} → {:.2}", old_p.extraversion, new_p.extraversion);
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ enum BankCommands {
|
|||
/// List all banks
|
||||
List,
|
||||
|
||||
/// Get bank profile (personality + background)
|
||||
/// Get bank profile (disposition + background)
|
||||
Profile {
|
||||
/// Bank ID
|
||||
bank_id: String,
|
||||
|
|
@ -129,9 +129,9 @@ enum BankCommands {
|
|||
/// Background content
|
||||
content: String,
|
||||
|
||||
/// Skip automatic personality inference
|
||||
/// Skip automatic disposition inference
|
||||
#[arg(long)]
|
||||
no_update_personality: bool,
|
||||
no_update_disposition: bool,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -145,8 +145,8 @@ enum MemoryCommands {
|
|||
/// Search query
|
||||
query: String,
|
||||
|
||||
/// Fact types to search (world, interactions, opinion)
|
||||
#[arg(short = 't', long, value_delimiter = ',', default_values = &["world", "interactions", "opinion"])]
|
||||
/// Fact types to search (world, experience, opinion)
|
||||
#[arg(short = 't', long, value_delimiter = ',', default_values = &["world", "experience", "opinion"])]
|
||||
fact_type: Vec<String>,
|
||||
|
||||
/// Thinking budget (low, mid, high)
|
||||
|
|
@ -381,8 +381,8 @@ fn run() -> Result<()> {
|
|||
BankCommands::Profile { bank_id } => commands::bank::profile(&client, &bank_id, verbose, output_format),
|
||||
BankCommands::Stats { bank_id } => commands::bank::stats(&client, &bank_id, verbose, output_format),
|
||||
BankCommands::Name { bank_id, name } => commands::bank::update_name(&client, &bank_id, &name, verbose, output_format),
|
||||
BankCommands::Background { bank_id, content, no_update_personality } => {
|
||||
commands::bank::update_background(&client, &bank_id, &content, no_update_personality, verbose, output_format)
|
||||
BankCommands::Background { bank_id, content, no_update_disposition } => {
|
||||
commands::bank::update_background(&client, &bank_id, &content, no_update_disposition, verbose, output_format)
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -205,16 +205,16 @@ pub fn print_profile(profile: &BankProfileResponse) {
|
|||
println!();
|
||||
}
|
||||
|
||||
// Print personality traits
|
||||
println!("{}", "─── Personality Traits ───".bright_yellow());
|
||||
// Print disposition traits
|
||||
println!("{}", "─── Disposition Traits ───".bright_yellow());
|
||||
println!();
|
||||
|
||||
let traits = [
|
||||
("Openness", profile.personality.openness, "🔓", "green"),
|
||||
("Conscientiousness", profile.personality.conscientiousness, "📋", "yellow"),
|
||||
("Extraversion", profile.personality.extraversion, "🗣️", "cyan"),
|
||||
("Agreeableness", profile.personality.agreeableness, "🤝", "magenta"),
|
||||
("Neuroticism", profile.personality.neuroticism, "😰", "yellow"),
|
||||
("Openness", profile.disposition.openness, "🔓", "green"),
|
||||
("Conscientiousness", profile.disposition.conscientiousness, "📋", "yellow"),
|
||||
("Extraversion", profile.disposition.extraversion, "🗣️", "cyan"),
|
||||
("Agreeableness", profile.disposition.agreeableness, "🤝", "magenta"),
|
||||
("Neuroticism", profile.disposition.neuroticism, "😰", "yellow"),
|
||||
];
|
||||
|
||||
for (name, value, emoji, color) in &traits {
|
||||
|
|
@ -241,17 +241,17 @@ pub fn print_profile(profile: &BankProfileResponse) {
|
|||
|
||||
println!();
|
||||
println!("{}", "Bias Strength:".bright_yellow());
|
||||
let bias = profile.personality.bias_strength;
|
||||
let bias = profile.disposition.bias_strength;
|
||||
let bar_length = 40;
|
||||
let filled = (bias * bar_length as f64) as usize;
|
||||
let empty = bar_length - filled;
|
||||
let bar = format!("{}{}", "█".repeat(filled), "░".repeat(empty));
|
||||
|
||||
println!(" 💪 {:<20} [{}] {:.0}%",
|
||||
"Personality Influence",
|
||||
"Disposition Influence",
|
||||
bar.bright_green(),
|
||||
bias * 100.0
|
||||
);
|
||||
println!(" {}", "(how much personality shapes opinions)".bright_black());
|
||||
println!(" {}", "(how much disposition shapes opinions)".bright_black());
|
||||
println!();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ hindsight_client_api/docs/ChunkResponse.md
|
|||
hindsight_client_api/docs/CreateBankRequest.md
|
||||
hindsight_client_api/docs/DefaultApi.md
|
||||
hindsight_client_api/docs/DeleteResponse.md
|
||||
hindsight_client_api/docs/DispositionTraits.md
|
||||
hindsight_client_api/docs/DocumentResponse.md
|
||||
hindsight_client_api/docs/EntityDetailResponse.md
|
||||
hindsight_client_api/docs/EntityIncludeOptions.md
|
||||
|
|
@ -32,7 +33,6 @@ hindsight_client_api/docs/ListMemoryUnitsResponse.md
|
|||
hindsight_client_api/docs/MemoryItem.md
|
||||
hindsight_client_api/docs/MetadataFilter.md
|
||||
hindsight_client_api/docs/MonitoringApi.md
|
||||
hindsight_client_api/docs/PersonalityTraits.md
|
||||
hindsight_client_api/docs/RecallRequest.md
|
||||
hindsight_client_api/docs/RecallResponse.md
|
||||
hindsight_client_api/docs/RecallResult.md
|
||||
|
|
@ -42,7 +42,7 @@ hindsight_client_api/docs/ReflectRequest.md
|
|||
hindsight_client_api/docs/ReflectResponse.md
|
||||
hindsight_client_api/docs/RetainRequest.md
|
||||
hindsight_client_api/docs/RetainResponse.md
|
||||
hindsight_client_api/docs/UpdatePersonalityRequest.md
|
||||
hindsight_client_api/docs/UpdateDispositionRequest.md
|
||||
hindsight_client_api/docs/ValidationError.md
|
||||
hindsight_client_api/docs/ValidationErrorLocInner.md
|
||||
hindsight_client_api/exceptions.py
|
||||
|
|
@ -58,6 +58,7 @@ hindsight_client_api/models/chunk_include_options.py
|
|||
hindsight_client_api/models/chunk_response.py
|
||||
hindsight_client_api/models/create_bank_request.py
|
||||
hindsight_client_api/models/delete_response.py
|
||||
hindsight_client_api/models/disposition_traits.py
|
||||
hindsight_client_api/models/document_response.py
|
||||
hindsight_client_api/models/entity_detail_response.py
|
||||
hindsight_client_api/models/entity_include_options.py
|
||||
|
|
@ -72,7 +73,6 @@ hindsight_client_api/models/list_documents_response.py
|
|||
hindsight_client_api/models/list_memory_units_response.py
|
||||
hindsight_client_api/models/memory_item.py
|
||||
hindsight_client_api/models/metadata_filter.py
|
||||
hindsight_client_api/models/personality_traits.py
|
||||
hindsight_client_api/models/recall_request.py
|
||||
hindsight_client_api/models/recall_response.py
|
||||
hindsight_client_api/models/recall_result.py
|
||||
|
|
@ -82,7 +82,7 @@ hindsight_client_api/models/reflect_request.py
|
|||
hindsight_client_api/models/reflect_response.py
|
||||
hindsight_client_api/models/retain_request.py
|
||||
hindsight_client_api/models/retain_response.py
|
||||
hindsight_client_api/models/update_personality_request.py
|
||||
hindsight_client_api/models/update_disposition_request.py
|
||||
hindsight_client_api/models/validation_error.py
|
||||
hindsight_client_api/models/validation_error_loc_inner.py
|
||||
hindsight_client_api/rest.py
|
||||
|
|
@ -99,6 +99,7 @@ hindsight_client_api/test/test_chunk_response.py
|
|||
hindsight_client_api/test/test_create_bank_request.py
|
||||
hindsight_client_api/test/test_default_api.py
|
||||
hindsight_client_api/test/test_delete_response.py
|
||||
hindsight_client_api/test/test_disposition_traits.py
|
||||
hindsight_client_api/test/test_document_response.py
|
||||
hindsight_client_api/test/test_entity_detail_response.py
|
||||
hindsight_client_api/test/test_entity_include_options.py
|
||||
|
|
@ -114,7 +115,6 @@ hindsight_client_api/test/test_list_memory_units_response.py
|
|||
hindsight_client_api/test/test_memory_item.py
|
||||
hindsight_client_api/test/test_metadata_filter.py
|
||||
hindsight_client_api/test/test_monitoring_api.py
|
||||
hindsight_client_api/test/test_personality_traits.py
|
||||
hindsight_client_api/test/test_recall_request.py
|
||||
hindsight_client_api/test/test_recall_response.py
|
||||
hindsight_client_api/test/test_recall_result.py
|
||||
|
|
@ -124,7 +124,7 @@ hindsight_client_api/test/test_reflect_request.py
|
|||
hindsight_client_api/test/test_reflect_response.py
|
||||
hindsight_client_api/test/test_retain_request.py
|
||||
hindsight_client_api/test/test_retain_response.py
|
||||
hindsight_client_api/test/test_update_personality_request.py
|
||||
hindsight_client_api/test/test_update_disposition_request.py
|
||||
hindsight_client_api/test/test_validation_error.py
|
||||
hindsight_client_api/test/test_validation_error_loc_inner.py
|
||||
hindsight_client_api_README.md
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ class Hindsight:
|
|||
Args:
|
||||
bank_id: The memory bank ID
|
||||
query: Search query
|
||||
types: Optional list of fact types to filter (world, interactions, opinion, observation)
|
||||
types: Optional list of fact types to filter (world, experience, opinion, observation)
|
||||
max_tokens: Maximum tokens in results (default: 4096)
|
||||
budget: Budget level for recall - "low", "mid", or "high" (default: "mid")
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ class Hindsight:
|
|||
Args:
|
||||
bank_id: The memory bank ID
|
||||
query: Search query
|
||||
types: Optional list of fact types to filter (world, interactions, opinion, observation)
|
||||
types: Optional list of fact types to filter (world, experience, opinion, observation)
|
||||
budget: Budget level - "low", "mid", or "high"
|
||||
max_tokens: Maximum tokens in results
|
||||
trace: Enable trace output
|
||||
|
|
@ -379,7 +379,7 @@ class Hindsight:
|
|||
Args:
|
||||
bank_id: The memory bank ID
|
||||
query: Search query
|
||||
types: Optional list of fact types to filter (world, interactions, opinion, observation)
|
||||
types: Optional list of fact types to filter (world, experience, opinion, observation)
|
||||
max_tokens: Maximum tokens in results (default: 4096)
|
||||
budget: Budget level for recall - "low", "mid", or "high" (default: "mid")
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ __all__ = [
|
|||
"ChunkResponse",
|
||||
"CreateBankRequest",
|
||||
"DeleteResponse",
|
||||
"DispositionTraits",
|
||||
"DocumentResponse",
|
||||
"EntityDetailResponse",
|
||||
"EntityIncludeOptions",
|
||||
|
|
@ -54,7 +55,6 @@ __all__ = [
|
|||
"ListMemoryUnitsResponse",
|
||||
"MemoryItem",
|
||||
"MetadataFilter",
|
||||
"PersonalityTraits",
|
||||
"RecallRequest",
|
||||
"RecallResponse",
|
||||
"RecallResult",
|
||||
|
|
@ -64,7 +64,7 @@ __all__ = [
|
|||
"ReflectResponse",
|
||||
"RetainRequest",
|
||||
"RetainResponse",
|
||||
"UpdatePersonalityRequest",
|
||||
"UpdateDispositionRequest",
|
||||
"ValidationError",
|
||||
"ValidationErrorLocInner",
|
||||
]
|
||||
|
|
@ -96,6 +96,7 @@ from hindsight_client_api.models.chunk_include_options import ChunkIncludeOption
|
|||
from hindsight_client_api.models.chunk_response import ChunkResponse as ChunkResponse
|
||||
from hindsight_client_api.models.create_bank_request import CreateBankRequest as CreateBankRequest
|
||||
from hindsight_client_api.models.delete_response import DeleteResponse as DeleteResponse
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits as DispositionTraits
|
||||
from hindsight_client_api.models.document_response import DocumentResponse as DocumentResponse
|
||||
from hindsight_client_api.models.entity_detail_response import EntityDetailResponse as EntityDetailResponse
|
||||
from hindsight_client_api.models.entity_include_options import EntityIncludeOptions as EntityIncludeOptions
|
||||
|
|
@ -110,7 +111,6 @@ from hindsight_client_api.models.list_documents_response import ListDocumentsRes
|
|||
from hindsight_client_api.models.list_memory_units_response import ListMemoryUnitsResponse as ListMemoryUnitsResponse
|
||||
from hindsight_client_api.models.memory_item import MemoryItem as MemoryItem
|
||||
from hindsight_client_api.models.metadata_filter import MetadataFilter as MetadataFilter
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits as PersonalityTraits
|
||||
from hindsight_client_api.models.recall_request import RecallRequest as RecallRequest
|
||||
from hindsight_client_api.models.recall_response import RecallResponse as RecallResponse
|
||||
from hindsight_client_api.models.recall_result import RecallResult as RecallResult
|
||||
|
|
@ -120,7 +120,7 @@ from hindsight_client_api.models.reflect_request import ReflectRequest as Reflec
|
|||
from hindsight_client_api.models.reflect_response import ReflectResponse as ReflectResponse
|
||||
from hindsight_client_api.models.retain_request import RetainRequest as RetainRequest
|
||||
from hindsight_client_api.models.retain_response import RetainResponse as RetainResponse
|
||||
from hindsight_client_api.models.update_personality_request import UpdatePersonalityRequest as UpdatePersonalityRequest
|
||||
from hindsight_client_api.models.update_disposition_request import UpdateDispositionRequest as UpdateDispositionRequest
|
||||
from hindsight_client_api.models.validation_error import ValidationError as ValidationError
|
||||
from hindsight_client_api.models.validation_error_loc_inner import ValidationErrorLocInner as ValidationErrorLocInner
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ from hindsight_client_api.models.reflect_request import ReflectRequest
|
|||
from hindsight_client_api.models.reflect_response import ReflectResponse
|
||||
from hindsight_client_api.models.retain_request import RetainRequest
|
||||
from hindsight_client_api.models.retain_response import RetainResponse
|
||||
from hindsight_client_api.models.update_personality_request import UpdatePersonalityRequest
|
||||
from hindsight_client_api.models.update_disposition_request import UpdateDispositionRequest
|
||||
|
||||
from hindsight_client_api.api_client import ApiClient, RequestSerialized
|
||||
from hindsight_client_api.api_response import ApiResponse
|
||||
|
|
@ -78,7 +78,7 @@ class DefaultApi:
|
|||
) -> BackgroundResponse:
|
||||
"""Add/merge memory bank background
|
||||
|
||||
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.
|
||||
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -150,7 +150,7 @@ class DefaultApi:
|
|||
) -> ApiResponse[BackgroundResponse]:
|
||||
"""Add/merge memory bank background
|
||||
|
||||
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.
|
||||
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -222,7 +222,7 @@ class DefaultApi:
|
|||
) -> RESTResponseType:
|
||||
"""Add/merge memory bank background
|
||||
|
||||
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.
|
||||
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -631,7 +631,7 @@ class DefaultApi:
|
|||
async def clear_bank_memories(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, interactions, opinion)")] = None,
|
||||
type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, experience, opinion)")] = None,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
|
|
@ -647,11 +647,11 @@ class DefaultApi:
|
|||
) -> DeleteResponse:
|
||||
"""Clear memory bank memories
|
||||
|
||||
Delete memory units for a memory bank. Optionally filter by type (world, interactions, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.
|
||||
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.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param type: Optional fact type filter (world, interactions, opinion)
|
||||
:param type: Optional fact type filter (world, experience, opinion)
|
||||
:type type: str
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
|
|
@ -703,7 +703,7 @@ class DefaultApi:
|
|||
async def clear_bank_memories_with_http_info(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, interactions, opinion)")] = None,
|
||||
type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, experience, opinion)")] = None,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
|
|
@ -719,11 +719,11 @@ class DefaultApi:
|
|||
) -> ApiResponse[DeleteResponse]:
|
||||
"""Clear memory bank memories
|
||||
|
||||
Delete memory units for a memory bank. Optionally filter by type (world, interactions, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.
|
||||
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.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param type: Optional fact type filter (world, interactions, opinion)
|
||||
:param type: Optional fact type filter (world, experience, opinion)
|
||||
:type type: str
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
|
|
@ -775,7 +775,7 @@ class DefaultApi:
|
|||
async def clear_bank_memories_without_preload_content(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, interactions, opinion)")] = None,
|
||||
type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, experience, opinion)")] = None,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
|
|
@ -791,11 +791,11 @@ class DefaultApi:
|
|||
) -> RESTResponseType:
|
||||
"""Clear memory bank memories
|
||||
|
||||
Delete memory units for a memory bank. Optionally filter by type (world, interactions, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.
|
||||
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.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param type: Optional fact type filter (world, interactions, opinion)
|
||||
:param type: Optional fact type filter (world, experience, opinion)
|
||||
:type type: str
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
|
|
@ -927,7 +927,7 @@ class DefaultApi:
|
|||
) -> BankProfileResponse:
|
||||
"""Create or update memory bank
|
||||
|
||||
Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.
|
||||
Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -999,7 +999,7 @@ class DefaultApi:
|
|||
) -> ApiResponse[BankProfileResponse]:
|
||||
"""Create or update memory bank
|
||||
|
||||
Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.
|
||||
Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -1071,7 +1071,7 @@ class DefaultApi:
|
|||
) -> RESTResponseType:
|
||||
"""Create or update memory bank
|
||||
|
||||
Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.
|
||||
Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -1758,7 +1758,7 @@ class DefaultApi:
|
|||
) -> BankProfileResponse:
|
||||
"""Get memory bank profile
|
||||
|
||||
Get personality traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -1826,7 +1826,7 @@ class DefaultApi:
|
|||
) -> ApiResponse[BankProfileResponse]:
|
||||
"""Get memory bank profile
|
||||
|
||||
Get personality traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -1894,7 +1894,7 @@ class DefaultApi:
|
|||
) -> RESTResponseType:
|
||||
"""Get memory bank profile
|
||||
|
||||
Get personality traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -2841,7 +2841,7 @@ class DefaultApi:
|
|||
) -> GraphDataResponse:
|
||||
"""Get memory graph data
|
||||
|
||||
Retrieve graph data for visualization, optionally filtered by type (world/interactions/opinion). Limited to 1000 most recent items.
|
||||
Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -2913,7 +2913,7 @@ class DefaultApi:
|
|||
) -> ApiResponse[GraphDataResponse]:
|
||||
"""Get memory graph data
|
||||
|
||||
Retrieve graph data for visualization, optionally filtered by type (world/interactions/opinion). Limited to 1000 most recent items.
|
||||
Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -2985,7 +2985,7 @@ class DefaultApi:
|
|||
) -> RESTResponseType:
|
||||
"""Get memory graph data
|
||||
|
||||
Retrieve graph data for visualization, optionally filtered by type (world/interactions/opinion). Limited to 1000 most recent items.
|
||||
Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -4554,7 +4554,7 @@ class DefaultApi:
|
|||
) -> RecallResponse:
|
||||
"""Recall memory
|
||||
|
||||
Recall memory using semantic similarity and spreading activation. The type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'interactions': Memories about interactions, conversations, actions taken, and tasks performed - 'opinion': The bank's formed beliefs, perspectives, and viewpoints Set include_entities=true to get entity observations alongside recall results.
|
||||
Recall memory using semantic similarity and spreading activation. The type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'experience': Memories about experience, conversations, actions taken, and tasks performed - 'opinion': The bank's formed beliefs, perspectives, and viewpoints Set include_entities=true to get entity observations alongside recall results.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -4626,7 +4626,7 @@ class DefaultApi:
|
|||
) -> ApiResponse[RecallResponse]:
|
||||
"""Recall memory
|
||||
|
||||
Recall memory using semantic similarity and spreading activation. The type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'interactions': Memories about interactions, conversations, actions taken, and tasks performed - 'opinion': The bank's formed beliefs, perspectives, and viewpoints Set include_entities=true to get entity observations alongside recall results.
|
||||
Recall memory using semantic similarity and spreading activation. The type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'experience': Memories about experience, conversations, actions taken, and tasks performed - 'opinion': The bank's formed beliefs, perspectives, and viewpoints Set include_entities=true to get entity observations alongside recall results.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -4698,7 +4698,7 @@ class DefaultApi:
|
|||
) -> RESTResponseType:
|
||||
"""Recall memory
|
||||
|
||||
Recall memory using semantic similarity and spreading activation. The type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'interactions': Memories about interactions, conversations, actions taken, and tasks performed - 'opinion': The bank's formed beliefs, perspectives, and viewpoints Set include_entities=true to get entity observations alongside recall results.
|
||||
Recall memory using semantic similarity and spreading activation. The type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'experience': Memories about experience, conversations, actions taken, and tasks performed - 'opinion': The bank's formed beliefs, perspectives, and viewpoints Set include_entities=true to get entity observations alongside recall results.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -4845,7 +4845,7 @@ class DefaultApi:
|
|||
) -> ReflectResponse:
|
||||
"""Reflect and generate answer
|
||||
|
||||
Reflect and formulate an answer using bank identity, world facts, and opinions. This endpoint: 1. Retrieves interactions (conversations and events) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (bank's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions
|
||||
Reflect and formulate an answer using bank identity, world facts, and opinions. This endpoint: 1. Retrieves experience (conversations and events) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (bank's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -4917,7 +4917,7 @@ class DefaultApi:
|
|||
) -> ApiResponse[ReflectResponse]:
|
||||
"""Reflect and generate answer
|
||||
|
||||
Reflect and formulate an answer using bank identity, world facts, and opinions. This endpoint: 1. Retrieves interactions (conversations and events) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (bank's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions
|
||||
Reflect and formulate an answer using bank identity, world facts, and opinions. This endpoint: 1. Retrieves experience (conversations and events) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (bank's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -4989,7 +4989,7 @@ class DefaultApi:
|
|||
) -> RESTResponseType:
|
||||
"""Reflect and generate answer
|
||||
|
||||
Reflect and formulate an answer using bank identity, world facts, and opinions. This endpoint: 1. Retrieves interactions (conversations and events) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (bank's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions
|
||||
Reflect and formulate an answer using bank identity, world facts, and opinions. This endpoint: 1. Retrieves experience (conversations and events) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (bank's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
|
|
@ -5686,10 +5686,10 @@ class DefaultApi:
|
|||
|
||||
|
||||
@validate_call
|
||||
async def update_bank_personality(
|
||||
async def update_bank_disposition(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
update_personality_request: UpdatePersonalityRequest,
|
||||
update_disposition_request: UpdateDispositionRequest,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
|
|
@ -5703,14 +5703,14 @@ class DefaultApi:
|
|||
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||
) -> BankProfileResponse:
|
||||
"""Update memory bank personality
|
||||
"""Update memory bank disposition
|
||||
|
||||
Update bank's Big Five personality traits and bias strength
|
||||
Update bank's Big Five disposition traits and bias strength
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param update_personality_request: (required)
|
||||
:type update_personality_request: UpdatePersonalityRequest
|
||||
:param update_disposition_request: (required)
|
||||
:type update_disposition_request: UpdateDispositionRequest
|
||||
: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
|
||||
|
|
@ -5733,9 +5733,9 @@ class DefaultApi:
|
|||
:return: Returns the result object.
|
||||
""" # noqa: E501
|
||||
|
||||
_param = self._update_bank_personality_serialize(
|
||||
_param = self._update_bank_disposition_serialize(
|
||||
bank_id=bank_id,
|
||||
update_personality_request=update_personality_request,
|
||||
update_disposition_request=update_disposition_request,
|
||||
_request_auth=_request_auth,
|
||||
_content_type=_content_type,
|
||||
_headers=_headers,
|
||||
|
|
@ -5758,10 +5758,10 @@ class DefaultApi:
|
|||
|
||||
|
||||
@validate_call
|
||||
async def update_bank_personality_with_http_info(
|
||||
async def update_bank_disposition_with_http_info(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
update_personality_request: UpdatePersonalityRequest,
|
||||
update_disposition_request: UpdateDispositionRequest,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
|
|
@ -5775,14 +5775,14 @@ class DefaultApi:
|
|||
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||
) -> ApiResponse[BankProfileResponse]:
|
||||
"""Update memory bank personality
|
||||
"""Update memory bank disposition
|
||||
|
||||
Update bank's Big Five personality traits and bias strength
|
||||
Update bank's Big Five disposition traits and bias strength
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param update_personality_request: (required)
|
||||
:type update_personality_request: UpdatePersonalityRequest
|
||||
:param update_disposition_request: (required)
|
||||
:type update_disposition_request: UpdateDispositionRequest
|
||||
: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
|
||||
|
|
@ -5805,9 +5805,9 @@ class DefaultApi:
|
|||
:return: Returns the result object.
|
||||
""" # noqa: E501
|
||||
|
||||
_param = self._update_bank_personality_serialize(
|
||||
_param = self._update_bank_disposition_serialize(
|
||||
bank_id=bank_id,
|
||||
update_personality_request=update_personality_request,
|
||||
update_disposition_request=update_disposition_request,
|
||||
_request_auth=_request_auth,
|
||||
_content_type=_content_type,
|
||||
_headers=_headers,
|
||||
|
|
@ -5830,10 +5830,10 @@ class DefaultApi:
|
|||
|
||||
|
||||
@validate_call
|
||||
async def update_bank_personality_without_preload_content(
|
||||
async def update_bank_disposition_without_preload_content(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
update_personality_request: UpdatePersonalityRequest,
|
||||
update_disposition_request: UpdateDispositionRequest,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
|
|
@ -5847,14 +5847,14 @@ class DefaultApi:
|
|||
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||
) -> RESTResponseType:
|
||||
"""Update memory bank personality
|
||||
"""Update memory bank disposition
|
||||
|
||||
Update bank's Big Five personality traits and bias strength
|
||||
Update bank's Big Five disposition traits and bias strength
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param update_personality_request: (required)
|
||||
:type update_personality_request: UpdatePersonalityRequest
|
||||
:param update_disposition_request: (required)
|
||||
:type update_disposition_request: UpdateDispositionRequest
|
||||
: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
|
||||
|
|
@ -5877,9 +5877,9 @@ class DefaultApi:
|
|||
:return: Returns the result object.
|
||||
""" # noqa: E501
|
||||
|
||||
_param = self._update_bank_personality_serialize(
|
||||
_param = self._update_bank_disposition_serialize(
|
||||
bank_id=bank_id,
|
||||
update_personality_request=update_personality_request,
|
||||
update_disposition_request=update_disposition_request,
|
||||
_request_auth=_request_auth,
|
||||
_content_type=_content_type,
|
||||
_headers=_headers,
|
||||
|
|
@ -5897,10 +5897,10 @@ class DefaultApi:
|
|||
return response_data.response
|
||||
|
||||
|
||||
def _update_bank_personality_serialize(
|
||||
def _update_bank_disposition_serialize(
|
||||
self,
|
||||
bank_id,
|
||||
update_personality_request,
|
||||
update_disposition_request,
|
||||
_request_auth,
|
||||
_content_type,
|
||||
_headers,
|
||||
|
|
@ -5928,8 +5928,8 @@ class DefaultApi:
|
|||
# process the header parameters
|
||||
# process the form parameters
|
||||
# process the body parameter
|
||||
if update_personality_request is not None:
|
||||
_body_params = update_personality_request
|
||||
if update_disposition_request is not None:
|
||||
_body_params = update_disposition_request
|
||||
|
||||
|
||||
# set the HTTP header `Accept`
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Request model for adding/merging background information.
|
|||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**content** | **str** | New background information to add or merge |
|
||||
**update_personality** | **bool** | If true, infer Big Five personality traits from the merged background (default: true) | [optional] [default to True]
|
||||
**update_disposition** | **bool** | If true, infer Big Five disposition traits from the merged background (default: true) | [optional] [default to True]
|
||||
|
||||
## Example
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Response model for background update.
|
|||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**background** | **str** | |
|
||||
**personality** | [**PersonalityTraits**](PersonalityTraits.md) | | [optional]
|
||||
**disposition** | [**DispositionTraits**](DispositionTraits.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Name | Type | Description | Notes
|
|||
------------ | ------------- | ------------- | -------------
|
||||
**bank_id** | **str** | |
|
||||
**name** | **str** | |
|
||||
**personality** | [**PersonalityTraits**](PersonalityTraits.md) | |
|
||||
**disposition** | [**DispositionTraits**](DispositionTraits.md) | |
|
||||
**background** | **str** | |
|
||||
**created_at** | **str** | | [optional]
|
||||
**updated_at** | **str** | | [optional]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Name | Type | Description | Notes
|
|||
------------ | ------------- | ------------- | -------------
|
||||
**bank_id** | **str** | |
|
||||
**name** | **str** | |
|
||||
**personality** | [**PersonalityTraits**](PersonalityTraits.md) | |
|
||||
**disposition** | [**DispositionTraits**](DispositionTraits.md) | |
|
||||
**background** | **str** | |
|
||||
|
||||
## Example
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Request model for creating/updating a bank.
|
|||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | **str** | | [optional]
|
||||
**personality** | [**PersonalityTraits**](PersonalityTraits.md) | | [optional]
|
||||
**disposition** | [**DispositionTraits**](DispositionTraits.md) | | [optional]
|
||||
**background** | **str** | | [optional]
|
||||
|
||||
## Example
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Method | HTTP request | Description
|
|||
[**reflect**](DefaultApi.md#reflect) | **POST** /v1/default/banks/{bank_id}/reflect | Reflect and generate answer
|
||||
[**regenerate_entity_observations**](DefaultApi.md#regenerate_entity_observations) | **POST** /v1/default/banks/{bank_id}/entities/{entity_id}/regenerate | Regenerate entity observations
|
||||
[**retain_memories**](DefaultApi.md#retain_memories) | **POST** /v1/default/banks/{bank_id}/memories | Retain memories
|
||||
[**update_bank_personality**](DefaultApi.md#update_bank_personality) | **PUT** /v1/default/banks/{bank_id}/profile | Update memory bank personality
|
||||
[**update_bank_disposition**](DefaultApi.md#update_bank_disposition) | **PUT** /v1/default/banks/{bank_id}/profile | Update memory bank disposition
|
||||
|
||||
|
||||
# **add_bank_background**
|
||||
|
|
@ -32,7 +32,7 @@ Method | HTTP request | Description
|
|||
|
||||
Add/merge memory bank background
|
||||
|
||||
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.
|
||||
Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.
|
||||
|
||||
### Example
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ No authorization required
|
|||
|
||||
Clear memory bank memories
|
||||
|
||||
Delete memory units for a memory bank. Optionally filter by type (world, interactions, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.
|
||||
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.
|
||||
|
||||
### Example
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ async with hindsight_client_api.ApiClient(configuration) as api_client:
|
|||
# Create an instance of the API class
|
||||
api_instance = hindsight_client_api.DefaultApi(api_client)
|
||||
bank_id = 'bank_id_example' # str |
|
||||
type = 'type_example' # str | Optional fact type filter (world, interactions, opinion) (optional)
|
||||
type = 'type_example' # str | Optional fact type filter (world, experience, opinion) (optional)
|
||||
|
||||
try:
|
||||
# Clear memory bank memories
|
||||
|
|
@ -216,7 +216,7 @@ async with hindsight_client_api.ApiClient(configuration) as api_client:
|
|||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**bank_id** | **str**| |
|
||||
**type** | **str**| Optional fact type filter (world, interactions, opinion) | [optional]
|
||||
**type** | **str**| Optional fact type filter (world, experience, opinion) | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
|
|
@ -245,7 +245,7 @@ No authorization required
|
|||
|
||||
Create or update memory bank
|
||||
|
||||
Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.
|
||||
Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.
|
||||
|
||||
### Example
|
||||
|
||||
|
|
@ -462,7 +462,7 @@ No authorization required
|
|||
|
||||
Get memory bank profile
|
||||
|
||||
Get personality traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
|
||||
### Example
|
||||
|
||||
|
|
@ -742,7 +742,7 @@ No authorization required
|
|||
|
||||
Get memory graph data
|
||||
|
||||
Retrieve graph data for visualization, optionally filtered by type (world/interactions/opinion). Limited to 1000 most recent items.
|
||||
Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.
|
||||
|
||||
### Example
|
||||
|
||||
|
|
@ -1172,7 +1172,7 @@ Recall memory using semantic similarity and spreading activation.
|
|||
|
||||
The type parameter is optional and must be one of:
|
||||
- 'world': General knowledge about people, places, events, and things that happen
|
||||
- 'interactions': Memories about interactions, conversations, actions taken, and tasks performed
|
||||
- 'experience': Memories about experience, conversations, actions taken, and tasks performed
|
||||
- 'opinion': The bank's formed beliefs, perspectives, and viewpoints
|
||||
|
||||
Set include_entities=true to get entity observations alongside recall results.
|
||||
|
|
@ -1250,7 +1250,7 @@ Reflect and generate answer
|
|||
Reflect and formulate an answer using bank identity, world facts, and opinions.
|
||||
|
||||
This endpoint:
|
||||
1. Retrieves interactions (conversations and events)
|
||||
1. Retrieves experience (conversations and events)
|
||||
2. Retrieves world facts relevant to the query
|
||||
3. Retrieves existing opinions (bank's perspectives)
|
||||
4. Uses LLM to formulate a contextual answer
|
||||
|
|
@ -1494,12 +1494,12 @@ No authorization required
|
|||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **update_bank_personality**
|
||||
> BankProfileResponse update_bank_personality(bank_id, update_personality_request)
|
||||
# **update_bank_disposition**
|
||||
> BankProfileResponse update_bank_disposition(bank_id, update_disposition_request)
|
||||
|
||||
Update memory bank personality
|
||||
Update memory bank disposition
|
||||
|
||||
Update bank's Big Five personality traits and bias strength
|
||||
Update bank's Big Five disposition traits and bias strength
|
||||
|
||||
### Example
|
||||
|
||||
|
|
@ -1507,7 +1507,7 @@ Update bank's Big Five personality traits and bias strength
|
|||
```python
|
||||
import hindsight_client_api
|
||||
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
|
||||
from hindsight_client_api.models.update_personality_request import UpdatePersonalityRequest
|
||||
from hindsight_client_api.models.update_disposition_request import UpdateDispositionRequest
|
||||
from hindsight_client_api.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
|
|
@ -1523,15 +1523,15 @@ async with hindsight_client_api.ApiClient(configuration) as api_client:
|
|||
# Create an instance of the API class
|
||||
api_instance = hindsight_client_api.DefaultApi(api_client)
|
||||
bank_id = 'bank_id_example' # str |
|
||||
update_personality_request = hindsight_client_api.UpdatePersonalityRequest() # UpdatePersonalityRequest |
|
||||
update_disposition_request = hindsight_client_api.UpdateDispositionRequest() # UpdateDispositionRequest |
|
||||
|
||||
try:
|
||||
# Update memory bank personality
|
||||
api_response = await api_instance.update_bank_personality(bank_id, update_personality_request)
|
||||
print("The response of DefaultApi->update_bank_personality:\n")
|
||||
# Update memory bank disposition
|
||||
api_response = await api_instance.update_bank_disposition(bank_id, update_disposition_request)
|
||||
print("The response of DefaultApi->update_bank_disposition:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling DefaultApi->update_bank_personality: %s\n" % e)
|
||||
print("Exception when calling DefaultApi->update_bank_disposition: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
|
@ -1542,7 +1542,7 @@ async with hindsight_client_api.ApiClient(configuration) as api_client:
|
|||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**bank_id** | **str**| |
|
||||
**update_personality_request** | [**UpdatePersonalityRequest**](UpdatePersonalityRequest.md)| |
|
||||
**update_disposition_request** | [**UpdateDispositionRequest**](UpdateDispositionRequest.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# PersonalityTraits
|
||||
# DispositionTraits
|
||||
|
||||
Personality traits based on Big Five model.
|
||||
Disposition traits based on Big Five model.
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
@ -11,24 +11,24 @@ Name | Type | Description | Notes
|
|||
**extraversion** | **float** | Extraversion (0-1) |
|
||||
**agreeableness** | **float** | Agreeableness (0-1) |
|
||||
**neuroticism** | **float** | Neuroticism (0-1) |
|
||||
**bias_strength** | **float** | How strongly personality influences opinions (0-1) |
|
||||
**bias_strength** | **float** | How strongly disposition influences opinions (0-1) |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of PersonalityTraits from a JSON string
|
||||
personality_traits_instance = PersonalityTraits.from_json(json)
|
||||
# create an instance of DispositionTraits from a JSON string
|
||||
disposition_traits_instance = DispositionTraits.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(PersonalityTraits.to_json())
|
||||
print(DispositionTraits.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
personality_traits_dict = personality_traits_instance.to_dict()
|
||||
# create an instance of PersonalityTraits from a dict
|
||||
personality_traits_from_dict = PersonalityTraits.from_dict(personality_traits_dict)
|
||||
disposition_traits_dict = disposition_traits_instance.to_dict()
|
||||
# create an instance of DispositionTraits from a dict
|
||||
disposition_traits_from_dict = DispositionTraits.from_dict(disposition_traits_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# UpdateDispositionRequest
|
||||
|
||||
Request model for updating disposition traits.
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**disposition** | [**DispositionTraits**](DispositionTraits.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from hindsight_client_api.models.update_disposition_request import UpdateDispositionRequest
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of UpdateDispositionRequest from a JSON string
|
||||
update_disposition_request_instance = UpdateDispositionRequest.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(UpdateDispositionRequest.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
update_disposition_request_dict = update_disposition_request_instance.to_dict()
|
||||
# create an instance of UpdateDispositionRequest from a dict
|
||||
update_disposition_request_from_dict = UpdateDispositionRequest.from_dict(update_disposition_request_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# UpdatePersonalityRequest
|
||||
|
||||
Request model for updating personality traits.
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**personality** | [**PersonalityTraits**](PersonalityTraits.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from hindsight_client_api.models.update_personality_request import UpdatePersonalityRequest
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of UpdatePersonalityRequest from a JSON string
|
||||
update_personality_request_instance = UpdatePersonalityRequest.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(UpdatePersonalityRequest.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
update_personality_request_dict = update_personality_request_instance.to_dict()
|
||||
# create an instance of UpdatePersonalityRequest from a dict
|
||||
update_personality_request_from_dict = UpdatePersonalityRequest.from_dict(update_personality_request_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
|
|
@ -24,6 +24,7 @@ from hindsight_client_api.models.chunk_include_options import ChunkIncludeOption
|
|||
from hindsight_client_api.models.chunk_response import ChunkResponse
|
||||
from hindsight_client_api.models.create_bank_request import CreateBankRequest
|
||||
from hindsight_client_api.models.delete_response import DeleteResponse
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits
|
||||
from hindsight_client_api.models.document_response import DocumentResponse
|
||||
from hindsight_client_api.models.entity_detail_response import EntityDetailResponse
|
||||
from hindsight_client_api.models.entity_include_options import EntityIncludeOptions
|
||||
|
|
@ -38,7 +39,6 @@ from hindsight_client_api.models.list_documents_response import ListDocumentsRes
|
|||
from hindsight_client_api.models.list_memory_units_response import ListMemoryUnitsResponse
|
||||
from hindsight_client_api.models.memory_item import MemoryItem
|
||||
from hindsight_client_api.models.metadata_filter import MetadataFilter
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits
|
||||
from hindsight_client_api.models.recall_request import RecallRequest
|
||||
from hindsight_client_api.models.recall_response import RecallResponse
|
||||
from hindsight_client_api.models.recall_result import RecallResult
|
||||
|
|
@ -48,7 +48,7 @@ from hindsight_client_api.models.reflect_request import ReflectRequest
|
|||
from hindsight_client_api.models.reflect_response import ReflectResponse
|
||||
from hindsight_client_api.models.retain_request import RetainRequest
|
||||
from hindsight_client_api.models.retain_response import RetainResponse
|
||||
from hindsight_client_api.models.update_personality_request import UpdatePersonalityRequest
|
||||
from hindsight_client_api.models.update_disposition_request import UpdateDispositionRequest
|
||||
from hindsight_client_api.models.validation_error import ValidationError
|
||||
from hindsight_client_api.models.validation_error_loc_inner import ValidationErrorLocInner
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ class AddBackgroundRequest(BaseModel):
|
|||
Request model for adding/merging background information.
|
||||
""" # noqa: E501
|
||||
content: StrictStr = Field(description="New background information to add or merge")
|
||||
update_personality: Optional[StrictBool] = Field(default=True, description="If true, infer Big Five personality traits from the merged background (default: true)")
|
||||
__properties: ClassVar[List[str]] = ["content", "update_personality"]
|
||||
update_disposition: Optional[StrictBool] = Field(default=True, description="If true, infer Big Five disposition traits from the merged background (default: true)")
|
||||
__properties: ClassVar[List[str]] = ["content", "update_disposition"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
|
|
@ -82,7 +82,7 @@ class AddBackgroundRequest(BaseModel):
|
|||
|
||||
_obj = cls.model_validate({
|
||||
"content": obj.get("content"),
|
||||
"update_personality": obj.get("update_personality") if obj.get("update_personality") is not None else True
|
||||
"update_disposition": obj.get("update_disposition") if obj.get("update_disposition") is not None else True
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import json
|
|||
|
||||
from pydantic import BaseModel, ConfigDict, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
|
|
@ -28,8 +28,8 @@ class BackgroundResponse(BaseModel):
|
|||
Response model for background update.
|
||||
""" # noqa: E501
|
||||
background: StrictStr
|
||||
personality: Optional[PersonalityTraits] = None
|
||||
__properties: ClassVar[List[str]] = ["background", "personality"]
|
||||
disposition: Optional[DispositionTraits] = None
|
||||
__properties: ClassVar[List[str]] = ["background", "disposition"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
|
|
@ -70,13 +70,13 @@ class BackgroundResponse(BaseModel):
|
|||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of personality
|
||||
if self.personality:
|
||||
_dict['personality'] = self.personality.to_dict()
|
||||
# set to None if personality (nullable) is None
|
||||
# override the default output from pydantic by calling `to_dict()` of disposition
|
||||
if self.disposition:
|
||||
_dict['disposition'] = self.disposition.to_dict()
|
||||
# set to None if disposition (nullable) is None
|
||||
# and model_fields_set contains the field
|
||||
if self.personality is None and "personality" in self.model_fields_set:
|
||||
_dict['personality'] = None
|
||||
if self.disposition is None and "disposition" in self.model_fields_set:
|
||||
_dict['disposition'] = None
|
||||
|
||||
return _dict
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ class BackgroundResponse(BaseModel):
|
|||
|
||||
_obj = cls.model_validate({
|
||||
"background": obj.get("background"),
|
||||
"personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None
|
||||
"disposition": DispositionTraits.from_dict(obj["disposition"]) if obj.get("disposition") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import json
|
|||
|
||||
from pydantic import BaseModel, ConfigDict, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
|
|
@ -29,11 +29,11 @@ class BankListItem(BaseModel):
|
|||
""" # noqa: E501
|
||||
bank_id: StrictStr
|
||||
name: StrictStr
|
||||
personality: PersonalityTraits
|
||||
disposition: DispositionTraits
|
||||
background: StrictStr
|
||||
created_at: Optional[StrictStr] = None
|
||||
updated_at: Optional[StrictStr] = None
|
||||
__properties: ClassVar[List[str]] = ["bank_id", "name", "personality", "background", "created_at", "updated_at"]
|
||||
__properties: ClassVar[List[str]] = ["bank_id", "name", "disposition", "background", "created_at", "updated_at"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
|
|
@ -74,9 +74,9 @@ class BankListItem(BaseModel):
|
|||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of personality
|
||||
if self.personality:
|
||||
_dict['personality'] = self.personality.to_dict()
|
||||
# override the default output from pydantic by calling `to_dict()` of disposition
|
||||
if self.disposition:
|
||||
_dict['disposition'] = self.disposition.to_dict()
|
||||
# set to None if created_at (nullable) is None
|
||||
# and model_fields_set contains the field
|
||||
if self.created_at is None and "created_at" in self.model_fields_set:
|
||||
|
|
@ -101,7 +101,7 @@ class BankListItem(BaseModel):
|
|||
_obj = cls.model_validate({
|
||||
"bank_id": obj.get("bank_id"),
|
||||
"name": obj.get("name"),
|
||||
"personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None,
|
||||
"disposition": DispositionTraits.from_dict(obj["disposition"]) if obj.get("disposition") is not None else None,
|
||||
"background": obj.get("background"),
|
||||
"created_at": obj.get("created_at"),
|
||||
"updated_at": obj.get("updated_at")
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import json
|
|||
|
||||
from pydantic import BaseModel, ConfigDict, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
|
|
@ -29,9 +29,9 @@ class BankProfileResponse(BaseModel):
|
|||
""" # noqa: E501
|
||||
bank_id: StrictStr
|
||||
name: StrictStr
|
||||
personality: PersonalityTraits
|
||||
disposition: DispositionTraits
|
||||
background: StrictStr
|
||||
__properties: ClassVar[List[str]] = ["bank_id", "name", "personality", "background"]
|
||||
__properties: ClassVar[List[str]] = ["bank_id", "name", "disposition", "background"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
|
|
@ -72,9 +72,9 @@ class BankProfileResponse(BaseModel):
|
|||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of personality
|
||||
if self.personality:
|
||||
_dict['personality'] = self.personality.to_dict()
|
||||
# override the default output from pydantic by calling `to_dict()` of disposition
|
||||
if self.disposition:
|
||||
_dict['disposition'] = self.disposition.to_dict()
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
|
|
@ -89,7 +89,7 @@ class BankProfileResponse(BaseModel):
|
|||
_obj = cls.model_validate({
|
||||
"bank_id": obj.get("bank_id"),
|
||||
"name": obj.get("name"),
|
||||
"personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None,
|
||||
"disposition": DispositionTraits.from_dict(obj["disposition"]) if obj.get("disposition") is not None else None,
|
||||
"background": obj.get("background")
|
||||
})
|
||||
return _obj
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import json
|
|||
|
||||
from pydantic import BaseModel, ConfigDict, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
|
|
@ -28,9 +28,9 @@ class CreateBankRequest(BaseModel):
|
|||
Request model for creating/updating a bank.
|
||||
""" # noqa: E501
|
||||
name: Optional[StrictStr] = None
|
||||
personality: Optional[PersonalityTraits] = None
|
||||
disposition: Optional[DispositionTraits] = None
|
||||
background: Optional[StrictStr] = None
|
||||
__properties: ClassVar[List[str]] = ["name", "personality", "background"]
|
||||
__properties: ClassVar[List[str]] = ["name", "disposition", "background"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
|
|
@ -71,18 +71,18 @@ class CreateBankRequest(BaseModel):
|
|||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of personality
|
||||
if self.personality:
|
||||
_dict['personality'] = self.personality.to_dict()
|
||||
# override the default output from pydantic by calling `to_dict()` of disposition
|
||||
if self.disposition:
|
||||
_dict['disposition'] = self.disposition.to_dict()
|
||||
# set to None if name (nullable) is None
|
||||
# and model_fields_set contains the field
|
||||
if self.name is None and "name" in self.model_fields_set:
|
||||
_dict['name'] = None
|
||||
|
||||
# set to None if personality (nullable) is None
|
||||
# set to None if disposition (nullable) is None
|
||||
# and model_fields_set contains the field
|
||||
if self.personality is None and "personality" in self.model_fields_set:
|
||||
_dict['personality'] = None
|
||||
if self.disposition is None and "disposition" in self.model_fields_set:
|
||||
_dict['disposition'] = None
|
||||
|
||||
# set to None if background (nullable) is None
|
||||
# and model_fields_set contains the field
|
||||
|
|
@ -102,7 +102,7 @@ class CreateBankRequest(BaseModel):
|
|||
|
||||
_obj = cls.model_validate({
|
||||
"name": obj.get("name"),
|
||||
"personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None,
|
||||
"disposition": DispositionTraits.from_dict(obj["disposition"]) if obj.get("disposition") is not None else None,
|
||||
"background": obj.get("background")
|
||||
})
|
||||
return _obj
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ from typing_extensions import Annotated
|
|||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class PersonalityTraits(BaseModel):
|
||||
class DispositionTraits(BaseModel):
|
||||
"""
|
||||
Personality traits based on Big Five model.
|
||||
Disposition traits based on Big Five model.
|
||||
""" # noqa: E501
|
||||
openness: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Openness to experience (0-1)")
|
||||
conscientiousness: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Conscientiousness (0-1)")
|
||||
extraversion: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Extraversion (0-1)")
|
||||
agreeableness: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Agreeableness (0-1)")
|
||||
neuroticism: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Neuroticism (0-1)")
|
||||
bias_strength: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="How strongly personality influences opinions (0-1)")
|
||||
bias_strength: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="How strongly disposition influences opinions (0-1)")
|
||||
__properties: ClassVar[List[str]] = ["openness", "conscientiousness", "extraversion", "agreeableness", "neuroticism", "bias_strength"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
|
|
@ -53,7 +53,7 @@ class PersonalityTraits(BaseModel):
|
|||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of PersonalityTraits from a JSON string"""
|
||||
"""Create an instance of DispositionTraits from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
|
|
@ -78,7 +78,7 @@ class PersonalityTraits(BaseModel):
|
|||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of PersonalityTraits from a dict"""
|
||||
"""Create an instance of DispositionTraits from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
|
|
@ -19,16 +19,16 @@ import json
|
|||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from typing import Any, ClassVar, Dict, List
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class UpdatePersonalityRequest(BaseModel):
|
||||
class UpdateDispositionRequest(BaseModel):
|
||||
"""
|
||||
Request model for updating personality traits.
|
||||
Request model for updating disposition traits.
|
||||
""" # noqa: E501
|
||||
personality: PersonalityTraits
|
||||
__properties: ClassVar[List[str]] = ["personality"]
|
||||
disposition: DispositionTraits
|
||||
__properties: ClassVar[List[str]] = ["disposition"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
|
|
@ -48,7 +48,7 @@ class UpdatePersonalityRequest(BaseModel):
|
|||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of UpdatePersonalityRequest from a JSON string"""
|
||||
"""Create an instance of UpdateDispositionRequest from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
|
|
@ -69,14 +69,14 @@ class UpdatePersonalityRequest(BaseModel):
|
|||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of personality
|
||||
if self.personality:
|
||||
_dict['personality'] = self.personality.to_dict()
|
||||
# override the default output from pydantic by calling `to_dict()` of disposition
|
||||
if self.disposition:
|
||||
_dict['disposition'] = self.disposition.to_dict()
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of UpdatePersonalityRequest from a dict"""
|
||||
"""Create an instance of UpdateDispositionRequest from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ class UpdatePersonalityRequest(BaseModel):
|
|||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None
|
||||
"disposition": DispositionTraits.from_dict(obj["disposition"]) if obj.get("disposition") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ class TestAddBackgroundRequest(unittest.TestCase):
|
|||
if include_optional:
|
||||
return AddBackgroundRequest(
|
||||
content = '',
|
||||
update_personality = True
|
||||
update_disposition = True
|
||||
)
|
||||
else:
|
||||
return AddBackgroundRequest(
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class TestBackgroundResponse(unittest.TestCase):
|
|||
if include_optional:
|
||||
return BackgroundResponse(
|
||||
background = '',
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}
|
||||
)
|
||||
else:
|
||||
return BackgroundResponse(
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class TestBankListItem(unittest.TestCase):
|
|||
return BankListItem(
|
||||
bank_id = '',
|
||||
name = '',
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
background = '',
|
||||
created_at = '',
|
||||
updated_at = ''
|
||||
|
|
@ -46,7 +46,7 @@ class TestBankListItem(unittest.TestCase):
|
|||
return BankListItem(
|
||||
bank_id = '',
|
||||
name = '',
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
background = '',
|
||||
)
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class TestBankListResponse(unittest.TestCase):
|
|||
hindsight_client_api.models.bank_list_item.BankListItem(
|
||||
bank_id = '',
|
||||
name = '',
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
background = '',
|
||||
created_at = '',
|
||||
updated_at = '', )
|
||||
|
|
@ -51,7 +51,7 @@ class TestBankListResponse(unittest.TestCase):
|
|||
hindsight_client_api.models.bank_list_item.BankListItem(
|
||||
bank_id = '',
|
||||
name = '',
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
background = '',
|
||||
created_at = '',
|
||||
updated_at = '', )
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@ class TestBankProfileResponse(unittest.TestCase):
|
|||
return BankProfileResponse(
|
||||
bank_id = '',
|
||||
name = '',
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
background = ''
|
||||
)
|
||||
else:
|
||||
return BankProfileResponse(
|
||||
bank_id = '',
|
||||
name = '',
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
background = '',
|
||||
)
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class TestCreateBankRequest(unittest.TestCase):
|
|||
if include_optional:
|
||||
return CreateBankRequest(
|
||||
name = '',
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
background = ''
|
||||
)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -166,10 +166,10 @@ class TestDefaultApi(unittest.IsolatedAsyncioTestCase):
|
|||
"""
|
||||
pass
|
||||
|
||||
async def test_update_bank_personality(self) -> None:
|
||||
"""Test case for update_bank_personality
|
||||
async def test_update_bank_disposition(self) -> None:
|
||||
"""Test case for update_bank_disposition
|
||||
|
||||
Update memory bank personality
|
||||
Update memory bank disposition
|
||||
"""
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
import unittest
|
||||
|
||||
from hindsight_client_api.models.personality_traits import PersonalityTraits
|
||||
from hindsight_client_api.models.disposition_traits import DispositionTraits
|
||||
|
||||
class TestPersonalityTraits(unittest.TestCase):
|
||||
"""PersonalityTraits unit test stubs"""
|
||||
class TestDispositionTraits(unittest.TestCase):
|
||||
"""DispositionTraits unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
|
@ -25,16 +25,16 @@ class TestPersonalityTraits(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> PersonalityTraits:
|
||||
"""Test PersonalityTraits
|
||||
def make_instance(self, include_optional) -> DispositionTraits:
|
||||
"""Test DispositionTraits
|
||||
include_optional is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `PersonalityTraits`
|
||||
# uncomment below to create an instance of `DispositionTraits`
|
||||
"""
|
||||
model = PersonalityTraits()
|
||||
model = DispositionTraits()
|
||||
if include_optional:
|
||||
return PersonalityTraits(
|
||||
return DispositionTraits(
|
||||
openness = 0.0,
|
||||
conscientiousness = 0.0,
|
||||
extraversion = 0.0,
|
||||
|
|
@ -43,7 +43,7 @@ class TestPersonalityTraits(unittest.TestCase):
|
|||
bias_strength = 0.0
|
||||
)
|
||||
else:
|
||||
return PersonalityTraits(
|
||||
return DispositionTraits(
|
||||
openness = 0.0,
|
||||
conscientiousness = 0.0,
|
||||
extraversion = 0.0,
|
||||
|
|
@ -53,8 +53,8 @@ class TestPersonalityTraits(unittest.TestCase):
|
|||
)
|
||||
"""
|
||||
|
||||
def testPersonalityTraits(self):
|
||||
"""Test PersonalityTraits"""
|
||||
def testDispositionTraits(self):
|
||||
"""Test DispositionTraits"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
import unittest
|
||||
|
||||
from hindsight_client_api.models.update_personality_request import UpdatePersonalityRequest
|
||||
from hindsight_client_api.models.update_disposition_request import UpdateDispositionRequest
|
||||
|
||||
class TestUpdatePersonalityRequest(unittest.TestCase):
|
||||
"""UpdatePersonalityRequest unit test stubs"""
|
||||
class TestUpdateDispositionRequest(unittest.TestCase):
|
||||
"""UpdateDispositionRequest unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
|
@ -25,26 +25,26 @@ class TestUpdatePersonalityRequest(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> UpdatePersonalityRequest:
|
||||
"""Test UpdatePersonalityRequest
|
||||
def make_instance(self, include_optional) -> UpdateDispositionRequest:
|
||||
"""Test UpdateDispositionRequest
|
||||
include_optional is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `UpdatePersonalityRequest`
|
||||
# uncomment below to create an instance of `UpdateDispositionRequest`
|
||||
"""
|
||||
model = UpdatePersonalityRequest()
|
||||
model = UpdateDispositionRequest()
|
||||
if include_optional:
|
||||
return UpdatePersonalityRequest(
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}
|
||||
return UpdateDispositionRequest(
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}
|
||||
)
|
||||
else:
|
||||
return UpdatePersonalityRequest(
|
||||
personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
return UpdateDispositionRequest(
|
||||
disposition = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8},
|
||||
)
|
||||
"""
|
||||
|
||||
def testUpdatePersonalityRequest(self):
|
||||
"""Test UpdatePersonalityRequest"""
|
||||
def testUpdateDispositionRequest(self):
|
||||
"""Test UpdateDispositionRequest"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import type { Client, Options as Options2, TDataShape } from './client';
|
||||
import { client } from './client.gen';
|
||||
import type { AddBankBackgroundData, AddBankBackgroundErrors, AddBankBackgroundResponses, CancelOperationData, CancelOperationErrors, CancelOperationResponses, ClearBankMemoriesData, ClearBankMemoriesErrors, ClearBankMemoriesResponses, CreateOrUpdateBankData, CreateOrUpdateBankErrors, CreateOrUpdateBankResponses, DeleteDocumentData, DeleteDocumentErrors, DeleteDocumentResponses, GetAgentStatsData, GetAgentStatsErrors, GetAgentStatsResponses, GetBankProfileData, GetBankProfileErrors, GetBankProfileResponses, GetChunkData, GetChunkErrors, GetChunkResponses, GetDocumentData, GetDocumentErrors, GetDocumentResponses, GetEntityData, GetEntityErrors, GetEntityResponses, GetGraphData, GetGraphErrors, GetGraphResponses, HealthEndpointHealthGetData, HealthEndpointHealthGetResponses, ListBanksData, ListBanksResponses, ListDocumentsData, ListDocumentsErrors, ListDocumentsResponses, ListEntitiesData, ListEntitiesErrors, ListEntitiesResponses, ListMemoriesData, ListMemoriesErrors, ListMemoriesResponses, ListOperationsData, ListOperationsErrors, ListOperationsResponses, MetricsEndpointMetricsGetData, MetricsEndpointMetricsGetResponses, RecallMemoriesData, RecallMemoriesErrors, RecallMemoriesResponses, ReflectData, ReflectErrors, ReflectResponses, RegenerateEntityObservationsData, RegenerateEntityObservationsErrors, RegenerateEntityObservationsResponses, RetainMemoriesData, RetainMemoriesErrors, RetainMemoriesResponses, UpdateBankPersonalityData, UpdateBankPersonalityErrors, UpdateBankPersonalityResponses } from './types.gen';
|
||||
import type { AddBankBackgroundData, AddBankBackgroundErrors, AddBankBackgroundResponses, CancelOperationData, CancelOperationErrors, CancelOperationResponses, ClearBankMemoriesData, ClearBankMemoriesErrors, ClearBankMemoriesResponses, CreateOrUpdateBankData, CreateOrUpdateBankErrors, CreateOrUpdateBankResponses, DeleteDocumentData, DeleteDocumentErrors, DeleteDocumentResponses, GetAgentStatsData, GetAgentStatsErrors, GetAgentStatsResponses, GetBankProfileData, GetBankProfileErrors, GetBankProfileResponses, GetChunkData, GetChunkErrors, GetChunkResponses, GetDocumentData, GetDocumentErrors, GetDocumentResponses, GetEntityData, GetEntityErrors, GetEntityResponses, GetGraphData, GetGraphErrors, GetGraphResponses, HealthEndpointHealthGetData, HealthEndpointHealthGetResponses, ListBanksData, ListBanksResponses, ListDocumentsData, ListDocumentsErrors, ListDocumentsResponses, ListEntitiesData, ListEntitiesErrors, ListEntitiesResponses, ListMemoriesData, ListMemoriesErrors, ListMemoriesResponses, ListOperationsData, ListOperationsErrors, ListOperationsResponses, MetricsEndpointMetricsGetData, MetricsEndpointMetricsGetResponses, RecallMemoriesData, RecallMemoriesErrors, RecallMemoriesResponses, ReflectData, ReflectErrors, ReflectResponses, RegenerateEntityObservationsData, RegenerateEntityObservationsErrors, RegenerateEntityObservationsResponses, RetainMemoriesData, RetainMemoriesErrors, RetainMemoriesResponses, UpdateBankDispositionData, UpdateBankDispositionErrors, UpdateBankDispositionResponses } from './types.gen';
|
||||
|
||||
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & {
|
||||
/**
|
||||
|
|
@ -35,7 +35,7 @@ export const metricsEndpointMetricsGet = <ThrowOnError extends boolean = false>(
|
|||
/**
|
||||
* Get memory graph data
|
||||
*
|
||||
* Retrieve graph data for visualization, optionally filtered by type (world/interactions/opinion). Limited to 1000 most recent items.
|
||||
* Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.
|
||||
*/
|
||||
export const getGraph = <ThrowOnError extends boolean = false>(options: Options<GetGraphData, ThrowOnError>) => (options.client ?? client).get<GetGraphResponses, GetGraphErrors, ThrowOnError>({ url: '/v1/default/banks/{bank_id}/graph', ...options });
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ export const listMemories = <ThrowOnError extends boolean = false>(options: Opti
|
|||
*
|
||||
* The type parameter is optional and must be one of:
|
||||
* - 'world': General knowledge about people, places, events, and things that happen
|
||||
* - 'interactions': Memories about interactions, conversations, actions taken, and tasks performed
|
||||
* - 'experience': Memories about experience, conversations, actions taken, and tasks performed
|
||||
* - 'opinion': The bank's formed beliefs, perspectives, and viewpoints
|
||||
*
|
||||
* Set include_entities=true to get entity observations alongside recall results.
|
||||
|
|
@ -73,7 +73,7 @@ export const recallMemories = <ThrowOnError extends boolean = false>(options: Op
|
|||
* Reflect and formulate an answer using bank identity, world facts, and opinions.
|
||||
*
|
||||
* This endpoint:
|
||||
* 1. Retrieves interactions (conversations and events)
|
||||
* 1. Retrieves experience (conversations and events)
|
||||
* 2. Retrieves world facts relevant to the query
|
||||
* 3. Retrieves existing opinions (bank's perspectives)
|
||||
* 4. Uses LLM to formulate a contextual answer
|
||||
|
|
@ -176,16 +176,16 @@ export const cancelOperation = <ThrowOnError extends boolean = false>(options: O
|
|||
/**
|
||||
* Get memory bank profile
|
||||
*
|
||||
* Get personality traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
* Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.
|
||||
*/
|
||||
export const getBankProfile = <ThrowOnError extends boolean = false>(options: Options<GetBankProfileData, ThrowOnError>) => (options.client ?? client).get<GetBankProfileResponses, GetBankProfileErrors, ThrowOnError>({ url: '/v1/default/banks/{bank_id}/profile', ...options });
|
||||
|
||||
/**
|
||||
* Update memory bank personality
|
||||
* Update memory bank disposition
|
||||
*
|
||||
* Update bank's Big Five personality traits and bias strength
|
||||
* Update bank's Big Five disposition traits and bias strength
|
||||
*/
|
||||
export const updateBankPersonality = <ThrowOnError extends boolean = false>(options: Options<UpdateBankPersonalityData, ThrowOnError>) => (options.client ?? client).put<UpdateBankPersonalityResponses, UpdateBankPersonalityErrors, ThrowOnError>({
|
||||
export const updateBankDisposition = <ThrowOnError extends boolean = false>(options: Options<UpdateBankDispositionData, ThrowOnError>) => (options.client ?? client).put<UpdateBankDispositionResponses, UpdateBankDispositionErrors, ThrowOnError>({
|
||||
url: '/v1/default/banks/{bank_id}/profile',
|
||||
...options,
|
||||
headers: {
|
||||
|
|
@ -197,7 +197,7 @@ export const updateBankPersonality = <ThrowOnError extends boolean = false>(opti
|
|||
/**
|
||||
* Add/merge memory bank background
|
||||
*
|
||||
* Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.
|
||||
* Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.
|
||||
*/
|
||||
export const addBankBackground = <ThrowOnError extends boolean = false>(options: Options<AddBankBackgroundData, ThrowOnError>) => (options.client ?? client).post<AddBankBackgroundResponses, AddBankBackgroundErrors, ThrowOnError>({
|
||||
url: '/v1/default/banks/{bank_id}/background',
|
||||
|
|
@ -211,7 +211,7 @@ export const addBankBackground = <ThrowOnError extends boolean = false>(options:
|
|||
/**
|
||||
* Create or update memory bank
|
||||
*
|
||||
* Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.
|
||||
* Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.
|
||||
*/
|
||||
export const createOrUpdateBank = <ThrowOnError extends boolean = false>(options: Options<CreateOrUpdateBankData, ThrowOnError>) => (options.client ?? client).put<CreateOrUpdateBankResponses, CreateOrUpdateBankErrors, ThrowOnError>({
|
||||
url: '/v1/default/banks/{bank_id}',
|
||||
|
|
@ -225,7 +225,7 @@ export const createOrUpdateBank = <ThrowOnError extends boolean = false>(options
|
|||
/**
|
||||
* Clear memory bank memories
|
||||
*
|
||||
* Delete memory units for a memory bank. Optionally filter by type (world, interactions, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.
|
||||
* 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.
|
||||
*/
|
||||
export const clearBankMemories = <ThrowOnError extends boolean = false>(options: Options<ClearBankMemoriesData, ThrowOnError>) => (options.client ?? client).delete<ClearBankMemoriesResponses, ClearBankMemoriesErrors, ThrowOnError>({ url: '/v1/default/banks/{bank_id}/memories', ...options });
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ export type AddBackgroundRequest = {
|
|||
*/
|
||||
content: string;
|
||||
/**
|
||||
* Update Personality
|
||||
* Update Disposition
|
||||
*
|
||||
* If true, infer Big Five personality traits from the merged background (default: true)
|
||||
* If true, infer Big Five disposition traits from the merged background (default: true)
|
||||
*/
|
||||
update_personality?: boolean;
|
||||
update_disposition?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -34,7 +34,7 @@ export type BackgroundResponse = {
|
|||
* Background
|
||||
*/
|
||||
background: string;
|
||||
personality?: PersonalityTraits | null;
|
||||
disposition?: DispositionTraits | null;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -51,7 +51,7 @@ export type BankListItem = {
|
|||
* Name
|
||||
*/
|
||||
name: string;
|
||||
personality: PersonalityTraits;
|
||||
disposition: DispositionTraits;
|
||||
/**
|
||||
* Background
|
||||
*/
|
||||
|
|
@ -92,7 +92,7 @@ export type BankProfileResponse = {
|
|||
* Name
|
||||
*/
|
||||
name: string;
|
||||
personality: PersonalityTraits;
|
||||
disposition: DispositionTraits;
|
||||
/**
|
||||
* Background
|
||||
*/
|
||||
|
|
@ -188,7 +188,7 @@ export type CreateBankRequest = {
|
|||
* Name
|
||||
*/
|
||||
name?: string | null;
|
||||
personality?: PersonalityTraits | null;
|
||||
disposition?: DispositionTraits | null;
|
||||
/**
|
||||
* Background
|
||||
*/
|
||||
|
|
@ -207,6 +207,50 @@ export type DeleteResponse = {
|
|||
success: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* DispositionTraits
|
||||
*
|
||||
* Disposition traits based on Big Five model.
|
||||
*/
|
||||
export type DispositionTraits = {
|
||||
/**
|
||||
* Openness
|
||||
*
|
||||
* Openness to experience (0-1)
|
||||
*/
|
||||
openness: number;
|
||||
/**
|
||||
* Conscientiousness
|
||||
*
|
||||
* Conscientiousness (0-1)
|
||||
*/
|
||||
conscientiousness: number;
|
||||
/**
|
||||
* Extraversion
|
||||
*
|
||||
* Extraversion (0-1)
|
||||
*/
|
||||
extraversion: number;
|
||||
/**
|
||||
* Agreeableness
|
||||
*
|
||||
* Agreeableness (0-1)
|
||||
*/
|
||||
agreeableness: number;
|
||||
/**
|
||||
* Neuroticism
|
||||
*
|
||||
* Neuroticism (0-1)
|
||||
*/
|
||||
neuroticism: number;
|
||||
/**
|
||||
* Bias Strength
|
||||
*
|
||||
* How strongly disposition influences opinions (0-1)
|
||||
*/
|
||||
bias_strength: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* DocumentResponse
|
||||
*
|
||||
|
|
@ -552,50 +596,6 @@ export type MetadataFilter = {
|
|||
match_unset?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* PersonalityTraits
|
||||
*
|
||||
* Personality traits based on Big Five model.
|
||||
*/
|
||||
export type PersonalityTraits = {
|
||||
/**
|
||||
* Openness
|
||||
*
|
||||
* Openness to experience (0-1)
|
||||
*/
|
||||
openness: number;
|
||||
/**
|
||||
* Conscientiousness
|
||||
*
|
||||
* Conscientiousness (0-1)
|
||||
*/
|
||||
conscientiousness: number;
|
||||
/**
|
||||
* Extraversion
|
||||
*
|
||||
* Extraversion (0-1)
|
||||
*/
|
||||
extraversion: number;
|
||||
/**
|
||||
* Agreeableness
|
||||
*
|
||||
* Agreeableness (0-1)
|
||||
*/
|
||||
agreeableness: number;
|
||||
/**
|
||||
* Neuroticism
|
||||
*
|
||||
* Neuroticism (0-1)
|
||||
*/
|
||||
neuroticism: number;
|
||||
/**
|
||||
* Bias Strength
|
||||
*
|
||||
* How strongly personality influences opinions (0-1)
|
||||
*/
|
||||
bias_strength: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* RecallRequest
|
||||
*
|
||||
|
|
@ -859,12 +859,12 @@ export type RetainResponse = {
|
|||
};
|
||||
|
||||
/**
|
||||
* UpdatePersonalityRequest
|
||||
* UpdateDispositionRequest
|
||||
*
|
||||
* Request model for updating personality traits.
|
||||
* Request model for updating disposition traits.
|
||||
*/
|
||||
export type UpdatePersonalityRequest = {
|
||||
personality: PersonalityTraits;
|
||||
export type UpdateDispositionRequest = {
|
||||
disposition: DispositionTraits;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1433,8 +1433,8 @@ export type GetBankProfileResponses = {
|
|||
|
||||
export type GetBankProfileResponse = GetBankProfileResponses[keyof GetBankProfileResponses];
|
||||
|
||||
export type UpdateBankPersonalityData = {
|
||||
body: UpdatePersonalityRequest;
|
||||
export type UpdateBankDispositionData = {
|
||||
body: UpdateDispositionRequest;
|
||||
path: {
|
||||
/**
|
||||
* Bank Id
|
||||
|
|
@ -1445,23 +1445,23 @@ export type UpdateBankPersonalityData = {
|
|||
url: '/v1/default/banks/{bank_id}/profile';
|
||||
};
|
||||
|
||||
export type UpdateBankPersonalityErrors = {
|
||||
export type UpdateBankDispositionErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type UpdateBankPersonalityError = UpdateBankPersonalityErrors[keyof UpdateBankPersonalityErrors];
|
||||
export type UpdateBankDispositionError = UpdateBankDispositionErrors[keyof UpdateBankDispositionErrors];
|
||||
|
||||
export type UpdateBankPersonalityResponses = {
|
||||
export type UpdateBankDispositionResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: BankProfileResponse;
|
||||
};
|
||||
|
||||
export type UpdateBankPersonalityResponse = UpdateBankPersonalityResponses[keyof UpdateBankPersonalityResponses];
|
||||
export type UpdateBankDispositionResponse = UpdateBankDispositionResponses[keyof UpdateBankDispositionResponses];
|
||||
|
||||
export type AddBankBackgroundData = {
|
||||
body: AddBackgroundRequest;
|
||||
|
|
@ -1535,7 +1535,7 @@ export type ClearBankMemoriesData = {
|
|||
/**
|
||||
* Type
|
||||
*
|
||||
* Optional fact type filter (world, interactions, opinion)
|
||||
* Optional fact type filter (world, experience, opinion)
|
||||
*/
|
||||
type?: string | null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { BankProfileView } from '@/components/bank-profile-view';
|
|||
import { useBank } from '@/lib/bank-context';
|
||||
|
||||
type NavItem = 'recall' | 'reflect' | 'data' | 'documents' | 'entities' | 'profile';
|
||||
type DataSubTab = 'world' | 'interactions' | 'opinion';
|
||||
type DataSubTab = 'world' | 'experience' | 'opinion';
|
||||
|
||||
export default function BankPage() {
|
||||
const params = useParams();
|
||||
|
|
@ -54,7 +54,7 @@ export default function BankPage() {
|
|||
<div>
|
||||
<h1 className="text-3xl font-bold mb-2 text-foreground">Bank Profile</h1>
|
||||
<p className="text-muted-foreground mb-6">
|
||||
View and edit the memory bank profile, personality traits, and background information.
|
||||
View and edit the memory bank profile, disposition traits, and background information.
|
||||
</p>
|
||||
<BankProfileView />
|
||||
</div>
|
||||
|
|
@ -106,15 +106,15 @@ export default function BankPage() {
|
|||
)}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDataSubTabChange('interactions')}
|
||||
onClick={() => handleDataSubTabChange('experience')}
|
||||
className={`px-6 py-3 font-semibold text-sm transition-all relative ${
|
||||
subTab === 'interactions'
|
||||
subTab === 'experience'
|
||||
? 'text-primary'
|
||||
: 'text-muted-foreground hover:text-foreground'
|
||||
}`}
|
||||
>
|
||||
Interactions
|
||||
{subTab === 'interactions' && (
|
||||
Experience
|
||||
{subTab === 'experience' && (
|
||||
<div className="absolute bottom-0 left-0 right-0 h-0.5 bg-primary" />
|
||||
)}
|
||||
</button>
|
||||
|
|
@ -136,7 +136,7 @@ export default function BankPage() {
|
|||
|
||||
<div>
|
||||
{subTab === 'world' && <DataView key="world" factType="world" />}
|
||||
{subTab === 'interactions' && <DataView key="interactions" factType="interactions" />}
|
||||
{subTab === 'experience' && <DataView key="experience" factType="experience" />}
|
||||
{subTab === 'opinion' && <DataView key="opinion" factType="opinion" />}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@
|
|||
import { RefreshCw, Save, User, Brain, FileText, Clock, AlertCircle, CheckCircle, Database, Link2, FolderOpen, Activity } from 'lucide-react';
|
||||
import { RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, ResponsiveContainer, Tooltip } from 'recharts';
|
||||
|
||||
interface PersonalityTraits {
|
||||
interface DispositionTraits {
|
||||
openness: number;
|
||||
conscientiousness: number;
|
||||
extraversion: number;
|
||||
|
|
@ -23,7 +23,7 @@ interface PersonalityTraits {
|
|||
interface BankProfile {
|
||||
bank_id: string;
|
||||
name: string;
|
||||
personality: PersonalityTraits;
|
||||
disposition: DispositionTraits;
|
||||
background: string;
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ interface BankStats {
|
|||
total_documents: number;
|
||||
nodes_by_fact_type: {
|
||||
world?: number;
|
||||
interactions?: number;
|
||||
experience?: number;
|
||||
opinion?: number;
|
||||
};
|
||||
links_by_link_type: {
|
||||
|
|
@ -56,7 +56,7 @@ interface Operation {
|
|||
error_message?: string;
|
||||
}
|
||||
|
||||
const TRAIT_LABELS: Record<keyof PersonalityTraits, { label: string; shortLabel: string; description: string; lowLabel: string; highLabel: string }> = {
|
||||
const TRAIT_LABELS: Record<keyof DispositionTraits, { label: string; shortLabel: string; description: string; lowLabel: string; highLabel: string }> = {
|
||||
openness: {
|
||||
label: 'Openness',
|
||||
shortLabel: 'O',
|
||||
|
|
@ -95,19 +95,19 @@ const TRAIT_LABELS: Record<keyof PersonalityTraits, { label: string; shortLabel:
|
|||
bias_strength: {
|
||||
label: 'Influence',
|
||||
shortLabel: 'I',
|
||||
description: 'How strongly personality traits influence opinions and responses',
|
||||
description: 'How strongly disposition traits influence opinions and responses',
|
||||
lowLabel: 'Neutral',
|
||||
highLabel: 'Strong'
|
||||
}
|
||||
};
|
||||
|
||||
function PersonalityRadarChart({ personality, editMode, editPersonality, onEditChange }: {
|
||||
personality: PersonalityTraits;
|
||||
function DispositionRadarChart({ disposition, editMode, editDisposition, onEditChange }: {
|
||||
disposition: DispositionTraits;
|
||||
editMode: boolean;
|
||||
editPersonality: PersonalityTraits;
|
||||
onEditChange: (trait: keyof PersonalityTraits, value: number) => void;
|
||||
editDisposition: DispositionTraits;
|
||||
onEditChange: (trait: keyof DispositionTraits, value: number) => void;
|
||||
}) {
|
||||
const data = editMode ? editPersonality : personality;
|
||||
const data = editMode ? editDisposition : disposition;
|
||||
|
||||
const chartData = [
|
||||
{ trait: 'Openness', value: Math.round(data.openness * 100), fullMark: 100 },
|
||||
|
|
@ -134,7 +134,7 @@ function PersonalityRadarChart({ personality, editMode, editPersonality, onEditC
|
|||
tickCount={5}
|
||||
/>
|
||||
<Radar
|
||||
name="Personality"
|
||||
name="Disposition"
|
||||
dataKey="value"
|
||||
stroke="hsl(var(--primary))"
|
||||
fill="hsl(var(--primary))"
|
||||
|
|
@ -156,17 +156,17 @@ function PersonalityRadarChart({ personality, editMode, editPersonality, onEditC
|
|||
|
||||
{editMode && (
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{(Object.keys(TRAIT_LABELS) as Array<keyof PersonalityTraits>).filter(t => t !== 'bias_strength').map((trait) => (
|
||||
{(Object.keys(TRAIT_LABELS) as Array<keyof DispositionTraits>).filter(t => t !== 'bias_strength').map((trait) => (
|
||||
<div key={trait} className="space-y-1">
|
||||
<div className="flex justify-between items-center">
|
||||
<label className="text-xs font-medium text-muted-foreground">{TRAIT_LABELS[trait].label}</label>
|
||||
<span className="text-xs text-primary font-semibold">{Math.round(editPersonality[trait] * 100)}%</span>
|
||||
<span className="text-xs text-primary font-semibold">{Math.round(editDisposition[trait] * 100)}%</span>
|
||||
</div>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={Math.round(editPersonality[trait] * 100)}
|
||||
value={Math.round(editDisposition[trait] * 100)}
|
||||
onChange={(e) => onEditChange(trait, parseInt(e.target.value) / 100)}
|
||||
className="w-full h-1.5 bg-muted rounded-lg appearance-none cursor-pointer accent-primary"
|
||||
/>
|
||||
|
|
@ -179,7 +179,7 @@ function PersonalityRadarChart({ personality, editMode, editPersonality, onEditC
|
|||
<div className="pt-3 border-t border-border">
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div>
|
||||
<label className="text-sm font-medium text-foreground">Personality Influence</label>
|
||||
<label className="text-sm font-medium text-foreground">Disposition Influence</label>
|
||||
<p className="text-xs text-muted-foreground">How strongly traits affect responses</p>
|
||||
</div>
|
||||
<span className="text-sm font-bold text-primary">{Math.round(data.bias_strength * 100)}%</span>
|
||||
|
|
@ -189,7 +189,7 @@ function PersonalityRadarChart({ personality, editMode, editPersonality, onEditC
|
|||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={Math.round(editPersonality.bias_strength * 100)}
|
||||
value={Math.round(editDisposition.bias_strength * 100)}
|
||||
onChange={(e) => onEditChange('bias_strength', parseInt(e.target.value) / 100)}
|
||||
className="w-full h-2 bg-muted rounded-lg appearance-none cursor-pointer accent-primary"
|
||||
/>
|
||||
|
|
@ -211,7 +211,7 @@ export function BankProfileView() {
|
|||
// Edit state
|
||||
const [editName, setEditName] = useState('');
|
||||
const [editBackground, setEditBackground] = useState('');
|
||||
const [editPersonality, setEditPersonality] = useState<PersonalityTraits>({
|
||||
const [editDisposition, setEditDisposition] = useState<DispositionTraits>({
|
||||
openness: 0.5,
|
||||
conscientiousness: 0.5,
|
||||
extraversion: 0.5,
|
||||
|
|
@ -237,7 +237,7 @@ export function BankProfileView() {
|
|||
// Initialize edit state
|
||||
setEditName(profileData.name);
|
||||
setEditBackground(profileData.background);
|
||||
setEditPersonality(profileData.personality);
|
||||
setEditDisposition(profileData.disposition);
|
||||
} catch (error) {
|
||||
console.error('Error loading bank profile:', error);
|
||||
alert('Error loading bank profile: ' + (error as Error).message);
|
||||
|
|
@ -254,7 +254,7 @@ export function BankProfileView() {
|
|||
await client.updateBankProfile(currentBank, {
|
||||
name: editName,
|
||||
background: editBackground,
|
||||
personality: editPersonality
|
||||
disposition: editDisposition
|
||||
});
|
||||
await loadData();
|
||||
setEditMode(false);
|
||||
|
|
@ -270,7 +270,7 @@ export function BankProfileView() {
|
|||
if (profile) {
|
||||
setEditName(profile.name);
|
||||
setEditBackground(profile.background);
|
||||
setEditPersonality(profile.personality);
|
||||
setEditDisposition(profile.disposition);
|
||||
}
|
||||
setEditMode(false);
|
||||
};
|
||||
|
|
@ -417,8 +417,8 @@ export function BankProfileView() {
|
|||
<p className="text-2xl font-bold text-blue-600 dark:text-blue-400 mt-1">{stats.nodes_by_fact_type?.world || 0}</p>
|
||||
</div>
|
||||
<div className="bg-purple-500/10 border border-purple-500/20 rounded-xl p-4 text-center">
|
||||
<p className="text-xs text-purple-600 dark:text-purple-400 font-semibold uppercase tracking-wide">Interactions</p>
|
||||
<p className="text-2xl font-bold text-purple-600 dark:text-purple-400 mt-1">{stats.nodes_by_fact_type?.interactions || 0}</p>
|
||||
<p className="text-xs text-purple-600 dark:text-purple-400 font-semibold uppercase tracking-wide">Experience</p>
|
||||
<p className="text-2xl font-bold text-purple-600 dark:text-purple-400 mt-1">{stats.nodes_by_fact_type?.experience || 0}</p>
|
||||
</div>
|
||||
<div className="bg-amber-500/10 border border-amber-500/20 rounded-xl p-4 text-center">
|
||||
<p className="text-xs text-amber-600 dark:text-amber-400 font-semibold uppercase tracking-wide">Opinions</p>
|
||||
|
|
@ -428,22 +428,22 @@ export function BankProfileView() {
|
|||
)}
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* Personality Chart */}
|
||||
{/* Disposition Chart */}
|
||||
<Card>
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="flex items-center gap-2 text-lg">
|
||||
<Brain className="w-5 h-5 text-primary" />
|
||||
Personality Profile
|
||||
Disposition Profile
|
||||
</CardTitle>
|
||||
<CardDescription>Big Five personality traits that influence responses</CardDescription>
|
||||
<CardDescription>Big Five disposition traits that influence responses</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{profile && (
|
||||
<PersonalityRadarChart
|
||||
personality={profile.personality}
|
||||
<DispositionRadarChart
|
||||
disposition={profile.disposition}
|
||||
editMode={editMode}
|
||||
editPersonality={editPersonality}
|
||||
onEditChange={(trait, value) => setEditPersonality(prev => ({ ...prev, [trait]: value }))}
|
||||
editDisposition={editDisposition}
|
||||
onEditChange={(trait, value) => setEditDisposition(prev => ({ ...prev, [trait]: value }))}
|
||||
/>
|
||||
)}
|
||||
</CardContent>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { Copy, Check, Calendar, ZoomIn, ZoomOut, ChevronLeft, ChevronRight, Chev
|
|||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import { MemoryDetailPanel } from './memory-detail-panel';
|
||||
|
||||
type FactType = 'world' | 'interactions' | 'opinion';
|
||||
type FactType = 'world' | 'experience' | 'opinion';
|
||||
type ViewMode = 'graph' | 'table' | 'timeline';
|
||||
|
||||
interface DataViewProps {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import { MemoryDetailPanel } from './memory-detail-panel';
|
|||
|
||||
type Phase = 'retrieval' | 'rrf' | 'rerank' | 'final' | 'json';
|
||||
type RetrievalMethod = 'semantic' | 'bm25' | 'graph' | 'temporal';
|
||||
type FactType = 'world' | 'interactions' | 'opinion';
|
||||
type FactType = 'world' | 'experience' | 'opinion';
|
||||
|
||||
type Budget = 'low' | 'mid' | 'high';
|
||||
|
||||
|
|
@ -227,7 +227,7 @@ export function SearchDebugView() {
|
|||
<TableHead><ColumnHeader label="Rank" tooltip="Position in this retrieval method's results" /></TableHead>
|
||||
<TableHead><ColumnHeader label="Text" tooltip="The memory content" /></TableHead>
|
||||
{pane.factTypes.length > 1 && (
|
||||
<TableHead><ColumnHeader label="Type" tooltip="Fact type (world, bank, opinion)" /></TableHead>
|
||||
<TableHead><ColumnHeader label="Type" tooltip="Fact type (world, experience, opinion)" /></TableHead>
|
||||
)}
|
||||
<TableHead><ColumnHeader label="Score" tooltip={scoreTooltip} /></TableHead>
|
||||
</TableRow>
|
||||
|
|
@ -564,7 +564,7 @@ export function SearchDebugView() {
|
|||
<div>
|
||||
<label className="block text-sm font-bold mb-2 text-accent-foreground">Fact Types:</label>
|
||||
<div className="flex flex-col gap-2">
|
||||
{(['world', 'interactions', 'opinion'] as FactType[]).map((ft) => (
|
||||
{(['world', 'experience', 'opinion'] as FactType[]).map((ft) => (
|
||||
<div key={ft} className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id={`${pane.id}-${ft}`}
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ export function ThinkView() {
|
|||
(() => {
|
||||
// Group facts by type
|
||||
const worldFacts = result.based_on.filter((f: any) => f.type === 'world');
|
||||
const interactionsFacts = result.based_on.filter((f: any) => f.type === 'interactions');
|
||||
const experienceFacts = result.based_on.filter((f: any) => f.type === 'experience');
|
||||
const opinionFacts = result.based_on.filter((f: any) => f.type === 'opinion');
|
||||
|
||||
return (
|
||||
|
|
@ -184,13 +184,13 @@ export function ThinkView() {
|
|||
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base">Interactions</CardTitle>
|
||||
<CardTitle className="text-base">Experience</CardTitle>
|
||||
<CardDescription className="text-xs">Conversations & Events</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{interactionsFacts.length > 0 ? (
|
||||
{experienceFacts.length > 0 ? (
|
||||
<ul className="text-sm space-y-2">
|
||||
{interactionsFacts.map((fact: any, i: number) => (
|
||||
{experienceFacts.map((fact: any, i: number) => (
|
||||
<li key={i} className="p-2 bg-muted rounded">
|
||||
{fact.text}
|
||||
{fact.context && <div className="text-xs text-muted-foreground mt-1">{fact.context}</div>}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ export class ControlPlaneClient {
|
|||
return this.fetchApi<{
|
||||
bank_id: string;
|
||||
name: string;
|
||||
personality: {
|
||||
disposition: {
|
||||
openness: number;
|
||||
conscientiousness: number;
|
||||
extraversion: number;
|
||||
|
|
@ -196,7 +196,7 @@ export class ControlPlaneClient {
|
|||
*/
|
||||
async updateBankProfile(bankId: string, profile: {
|
||||
name?: string;
|
||||
personality?: {
|
||||
disposition?: {
|
||||
openness: number;
|
||||
conscientiousness: number;
|
||||
extraversion: number;
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@ Make sure you've completed the [Quick Start](./quickstart) to install the client
|
|||
|
||||
## What Are Opinions?
|
||||
|
||||
Opinions are beliefs formed by the memory bank based on evidence and personality. Unlike world facts (objective information received) or interactions (conversations and events), opinions are **judgments** with confidence scores.
|
||||
Opinions are beliefs formed by the memory bank based on evidence and personality. Unlike world facts (objective information received) or experience (conversations and events), opinions are **judgments** with confidence scores.
|
||||
|
||||
| Type | Example | Confidence |
|
||||
|------|---------|------------|
|
||||
| World Fact | "Python was created in 1991" | — |
|
||||
| Interactions | "I recommended Python to Bob" | — |
|
||||
| Experience | "I recommended Python to Bob" | — |
|
||||
| Opinion | "Python is the best language for data science" | 0.85 |
|
||||
|
||||
## How Opinions Form
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ hindsight memory search my-bank "What does Alice do?"
|
|||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `query` | string | required | Natural language query |
|
||||
| `types` | list | all | Filter: `world`, `interactions`, `opinion` |
|
||||
| `types` | list | all | Filter: `world`, `experience`, `opinion` |
|
||||
| `budget` | string | "mid" | Budget level: "low", "mid", "high" |
|
||||
| `max_tokens` | int | 4096 | Token budget for results |
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ hindsight memory search my-bank "What does Alice do?"
|
|||
results = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="What does Alice do?",
|
||||
types=["world", "interactions"],
|
||||
types=["world", "experience"],
|
||||
budget="high",
|
||||
max_tokens=8000
|
||||
)
|
||||
|
|
@ -94,7 +94,7 @@ For more control, use the full-featured recall method:
|
|||
response = client.recall_memories(
|
||||
bank_id="my-bank",
|
||||
query="What does Alice do?",
|
||||
types=["world", "interactions"],
|
||||
types=["world", "experience"],
|
||||
budget="high",
|
||||
max_tokens=8000,
|
||||
trace=True,
|
||||
|
|
@ -119,7 +119,7 @@ if "entities" in response:
|
|||
// Full response with trace info
|
||||
const response = await client.recallMemories('my-bank', {
|
||||
query: 'What does Alice do?',
|
||||
types: ['world', 'interactions'],
|
||||
types: ['world', 'experience'],
|
||||
budget: 'high',
|
||||
maxTokens: 8000,
|
||||
trace: true
|
||||
|
|
@ -184,11 +184,11 @@ world_facts = client.recall(
|
|||
types=["world"]
|
||||
)
|
||||
|
||||
# Only interactions (conversations and events)
|
||||
interactions = client.recall(
|
||||
# Only experience (conversations and events)
|
||||
experience = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="What have I recommended?",
|
||||
types=["interactions"]
|
||||
types=["experience"]
|
||||
)
|
||||
|
||||
# Only opinions (formed beliefs)
|
||||
|
|
@ -198,11 +198,11 @@ opinions = client.recall(
|
|||
types=["opinion"]
|
||||
)
|
||||
|
||||
# World facts and interactions (exclude opinions)
|
||||
# World facts and experience (exclude opinions)
|
||||
facts = client.recall(
|
||||
bank_id="my-bank",
|
||||
query="What happened?",
|
||||
types=["world", "interactions"]
|
||||
types=["world", "experience"]
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ facts = client.recall(
|
|||
|
||||
```bash
|
||||
hindsight memory search my-bank "Python" --fact-type opinion
|
||||
hindsight memory search my-bank "Alice" --fact-type world,interactions
|
||||
hindsight memory search my-bank "Alice" --fact-type world,experience
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Reflect: How Hindsight Reasons with Personality
|
||||
# Reflect: How Hindsight Reasons with Disposition
|
||||
|
||||
When you call `reflect()`, Hindsight doesn't just retrieve facts — it **reasons** about them through the lens of the bank's unique personality, forming new opinions and generating contextual responses.
|
||||
When you call `reflect()`, Hindsight doesn't just retrieve facts — it **reasons** about them through the lens of the bank's unique disposition, forming new opinions and generating contextual responses.
|
||||
|
||||
## Why Reflect?
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ Without reflect:
|
|||
- **No consistent character**: "Should we adopt remote work?" gets a different answer each time based on the LLM's randomness
|
||||
- **No opinion formation**: The system never develops beliefs based on accumulated evidence
|
||||
- **No reasoning context**: Responses don't reflect what the bank has learned or its perspective
|
||||
- **Generic responses**: Every AI sounds the same — no personality, no point of view
|
||||
- **Generic responses**: Every AI sounds the same — no disposition, no point of view
|
||||
|
||||
### The Value
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ With reflect:
|
|||
| Use `recall()` when... | Use `reflect()` when... |
|
||||
|------------------------|-------------------------|
|
||||
| You need raw facts | You need reasoned interpretation |
|
||||
| You're building your own reasoning | You want personality-consistent responses |
|
||||
| You're building your own reasoning | You want disposition-consistent responses |
|
||||
| You need maximum control | You want the bank to "think" for itself |
|
||||
| Simple fact lookup | Forming recommendations or opinions |
|
||||
|
||||
|
|
@ -44,16 +44,16 @@ With reflect:
|
|||
## The Reflect Process
|
||||
|
||||
1. **Recall** relevant memories based on the query
|
||||
2. **Load** the bank's personality traits and background
|
||||
3. **Reason** about the memories through the personality lens
|
||||
2. **Load** the bank's disposition traits and background
|
||||
3. **Reason** about the memories through the disposition lens
|
||||
4. **Form** new opinions with confidence scores
|
||||
5. **Return** response, sources, and any new beliefs
|
||||
|
||||
---
|
||||
|
||||
## Personality Framework (CARA)
|
||||
## Disposition Framework (CARA)
|
||||
|
||||
When you create a memory bank, you can configure its personality using **Big Five traits**. These traits influence how the bank interprets information and forms opinions:
|
||||
When you create a memory bank, you can configure its disposition using **Big Five traits**. These traits influence how the bank interprets information and forms opinions:
|
||||
|
||||
You can also provide a natural language **background** that describes the bank's identity and perspective, which shapes how these traits are applied.
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ client.create_bank(
|
|||
bank_id="my-bank",
|
||||
background="I am a senior software architect with 15 years of distributed "
|
||||
"systems experience. I prefer simplicity over cutting-edge technology.",
|
||||
personality={
|
||||
disposition={
|
||||
"openness": 0.3, # Prefers proven methods
|
||||
"conscientiousness": 0.9, # Highly organized
|
||||
# ... other traits
|
||||
|
|
@ -82,28 +82,28 @@ client.create_bank(
|
|||
)
|
||||
```
|
||||
|
||||
The background provides context that shapes how personality traits are applied:
|
||||
The background provides context that shapes how disposition traits are applied:
|
||||
- "I prefer simplicity" + low openness → consistently favors established solutions
|
||||
- "15 years experience" → responses reference this expertise
|
||||
- First-person perspective → creates consistent voice
|
||||
|
||||
### Bias Strength
|
||||
|
||||
The `bias_strength` parameter (0-1) controls how much personality influences reasoning:
|
||||
The `bias_strength` parameter (0-1) controls how much disposition influences reasoning:
|
||||
|
||||
- **0.0**: Purely evidence-based
|
||||
- **0.5**: Balanced personality and evidence
|
||||
- **1.0**: Strongly personality-driven
|
||||
- **0.5**: Balanced disposition and evidence
|
||||
- **1.0**: Strongly disposition-driven
|
||||
|
||||
---
|
||||
|
||||
## Opinion Formation
|
||||
|
||||
When `reflect()` encounters a question that warrants forming an opinion, personality shapes the response.
|
||||
When `reflect()` encounters a question that warrants forming an opinion, disposition shapes the response.
|
||||
|
||||
### Same Facts, Different Opinions
|
||||
|
||||
Two banks with different personalities, given identical facts about remote work:
|
||||
Two banks with different dispositions, given identical facts about remote work:
|
||||
|
||||
**Bank A** (high openness, low conscientiousness):
|
||||
> "Remote work unlocks creative flexibility and spontaneous innovation. The freedom to work from anywhere enables breakthrough thinking."
|
||||
|
|
@ -111,7 +111,7 @@ Two banks with different personalities, given identical facts about remote work:
|
|||
**Bank B** (low openness, high conscientiousness):
|
||||
> "Remote work lacks the structure and accountability needed for consistent performance. In-person collaboration is more reliable."
|
||||
|
||||
**Same facts → Different conclusions** because personality shapes interpretation.
|
||||
**Same facts → Different conclusions** because disposition shapes interpretation.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -138,9 +138,9 @@ This **continuous learning** ensures recommendations stay current with real-worl
|
|||
|
||||
---
|
||||
|
||||
## Personality Presets by Use Case
|
||||
## Disposition Presets by Use Case
|
||||
|
||||
Different use cases benefit from different personality configurations:
|
||||
Different use cases benefit from different disposition configurations:
|
||||
|
||||
| Use Case | Recommended Traits | Why |
|
||||
|----------|-------------------|-----|
|
||||
|
|
@ -157,7 +157,7 @@ Different use cases benefit from different personality configurations:
|
|||
When you call `reflect()`:
|
||||
|
||||
**Returns:**
|
||||
- **Response text** — Personality-influenced answer
|
||||
- **Response text** — Disposition-influenced answer
|
||||
- **Based on** — Which memories were used (with relevance scores)
|
||||
|
||||
**Example:**
|
||||
|
|
@ -177,16 +177,16 @@ When you call `reflect()`:
|
|||
|
||||
---
|
||||
|
||||
## Why Personality Matters
|
||||
## Why Disposition Matters
|
||||
|
||||
Without personality, all AI assistants sound the same. With personality:
|
||||
Without disposition, all AI assistants sound the same. With disposition:
|
||||
|
||||
- **Customer support bots** can be diplomatic and empathetic
|
||||
- **Code review assistants** can be direct and thorough
|
||||
- **Creative assistants** can be open to unconventional ideas
|
||||
- **Risk analysts** can be appropriately cautious
|
||||
|
||||
Personality creates **consistent character** across conversations while allowing opinions to **evolve with evidence**.
|
||||
Disposition creates **consistent character** across conversations while allowing opinions to **evolve with evidence**.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -59,12 +59,12 @@ This means search results include the full context, not disconnected fragments.
|
|||
|
||||
## Two Types of Facts
|
||||
|
||||
Hindsight distinguishes between **world** facts (about others) and **interactions** (conversations and events):
|
||||
Hindsight distinguishes between **world** facts (about others) and **experience** (conversations and events):
|
||||
|
||||
| Type | Description | Example |
|
||||
|-----------------|-----------------------------------|---------|
|
||||
| **world** | Facts about people, places, things | "Alice works at Google" |
|
||||
| **interactions** | Conversations and events | "I recommended Python to Alice" |
|
||||
| **experience** | Conversations and events | "I recommended Python to Alice" |
|
||||
|
||||
This separation is important for `reflect()` — the bank can reason about what it knows versus what happened in conversations.
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ Hindsight is built for AI agents, not humans. Traditional search systems return
|
|||
**Parameters you control:**
|
||||
- `max_tokens`: How much memory content to return (default: 4096 tokens)
|
||||
- `budget`: Budget level for graph traversal (low, mid, high)
|
||||
- `fact_type`: Filter by world, interactions, opinion, or all
|
||||
- `fact_type`: Filter by world, experience, opinion, or all
|
||||
|
||||
### Additional Context: Chunks and Entity Observations
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ results = client.recall(
|
|||
response = client.recall_memories(
|
||||
bank_id="my-agent",
|
||||
query="What does Alice do?",
|
||||
types=["world", "interactions"],
|
||||
types=["world", "experience"],
|
||||
budget="mid",
|
||||
max_tokens=4096,
|
||||
trace=True,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const sidebars: SidebarsConfig = {
|
|||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'developer/personality',
|
||||
id: 'developer/reflect',
|
||||
label: 'Reflect',
|
||||
},
|
||||
{
|
||||
|
|
|
|||
218
openapi.json
218
openapi.json
|
|
@ -56,7 +56,7 @@
|
|||
"/v1/default/banks/{bank_id}/graph": {
|
||||
"get": {
|
||||
"summary": "Get memory graph data",
|
||||
"description": "Retrieve graph data for visualization, optionally filtered by type (world/interactions/opinion). Limited to 1000 most recent items.",
|
||||
"description": "Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.",
|
||||
"operationId": "get_graph",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -204,7 +204,7 @@
|
|||
"/v1/default/banks/{bank_id}/memories/recall": {
|
||||
"post": {
|
||||
"summary": "Recall memory",
|
||||
"description": "Recall memory using semantic similarity and spreading activation.\n\n The type parameter is optional and must be one of:\n - 'world': General knowledge about people, places, events, and things that happen\n - 'interactions': Memories about interactions, conversations, actions taken, and tasks performed\n - 'opinion': The bank's formed beliefs, perspectives, and viewpoints\n\n Set include_entities=true to get entity observations alongside recall results.",
|
||||
"description": "Recall memory using semantic similarity and spreading activation.\n\n The type parameter is optional and must be one of:\n - 'world': General knowledge about people, places, events, and things that happen\n - 'experience': Memories about experience, conversations, actions taken, and tasks performed\n - 'opinion': The bank's formed beliefs, perspectives, and viewpoints\n\n Set include_entities=true to get entity observations alongside recall results.",
|
||||
"operationId": "recall_memories",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -254,7 +254,7 @@
|
|||
"/v1/default/banks/{bank_id}/reflect": {
|
||||
"post": {
|
||||
"summary": "Reflect and generate answer",
|
||||
"description": "Reflect and formulate an answer using bank identity, world facts, and opinions.\n\n This endpoint:\n 1. Retrieves interactions (conversations and events)\n 2. Retrieves world facts relevant to the query\n 3. Retrieves existing opinions (bank's perspectives)\n 4. Uses LLM to formulate a contextual answer\n 5. Extracts and stores any new opinions formed\n 6. Returns plain text answer, the facts used, and new opinions",
|
||||
"description": "Reflect and formulate an answer using bank identity, world facts, and opinions.\n\n This endpoint:\n 1. Retrieves experience (conversations and events)\n 2. Retrieves world facts relevant to the query\n 3. Retrieves existing opinions (bank's perspectives)\n 4. Uses LLM to formulate a contextual answer\n 5. Extracts and stores any new opinions formed\n 6. Returns plain text answer, the facts used, and new opinions",
|
||||
"operationId": "reflect",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -806,7 +806,7 @@
|
|||
"/v1/default/banks/{bank_id}/profile": {
|
||||
"get": {
|
||||
"summary": "Get memory bank profile",
|
||||
"description": "Get personality traits and background for a memory bank. Auto-creates agent with defaults if not exists.",
|
||||
"description": "Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.",
|
||||
"operationId": "get_bank_profile",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -843,9 +843,9 @@
|
|||
}
|
||||
},
|
||||
"put": {
|
||||
"summary": "Update memory bank personality",
|
||||
"description": "Update bank's Big Five personality traits and bias strength",
|
||||
"operationId": "update_bank_personality",
|
||||
"summary": "Update memory bank disposition",
|
||||
"description": "Update bank's Big Five disposition traits and bias strength",
|
||||
"operationId": "update_bank_disposition",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "bank_id",
|
||||
|
|
@ -862,7 +862,7 @@
|
|||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UpdatePersonalityRequest"
|
||||
"$ref": "#/components/schemas/UpdateDispositionRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -894,7 +894,7 @@
|
|||
"/v1/default/banks/{bank_id}/background": {
|
||||
"post": {
|
||||
"summary": "Add/merge memory bank background",
|
||||
"description": "Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.",
|
||||
"description": "Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.",
|
||||
"operationId": "add_bank_background",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -944,7 +944,7 @@
|
|||
"/v1/default/banks/{bank_id}": {
|
||||
"put": {
|
||||
"summary": "Create or update memory bank",
|
||||
"description": "Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.",
|
||||
"description": "Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.",
|
||||
"operationId": "create_or_update_bank",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1042,7 +1042,7 @@
|
|||
},
|
||||
"delete": {
|
||||
"summary": "Clear memory bank memories",
|
||||
"description": "Delete memory units for a memory bank. Optionally filter by type (world, interactions, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.",
|
||||
"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.",
|
||||
"operationId": "clear_bank_memories",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1067,10 +1067,10 @@
|
|||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional fact type filter (world, interactions, opinion)",
|
||||
"description": "Optional fact type filter (world, experience, opinion)",
|
||||
"title": "Type"
|
||||
},
|
||||
"description": "Optional fact type filter (world, interactions, opinion)"
|
||||
"description": "Optional fact type filter (world, experience, opinion)"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
|
@ -1107,10 +1107,10 @@
|
|||
"title": "Content",
|
||||
"description": "New background information to add or merge"
|
||||
},
|
||||
"update_personality": {
|
||||
"update_disposition": {
|
||||
"type": "boolean",
|
||||
"title": "Update Personality",
|
||||
"description": "If true, infer Big Five personality traits from the merged background (default: true)",
|
||||
"title": "Update Disposition",
|
||||
"description": "If true, infer Big Five disposition traits from the merged background (default: true)",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
|
|
@ -1122,7 +1122,7 @@
|
|||
"description": "Request model for adding/merging background information.",
|
||||
"example": {
|
||||
"content": "I was born in Texas",
|
||||
"update_personality": true
|
||||
"update_disposition": true
|
||||
}
|
||||
},
|
||||
"BackgroundResponse": {
|
||||
|
|
@ -1131,10 +1131,10 @@
|
|||
"type": "string",
|
||||
"title": "Background"
|
||||
},
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PersonalityTraits"
|
||||
"$ref": "#/components/schemas/DispositionTraits"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
|
|
@ -1150,7 +1150,7 @@
|
|||
"description": "Response model for background update.",
|
||||
"example": {
|
||||
"background": "I was born in Texas. I am a software engineer with 10 years of experience.",
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"agreeableness": 0.8,
|
||||
"bias_strength": 0.6,
|
||||
"conscientiousness": 0.6,
|
||||
|
|
@ -1170,8 +1170,8 @@
|
|||
"type": "string",
|
||||
"title": "Name"
|
||||
},
|
||||
"personality": {
|
||||
"$ref": "#/components/schemas/PersonalityTraits"
|
||||
"disposition": {
|
||||
"$ref": "#/components/schemas/DispositionTraits"
|
||||
},
|
||||
"background": {
|
||||
"type": "string",
|
||||
|
|
@ -1204,7 +1204,7 @@
|
|||
"required": [
|
||||
"bank_id",
|
||||
"name",
|
||||
"personality",
|
||||
"disposition",
|
||||
"background"
|
||||
],
|
||||
"title": "BankListItem",
|
||||
|
|
@ -1232,8 +1232,7 @@
|
|||
"background": "I am a software engineer",
|
||||
"bank_id": "user123",
|
||||
"created_at": "2024-01-15T10:30:00Z",
|
||||
"name": "Alice",
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"agreeableness": 0.5,
|
||||
"bias_strength": 0.5,
|
||||
"conscientiousness": 0.5,
|
||||
|
|
@ -1241,6 +1240,7 @@
|
|||
"neuroticism": 0.5,
|
||||
"openness": 0.5
|
||||
},
|
||||
"name": "Alice",
|
||||
"updated_at": "2024-01-16T14:20:00Z"
|
||||
}
|
||||
]
|
||||
|
|
@ -1256,8 +1256,8 @@
|
|||
"type": "string",
|
||||
"title": "Name"
|
||||
},
|
||||
"personality": {
|
||||
"$ref": "#/components/schemas/PersonalityTraits"
|
||||
"disposition": {
|
||||
"$ref": "#/components/schemas/DispositionTraits"
|
||||
},
|
||||
"background": {
|
||||
"type": "string",
|
||||
|
|
@ -1268,7 +1268,7 @@
|
|||
"required": [
|
||||
"bank_id",
|
||||
"name",
|
||||
"personality",
|
||||
"disposition",
|
||||
"background"
|
||||
],
|
||||
"title": "BankProfileResponse",
|
||||
|
|
@ -1276,15 +1276,15 @@
|
|||
"example": {
|
||||
"background": "I am a software engineer with 10 years of experience in startups",
|
||||
"bank_id": "user123",
|
||||
"name": "Alice",
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"agreeableness": 0.7,
|
||||
"bias_strength": 0.7,
|
||||
"conscientiousness": 0.6,
|
||||
"extraversion": 0.5,
|
||||
"neuroticism": 0.3,
|
||||
"openness": 0.8
|
||||
}
|
||||
},
|
||||
"name": "Alice"
|
||||
}
|
||||
},
|
||||
"Budget": {
|
||||
|
|
@ -1400,10 +1400,10 @@
|
|||
],
|
||||
"title": "Name"
|
||||
},
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PersonalityTraits"
|
||||
"$ref": "#/components/schemas/DispositionTraits"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
|
|
@ -1427,15 +1427,15 @@
|
|||
"description": "Request model for creating/updating a bank.",
|
||||
"example": {
|
||||
"background": "I am a creative software engineer with 10 years of experience",
|
||||
"name": "Alice",
|
||||
"personality": {
|
||||
"disposition": {
|
||||
"agreeableness": 0.7,
|
||||
"bias_strength": 0.7,
|
||||
"conscientiousness": 0.6,
|
||||
"extraversion": 0.5,
|
||||
"neuroticism": 0.3,
|
||||
"openness": 0.8
|
||||
}
|
||||
},
|
||||
"name": "Alice"
|
||||
}
|
||||
},
|
||||
"DeleteResponse": {
|
||||
|
|
@ -1455,6 +1455,71 @@
|
|||
"success": true
|
||||
}
|
||||
},
|
||||
"DispositionTraits": {
|
||||
"properties": {
|
||||
"openness": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Openness",
|
||||
"description": "Openness to experience (0-1)"
|
||||
},
|
||||
"conscientiousness": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Conscientiousness",
|
||||
"description": "Conscientiousness (0-1)"
|
||||
},
|
||||
"extraversion": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Extraversion",
|
||||
"description": "Extraversion (0-1)"
|
||||
},
|
||||
"agreeableness": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Agreeableness",
|
||||
"description": "Agreeableness (0-1)"
|
||||
},
|
||||
"neuroticism": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Neuroticism",
|
||||
"description": "Neuroticism (0-1)"
|
||||
},
|
||||
"bias_strength": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Bias Strength",
|
||||
"description": "How strongly disposition influences opinions (0-1)"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"openness",
|
||||
"conscientiousness",
|
||||
"extraversion",
|
||||
"agreeableness",
|
||||
"neuroticism",
|
||||
"bias_strength"
|
||||
],
|
||||
"title": "DispositionTraits",
|
||||
"description": "Disposition traits based on Big Five model.",
|
||||
"example": {
|
||||
"agreeableness": 0.7,
|
||||
"bias_strength": 0.7,
|
||||
"conscientiousness": 0.6,
|
||||
"extraversion": 0.5,
|
||||
"neuroticism": 0.3,
|
||||
"openness": 0.8
|
||||
}
|
||||
},
|
||||
"DocumentResponse": {
|
||||
"properties": {
|
||||
"id": {
|
||||
|
|
@ -2084,71 +2149,6 @@
|
|||
"value": "slack"
|
||||
}
|
||||
},
|
||||
"PersonalityTraits": {
|
||||
"properties": {
|
||||
"openness": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Openness",
|
||||
"description": "Openness to experience (0-1)"
|
||||
},
|
||||
"conscientiousness": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Conscientiousness",
|
||||
"description": "Conscientiousness (0-1)"
|
||||
},
|
||||
"extraversion": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Extraversion",
|
||||
"description": "Extraversion (0-1)"
|
||||
},
|
||||
"agreeableness": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Agreeableness",
|
||||
"description": "Agreeableness (0-1)"
|
||||
},
|
||||
"neuroticism": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Neuroticism",
|
||||
"description": "Neuroticism (0-1)"
|
||||
},
|
||||
"bias_strength": {
|
||||
"type": "number",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0,
|
||||
"title": "Bias Strength",
|
||||
"description": "How strongly personality influences opinions (0-1)"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"openness",
|
||||
"conscientiousness",
|
||||
"extraversion",
|
||||
"agreeableness",
|
||||
"neuroticism",
|
||||
"bias_strength"
|
||||
],
|
||||
"title": "PersonalityTraits",
|
||||
"description": "Personality traits based on Big Five model.",
|
||||
"example": {
|
||||
"agreeableness": 0.7,
|
||||
"bias_strength": 0.7,
|
||||
"conscientiousness": 0.6,
|
||||
"extraversion": 0.5,
|
||||
"neuroticism": 0.3,
|
||||
"openness": 0.8
|
||||
}
|
||||
},
|
||||
"RecallRequest": {
|
||||
"properties": {
|
||||
"query": {
|
||||
|
|
@ -2242,7 +2242,7 @@
|
|||
"trace": true,
|
||||
"types": [
|
||||
"world",
|
||||
"interactions"
|
||||
"experience"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
@ -2677,7 +2677,7 @@
|
|||
{
|
||||
"id": "456",
|
||||
"text": "I discussed AI applications last week",
|
||||
"type": "interactions"
|
||||
"type": "experience"
|
||||
}
|
||||
],
|
||||
"text": "Based on my understanding, AI is a transformative technology..."
|
||||
|
|
@ -2757,18 +2757,18 @@
|
|||
"success": true
|
||||
}
|
||||
},
|
||||
"UpdatePersonalityRequest": {
|
||||
"UpdateDispositionRequest": {
|
||||
"properties": {
|
||||
"personality": {
|
||||
"$ref": "#/components/schemas/PersonalityTraits"
|
||||
"disposition": {
|
||||
"$ref": "#/components/schemas/DispositionTraits"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"personality"
|
||||
"disposition"
|
||||
],
|
||||
"title": "UpdatePersonalityRequest",
|
||||
"description": "Request model for updating personality traits."
|
||||
"title": "UpdateDispositionRequest",
|
||||
"description": "Request model for updating disposition traits."
|
||||
},
|
||||
"ValidationError": {
|
||||
"properties": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue