jl-ecms-client 0.2.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jl-ecms-client might be problematic. Click here for more details.

Files changed (53) hide show
  1. jl_ecms_client-0.2.8.dist-info/METADATA +295 -0
  2. jl_ecms_client-0.2.8.dist-info/RECORD +53 -0
  3. jl_ecms_client-0.2.8.dist-info/WHEEL +5 -0
  4. jl_ecms_client-0.2.8.dist-info/licenses/LICENSE +190 -0
  5. jl_ecms_client-0.2.8.dist-info/top_level.txt +1 -0
  6. mirix/client/__init__.py +14 -0
  7. mirix/client/client.py +405 -0
  8. mirix/client/constants.py +60 -0
  9. mirix/client/remote_client.py +1136 -0
  10. mirix/client/utils.py +34 -0
  11. mirix/helpers/__init__.py +1 -0
  12. mirix/helpers/converters.py +429 -0
  13. mirix/helpers/datetime_helpers.py +90 -0
  14. mirix/helpers/json_helpers.py +47 -0
  15. mirix/helpers/message_helpers.py +74 -0
  16. mirix/helpers/tool_rule_solver.py +166 -0
  17. mirix/schemas/__init__.py +1 -0
  18. mirix/schemas/agent.py +401 -0
  19. mirix/schemas/block.py +188 -0
  20. mirix/schemas/cloud_file_mapping.py +29 -0
  21. mirix/schemas/embedding_config.py +114 -0
  22. mirix/schemas/enums.py +69 -0
  23. mirix/schemas/environment_variables.py +82 -0
  24. mirix/schemas/episodic_memory.py +170 -0
  25. mirix/schemas/file.py +57 -0
  26. mirix/schemas/health.py +10 -0
  27. mirix/schemas/knowledge_vault.py +181 -0
  28. mirix/schemas/llm_config.py +187 -0
  29. mirix/schemas/memory.py +318 -0
  30. mirix/schemas/message.py +1315 -0
  31. mirix/schemas/mirix_base.py +107 -0
  32. mirix/schemas/mirix_message.py +411 -0
  33. mirix/schemas/mirix_message_content.py +230 -0
  34. mirix/schemas/mirix_request.py +39 -0
  35. mirix/schemas/mirix_response.py +183 -0
  36. mirix/schemas/openai/__init__.py +1 -0
  37. mirix/schemas/openai/chat_completion_request.py +122 -0
  38. mirix/schemas/openai/chat_completion_response.py +144 -0
  39. mirix/schemas/openai/chat_completions.py +127 -0
  40. mirix/schemas/openai/embedding_response.py +11 -0
  41. mirix/schemas/openai/openai.py +229 -0
  42. mirix/schemas/organization.py +38 -0
  43. mirix/schemas/procedural_memory.py +151 -0
  44. mirix/schemas/providers.py +816 -0
  45. mirix/schemas/resource_memory.py +134 -0
  46. mirix/schemas/sandbox_config.py +132 -0
  47. mirix/schemas/semantic_memory.py +162 -0
  48. mirix/schemas/source.py +96 -0
  49. mirix/schemas/step.py +53 -0
  50. mirix/schemas/tool.py +241 -0
  51. mirix/schemas/tool_rule.py +209 -0
  52. mirix/schemas/usage.py +31 -0
  53. mirix/schemas/user.py +67 -0
