jl-ecms-client 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jl_ecms_client-0.2.0.dist-info/METADATA +295 -0
- jl_ecms_client-0.2.0.dist-info/RECORD +51 -0
- jl_ecms_client-0.2.0.dist-info/WHEEL +5 -0
- jl_ecms_client-0.2.0.dist-info/licenses/LICENSE +190 -0
- jl_ecms_client-0.2.0.dist-info/top_level.txt +1 -0
- mirix/client/__init__.py +72 -0
- mirix/client/client.py +2594 -0
- mirix/client/remote_client.py +1136 -0
- mirix/helpers/__init__.py +1 -0
- mirix/helpers/converters.py +429 -0
- mirix/helpers/datetime_helpers.py +90 -0
- mirix/helpers/json_helpers.py +47 -0
- mirix/helpers/message_helpers.py +74 -0
- mirix/helpers/tool_rule_solver.py +166 -0
- mirix/schemas/__init__.py +1 -0
- mirix/schemas/agent.py +400 -0
- mirix/schemas/block.py +188 -0
- mirix/schemas/cloud_file_mapping.py +29 -0
- mirix/schemas/embedding_config.py +114 -0
- mirix/schemas/enums.py +69 -0
- mirix/schemas/environment_variables.py +82 -0
- mirix/schemas/episodic_memory.py +170 -0
- mirix/schemas/file.py +57 -0
- mirix/schemas/health.py +10 -0
- mirix/schemas/knowledge_vault.py +181 -0
- mirix/schemas/llm_config.py +187 -0
- mirix/schemas/memory.py +318 -0
- mirix/schemas/message.py +1315 -0
- mirix/schemas/mirix_base.py +107 -0
- mirix/schemas/mirix_message.py +411 -0
- mirix/schemas/mirix_message_content.py +230 -0
- mirix/schemas/mirix_request.py +39 -0
- mirix/schemas/mirix_response.py +183 -0
- mirix/schemas/openai/__init__.py +1 -0
- mirix/schemas/openai/chat_completion_request.py +122 -0
- mirix/schemas/openai/chat_completion_response.py +144 -0
- mirix/schemas/openai/chat_completions.py +127 -0
- mirix/schemas/openai/embedding_response.py +11 -0
- mirix/schemas/openai/openai.py +229 -0
- mirix/schemas/organization.py +38 -0
- mirix/schemas/procedural_memory.py +151 -0
- mirix/schemas/providers.py +816 -0
- mirix/schemas/resource_memory.py +134 -0
- mirix/schemas/sandbox_config.py +132 -0
- mirix/schemas/semantic_memory.py +162 -0
- mirix/schemas/source.py +96 -0
- mirix/schemas/step.py +53 -0
- mirix/schemas/tool.py +241 -0
- mirix/schemas/tool_rule.py +209 -0
- mirix/schemas/usage.py +31 -0
- 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.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.schemas.mirix_base import MirixBase
|
|
6
|
+
from mirix.utils import get_utc_time
|
|
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.constants import MAX_EMBEDDING_DIM
|
|
7
|
+
from mirix.schemas.embedding_config import EmbeddingConfig
|
|
8
|
+
from mirix.schemas.mirix_base import MirixBase
|
|
9
|
+
from mirix.utils import get_utc_time
|
|
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
|
+
)
|