mirix/schemas/block.py ADDED
@@ -0,0 +1,188 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field, model_validator
4
+ from typing_extensions import Self
5
+
6
+ from mirix.client.constants import CORE_MEMORY_BLOCK_CHAR_LIMIT
7
+ from mirix.schemas.mirix_base import MirixBase
8
+
9
+ # block of the LLM context
10
+
11
+
12
+ class BaseBlock(MirixBase, validate_assignment=True):
13
+ """Base block of the LLM context"""
14
+
15
+ __id_prefix__ = "block"
16
+
17
+ # data value
18
+ value: Optional[str] = Field(None, description="Value of the block.")
19
+ limit: int = Field(
20
+ CORE_MEMORY_BLOCK_CHAR_LIMIT, description="Character limit of the block."
21
+ )
22
+
23
+ # context window label
24
+ label: Optional[str] = Field(
25
+ None,
26
+ description="Label of the block (e.g. 'human', 'persona') in the context window.",
27
+ )
28
+
29
+ class Config:
30
+ extra = "ignore" # Ignores extra fields
31
+
32
+ @model_validator(mode="after")
33
+ def verify_char_limit(self) -> Self:
34
+ if self.value and len(self.value) > self.limit:
35
+ error_msg = f"Edit failed: Exceeds {self.limit} character limit (requested {len(self.value)}) - {str(self)}."
36
+ raise ValueError(error_msg)
37
+
38
+ return self
39
+
40
+ def __setattr__(self, name, value):
41
+ """Run validation if self.value is updated"""
42
+ super().__setattr__(name, value)
43
+ if name == "value":
44
+ # run validation
45
+ self.__class__.model_validate(self.model_dump(exclude_unset=True))
46
+
47
+
48
+ class Block(BaseBlock):
49
+ """
50
+ A Block represents a reserved section of the LLM's context window which is editable. `Block` objects contained in the `Memory` object, which is able to edit the Block values.
51
+
52
+ Parameters:
53
+ label (str): The label of the block (e.g. 'human', 'persona'). This defines a category for the block.
54
+ value (str): The value of the block. This is the string that is represented in the context window.
55
+ limit (int): The character limit of the block.
56
+ user_id (str): The unique identifier of the user associated with the block.
57
+ agent_id (str): The unique identifier of the agent associated with the block.
58
+ """
59
+
60
+ id: str = BaseBlock.generate_id_field()
61
+
62
+ # associated user/agent/organization
63
+ user_id: Optional[str] = Field(
64
+ None, description="The unique identifier of the user associated with the block."
65
+ )
66
+ agent_id: Optional[str] = Field(
67
+ None, description="The unique identifier of the agent associated with the block."
68
+ )
69
+ organization_id: Optional[str] = Field(
70
+ None,
71
+ description="The unique identifier of the organization associated with the block.",
72
+ )
73
+
74
+ # default orm fields
75
+ created_by_id: Optional[str] = Field(
76
+ None, description="The id of the user that made this Block."
77
+ )
78
+ last_updated_by_id: Optional[str] = Field(
79
+ None, description="The id of the user that last updated this Block."
80
+ )
81
+
82
+
83
+ class Human(Block):
84
+ """Human block of the LLM context"""
85
+
86
+ label: str = "human"
87
+
88
+
89
+ class Persona(Block):
90
+ """Persona block of the LLM context"""
91
+
92
+ label: str = "persona"
93
+
94
+
95
+ # class CreateBlock(BaseBlock):
96
+ # """Create a block"""
97
+ #
98
+ # label: str = Field(..., description="Label of the block.")
99
+
100
+
101
+ class BlockLabelUpdate(BaseModel):
102
+ """Update the label of a block"""
103
+
104
+ current_label: str = Field(..., description="Current label of the block.")
105
+ new_label: str = Field(..., description="New label of the block.")
106
+
107
+
108
+ # class CreatePersona(CreateBlock):
109
+ # """Create a persona block"""
110
+ #
111
+ # label: str = "persona"
112
+ #
113
+ #
114
+ # class CreateHuman(CreateBlock):
115
+ # """Create a human block"""
116
+ #
117
+ # label: str = "human"
118
+
119
+
120
+ class BlockUpdate(BaseBlock):
121
+ """Update a block"""
122
+
123
+ limit: Optional[int] = Field(
124
+ CORE_MEMORY_BLOCK_CHAR_LIMIT, description="Character limit of the block."
125
+ )
126
+ value: Optional[str] = Field(None, description="Value of the block.")
127
+
128
+ class Config:
129
+ extra = "ignore" # Ignores extra fields
130
+
131
+
132
+ class BlockLimitUpdate(BaseModel):
133
+ """Update the limit of a block"""
134
+
135
+ label: str = Field(..., description="Label of the block.")
136
+ limit: int = Field(..., description="New limit of the block.")
137
+
138
+
139
+ # class UpdatePersona(BlockUpdate):
140
+ # """Update a persona block"""
141
+ #
142
+ # label: str = "persona"
143
+ #
144
+ #
145
+ # class UpdateHuman(BlockUpdate):
146
+ # """Update a human block"""
147
+ #
148
+ # label: str = "human"
149
+
150
+
151
+ class CreateBlock(BaseBlock):
152
+ """Create a block"""
153
+
154
+ label: str = Field(..., description="Label of the block.")
155
+ limit: int = Field(
156
+ CORE_MEMORY_BLOCK_CHAR_LIMIT, description="Character limit of the block."
157
+ )
158
+ value: str = Field(..., description="Value of the block.")
159
+
160
+
161
+ class CreateHuman(CreateBlock):
162
+ """Create a human block"""
163
+
164
+ label: str = "human"
165
+
166
+
167
+ class CreatePersona(CreateBlock):
168
+ """Create a persona block"""
169
+
170
+ label: str = "persona"
171
+
172
+
173
+ class CreateBlockTemplate(CreateBlock):
174
+ """Create a block template"""
175
+
176
+ pass
177
+
178
+
179
+ class CreateHumanBlockTemplate(CreateHuman):
180
+ """Create a human block template"""
181
+
182
+ label: str = "human"
183
+
184
+
185
+ class CreatePersonaBlockTemplate(CreatePersona):
186
+ """Create a persona block template"""
187
+
188
+ label: str = "persona"
@@ -0,0 +1,29 @@
1
+ from datetime import datetime
2
+
3
+ from pydantic import Field
4
+
5
+ from mirix.client.utils import get_utc_time
6
+ from mirix.schemas.mirix_base import MirixBase
7
+
8
+
9
+ class CloudFileMappingBase(MirixBase):
10
+ __id_prefix__ = "cloud_map"
11
+
12
+
13
+ class CloudFileMapping(CloudFileMappingBase):
14
+ """
15
+ Schema for the mapping between cloud file and the local file
16
+ """
17
+
18
+ id: str = CloudFileMappingBase.generate_id_field()
19
+ cloud_file_id: str = Field(..., description="The ID of the cloud file")
20
+ local_file_id: str = Field(..., description="The ID of the local file")
21
+ status: str = Field(
22
+ ..., description="whether it has been processed into the memory system."
23
+ )
24
+ # TODO: change timestamp from str to datetime to accommodate timezone changes.
25
+ timestamp: str = Field(..., description="timestamp of the screenshot")
26
+ created_at: datetime = Field(
27
+ default_factory=get_utc_time,
28
+ description="Timestamp when this memory record was created",
29
+ )
@@ -0,0 +1,114 @@
1
+ from typing import Literal, Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from mirix.log import get_logger
6
+
7
+ logger = get_logger(__name__)
8
+
9
+ class EmbeddingConfig(BaseModel):
10
+ """
11
+
12
+ Embedding model configuration. This object specifies all the information necessary to access an embedding model to usage with Mirix, except for secret keys.
13
+
14
+ Attributes:
15
+ embedding_endpoint_type (str): The endpoint type for the model.
16
+ embedding_endpoint (str): The endpoint for the model.
17
+ embedding_model (str): The model for the embedding.
18
+ embedding_dim (int): The dimension of the embedding.
19
+ embedding_chunk_size (int): The chunk size of the embedding.
20
+ azure_endpoint (:obj:`str`, optional): The Azure endpoint for the model (Azure only).
21
+ azure_version (str): The Azure version for the model (Azure only).
22
+ azure_deployment (str): The Azure deployment for the model (Azure only).
23
+
24
+ """
25
+
26
+ embedding_endpoint_type: Literal[
27
+ "openai",
28
+ "anthropic",
29
+ "bedrock",
30
+ "cohere",
31
+ "google_ai",
32
+ "azure",
33
+ "groq",
34
+ "ollama",
35
+ "webui",
36
+ "webui-legacy",
37
+ "lmstudio",
38
+ "lmstudio-legacy",
39
+ "llamacpp",
40
+ "koboldcpp",
41
+ "vllm",
42
+ "hugging-face",
43
+ "mistral",
44
+ "together", # completions endpoint
45
+ ] = Field(..., description="The endpoint type for the model.")
46
+ embedding_endpoint: Optional[str] = Field(
47
+ None, description="The endpoint for the model (`None` if local)."
48
+ )
49
+ embedding_model: str = Field(..., description="The model for the embedding.")
50
+ embedding_dim: int = Field(..., description="The dimension of the embedding.")
51
+ embedding_chunk_size: Optional[int] = Field(
52
+ 300, description="The chunk size of the embedding."
53
+ )
54
+ handle: Optional[str] = Field(
55
+ None,
56
+ description="The handle for this config, in the format provider/model-name.",
57
+ )
58
+
59
+ # azure only
60
+ azure_endpoint: Optional[str] = Field(
61
+ None, description="The Azure endpoint for the model."
62
+ )
63
+ azure_version: Optional[str] = Field(
64
+ None, description="The Azure version for the model."
65
+ )
66
+ azure_deployment: Optional[str] = Field(
67
+ None, description="The Azure deployment for the model."
68
+ )
69
+
70
+ @classmethod
71
+ def default_config(
72
+ cls, model_name: Optional[str] = None, provider: Optional[str] = None
73
+ ):
74
+ if model_name == "text-embedding-3-small" or (
75
+ not model_name and provider == "openai"
76
+ ):
77
+ return cls(
78
+ embedding_model="text-embedding-3-small",
79
+ embedding_endpoint_type="openai",
80
+ embedding_endpoint="https://api.openai.com/v1",
81
+ embedding_dim=1536,
82
+ embedding_chunk_size=8191,
83
+ )
84
+ elif model_name == "text-embedding-004" or (
85
+ not model_name and provider == "google_ai"
86
+ ):
87
+ return cls(
88
+ embedding_model="text-embedding-004",
89
+ embedding_endpoint_type="google_ai",
90
+ embedding_endpoint="https://generativelanguage.googleapis.com",
91
+ embedding_dim=768,
92
+ embedding_chunk_size=2048,
93
+ )
94
+ elif model_name == "mirix":
95
+ return cls(
96
+ embedding_endpoint="https://embeddings.memgpt.ai",
97
+ embedding_model="BAAI/bge-large-en-v1.5",
98
+ embedding_dim=1024,
99
+ embedding_chunk_size=300,
100
+ embedding_endpoint_type="hugging-face",
101
+ )
102
+ else:
103
+ raise ValueError(f"Model {model_name} not supported.")
104
+
105
+ def pretty_print(self) -> str:
106
+ return (
107
+ f"{self.embedding_model}"
108
+ + (
109
+ f" [type={self.embedding_endpoint_type}]"
110
+ if self.embedding_endpoint_type
111
+ else ""
112
+ )
113
+ + (f" [ip={self.embedding_endpoint}]" if self.embedding_endpoint else "")
114
+ )
mirix/schemas/enums.py ADDED
@@ -0,0 +1,69 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ProviderType(str, Enum):
5
+ anthropic = "anthropic"
6
+
7
+
8
+ class MessageRole(str, Enum):
9
+ assistant = "assistant"
10
+ user = "user"
11
+ tool = "tool"
12
+ function = "function"
13
+ system = "system"
14
+
15
+
16
+ class OptionState(str, Enum):
17
+ """Useful for kwargs that are bool + default option"""
18
+
19
+ YES = "yes"
20
+ NO = "no"
21
+ DEFAULT = "default"
22
+
23
+
24
+ class JobStatus(str, Enum):
25
+ """
26
+ Status of the job.
27
+ """
28
+
29
+ not_started = "not_started"
30
+ created = "created"
31
+ running = "running"
32
+ completed = "completed"
33
+ failed = "failed"
34
+ pending = "pending"
35
+ cancelled = "cancelled"
36
+ expired = "expired"
37
+
38
+
39
+ class AgentStepStatus(str, Enum):
40
+ """
41
+ Status of the job.
42
+ """
43
+
44
+ paused = "paused"
45
+ resumed = "resumed"
46
+ completed = "completed"
47
+
48
+
49
+ class MessageStreamStatus(str, Enum):
50
+ done = "[DONE]"
51
+
52
+ def model_dump_json(self):
53
+ return "[DONE]"
54
+
55
+
56
+ class ToolRuleType(str, Enum):
57
+ """
58
+ Type of tool rule.
59
+ """
60
+
61
+ # note: some of these should be renamed when we do the data migration
62
+
63
+ run_first = "run_first"
64
+ exit_loop = "exit_loop" # reasoning loop should exit
65
+ continue_loop = "continue_loop"
66
+ conditional = "conditional"
67
+ constrain_child_tools = "constrain_child_tools"
68
+ max_count_per_step = "max_count_per_step"
69
+ parent_last_tool = "parent_last_tool"
@@ -0,0 +1,82 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import Field
4
+
5
+ from mirix.schemas.mirix_base import MirixBase, OrmMetadataBase
6
+
7
+
8
+ # Base Environment Variable
9
+ class EnvironmentVariableBase(OrmMetadataBase):
10
+ id: str = Field(
11
+ ..., description="The unique identifier for the environment variable."
12
+ )
13
+ key: str = Field(..., description="The name of the environment variable.")
14
+ value: str = Field(..., description="The value of the environment variable.")
15
+ description: Optional[str] = Field(
16
+ None, description="An optional description of the environment variable."
17
+ )
18
+ organization_id: Optional[str] = Field(
19
+ None,
20
+ description="The ID of the organization this environment variable belongs to.",
21
+ )
22
+
23
+
24
+ class EnvironmentVariableCreateBase(MirixBase):
25
+ key: str = Field(..., description="The name of the environment variable.")
26
+ value: str = Field(..., description="The value of the environment variable.")
27
+ description: Optional[str] = Field(
28
+ None, description="An optional description of the environment variable."
29
+ )
30
+
31
+
32
+ class EnvironmentVariableUpdateBase(MirixBase):
33
+ key: Optional[str] = Field(
34
+ None, description="The name of the environment variable."
35
+ )
36
+ value: Optional[str] = Field(
37
+ None, description="The value of the environment variable."
38
+ )
39
+ description: Optional[str] = Field(
40
+ None, description="An optional description of the environment variable."
41
+ )
42
+
43
+
44
+ # Environment Variable
45
+ class SandboxEnvironmentVariableBase(EnvironmentVariableBase):
46
+ __id_prefix__ = "sandbox-env"
47
+ sandbox_config_id: str = Field(
48
+ ...,
49
+ description="The ID of the sandbox config this environment variable belongs to.",
50
+ )
51
+
52
+
53
+ class SandboxEnvironmentVariable(SandboxEnvironmentVariableBase):
54
+ id: str = SandboxEnvironmentVariableBase.generate_id_field()
55
+
56
+
57
+ class SandboxEnvironmentVariableCreate(EnvironmentVariableCreateBase):
58
+ pass
59
+
60
+
61
+ class SandboxEnvironmentVariableUpdate(EnvironmentVariableUpdateBase):
62
+ pass
63
+
64
+
65
+ # Agent-Specific Environment Variable
66
+ class AgentEnvironmentVariableBase(EnvironmentVariableBase):
67
+ __id_prefix__ = "agent-env"
68
+ agent_id: str = Field(
69
+ ..., description="The ID of the agent this environment variable belongs to."
70
+ )
71
+
72
+
73
+ class AgentEnvironmentVariable(AgentEnvironmentVariableBase):
74
+ id: str = AgentEnvironmentVariableBase.generate_id_field()
75
+
76
+
77
+ class AgentEnvironmentVariableCreate(EnvironmentVariableCreateBase):
78
+ pass
79
+
80
+
81
+ class AgentEnvironmentVariableUpdate(EnvironmentVariableUpdateBase):
82
+ pass
@@ -0,0 +1,170 @@
1
+ from datetime import datetime
2
+ from typing import Any, Dict, List, Optional
3
+
4
+ from pydantic import Field, field_validator
5
+
6
+ from mirix.client.utils import get_utc_time
7
+ from mirix.client.constants import MAX_EMBEDDING_DIM
8
+ from mirix.schemas.embedding_config import EmbeddingConfig
9
+ from mirix.schemas.mirix_base import MirixBase
10
+
11
+
12
+ class EpisodicEventBase(MirixBase):
13
+ """
14
+ Base schema for episodic memory events containing common fields.
15
+ """
16
+
17
+ __id_prefix__ = "ep_mem"
18
+ event_type: str = Field(
19
+ ...,
20
+ description="Type/category of the episodic event (e.g., user_message, inference, system_notification)",
21
+ )
22
+ summary: str = Field(..., description="Short textual summary of the event")
23
+ details: str = Field(..., description="Detailed description or text for the event")
24
+ actor: str = Field(
25
+ ..., description="The actor who generated the event (user or assistant)"
26
+ )
27
+
28
+
29
+ class EpisodicEventForLLM(EpisodicEventBase):
30
+ """
31
+ Schema for creating a new episodic memory record.
32
+ """
33
+
34
+ # TODO: make `occurred_at` optional
35
+ occurred_at: str = Field(
36
+ ...,
37
+ description="When the event happened (it should be mentioned in the user's response and it should be in the format of 'YYYY-MM-DD HH:MM:SS')",
38
+ )
39
+
40
+
41
+ class EpisodicEvent(EpisodicEventBase):
42
+ """
43
+ Representation of a single episodic memory event in the system.
44
+
45
+ Additional Parameters:
46
+ id (str): Unique identifier for this memory item
47
+ occurred_at (datetime): When the event occurred or was recorded
48
+ created_at (datetime): When the memory record was created in the system
49
+ updated_at (Optional[datetime]): Last update timestamp
50
+ """
51
+
52
+ id: Optional[str] = Field(
53
+ None, description="Unique identifier for the episodic event"
54
+ )
55
+
56
+ agent_id: Optional[str] = Field(
57
+ None, description="The id of the agent this episodic event belongs to"
58
+ )
59
+
60
+ user_id: str = Field(
61
+ ..., description="The id of the user who generated the episodic event"
62
+ )
63
+
64
+ occurred_at: datetime = Field(
65
+ default_factory=get_utc_time,
66
+ description="When the event actually happened (recorded or user-labeled).",
67
+ )
68
+ created_at: datetime = Field(
69
+ default_factory=get_utc_time,
70
+ description="Timestamp when this memory record was created",
71
+ )
72
+ updated_at: Optional[datetime] = Field(
73
+ None, description="When this memory record was last updated"
74
+ )
75
+ last_modify: Dict[str, Any] = Field(
76
+ default_factory=lambda: {
77
+ "timestamp": get_utc_time().isoformat(),
78
+ "operation": "created",
79
+ },
80
+ description="Last modification info including timestamp and operation type",
81
+ )
82
+ organization_id: str = Field(
83
+ ..., description="Unique identifier of the organization"
84
+ )
85
+ details_embedding: Optional[List[float]] = Field(
86
+ None, description="The embedding of the event"
87
+ )
88
+ summary_embedding: Optional[List[float]] = Field(
89
+ None, description="The embedding of the summary"
90
+ )
91
+ embedding_config: Optional[EmbeddingConfig] = Field(
92
+ None, description="The embedding configuration used by the event"
93
+ )
94
+
95
+ # NEW: Filter tags for flexible filtering and categorization
96
+ filter_tags: Optional[Dict[str, Any]] = Field(
97
+ default=None,
98
+ description="Custom filter tags for filtering and categorization",
99
+ examples=[
100
+ {
101
+ "project_id": "proj-abc",
102
+ "session_id": "sess-xyz",
103
+ "tags": ["important", "work"],
104
+ "priority": "high"
105
+ }
106
+ ]
107
+ )
108
+
109
+ # need to validate both details_embedding and summary_embedding to ensure they are the same size
110
+ @field_validator("details_embedding", "summary_embedding")
111
+ @classmethod
112
+ def pad_embeddings(cls, embedding: List[float]) -> List[float]:
113
+ """Pad embeddings to `MAX_EMBEDDING_SIZE`. This is necessary to ensure all stored embeddings are the same size."""
114
+ import numpy as np
115
+
116
+ if embedding and len(embedding) != MAX_EMBEDDING_DIM:
117
+ np_embedding = np.array(embedding)
118
+ padded_embedding = np.pad(
119
+ np_embedding,
120
+ (0, MAX_EMBEDDING_DIM - np_embedding.shape[0]),
121
+ mode="constant",
122
+ )
123
+ return padded_embedding.tolist()
124
+ return embedding
125
+
126
+
127
+ class EpisodicEventUpdate(MirixBase):
128
+ """
129
+ Schema for updating an existing episodic memory record.
130
+
131
+ All fields (except id) are optional so that only provided fields are updated.
132
+ """
133
+
134
+ id: str = Field(..., description="Unique ID for this episodic memory record")
135
+ agent_id: Optional[str] = Field(
136
+ None, description="The id of the agent this episodic event belongs to"
137
+ )
138
+ event_type: Optional[str] = Field(None, description="Type/category of the event")
139
+ summary: Optional[str] = Field(
140
+ None, description="Short textual summary of the event"
141
+ )
142
+ details: Optional[str] = Field(
143
+ None, description="Detailed text describing the event"
144
+ )
145
+ organization_id: Optional[str] = Field(
146
+ None, description="Unique identifier of the organization"
147
+ )
148
+ occurred_at: Optional[datetime] = Field(
149
+ None, description="If the event's time is updated"
150
+ )
151
+ updated_at: datetime = Field(
152
+ default_factory=get_utc_time,
153
+ description="Timestamp when this memory record was last updated",
154
+ )
155
+ last_modify: Optional[Dict[str, Any]] = Field(
156
+ None,
157
+ description="Last modification info including timestamp and operation type",
158
+ )
159
+ summary_embedding: Optional[List[float]] = Field(
160
+ None, description="The embedding of the summary"
161
+ )
162
+ details_embedding: Optional[List[float]] = Field(
163
+ None, description="The embedding of the event"
164
+ )
165
+ embedding_config: Optional[EmbeddingConfig] = Field(
166
+ None, description="The embedding configuration used by the event"
167
+ )
168
+ filter_tags: Optional[Dict[str, Any]] = Field(
169
+ None, description="Custom filter tags for filtering and categorization"
170
+ )