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
@@ -0,0 +1,134 @@
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.constants import MAX_EMBEDDING_DIM
7
+ from mirix.schemas.embedding_config import EmbeddingConfig
8
+ from mirix.schemas.mirix_base import MirixBase
9
+ from mirix.client.utils import get_utc_time
10
+
11
+
12
+ class ResourceMemoryItemBase(MirixBase):
13
+ """
14
+ Base schema for resource memory items - storing docs, user files, references, etc.
15
+ """
16
+
17
+ __id_prefix__ = "res_item"
18
+ title: str = Field(..., description="Short name/title of the resource")
19
+ summary: str = Field(
20
+ ..., description="Short description or summary of the resource"
21
+ )
22
+ resource_type: str = Field(
23
+ ..., description="File type or format (e.g. 'doc', 'markdown', 'pdf_text')"
24
+ )
25
+ content: str = Field(
26
+ ..., description="Full or partial text content of the resource"
27
+ )
28
+
29
+
30
+ class ResourceMemoryItem(ResourceMemoryItemBase):
31
+ """
32
+ Full schema for resource memory items with DB fields.
33
+ """
34
+
35
+ id: Optional[str] = Field(
36
+ None, description="Unique identifier for the resource memory item"
37
+ )
38
+ agent_id: Optional[str] = Field(
39
+ None, description="The id of the agent this resource memory item belongs to"
40
+ )
41
+ user_id: str = Field(
42
+ ..., description="The id of the user who generated the resource"
43
+ )
44
+ created_at: datetime = Field(
45
+ default_factory=get_utc_time, description="Creation timestamp"
46
+ )
47
+ updated_at: Optional[datetime] = Field(None, description="Last update timestamp")
48
+ last_modify: Dict[str, Any] = Field(
49
+ default_factory=lambda: {
50
+ "timestamp": get_utc_time().isoformat(),
51
+ "operation": "created",
52
+ },
53
+ description="Last modification info including timestamp and operation type",
54
+ )
55
+ organization_id: str = Field(
56
+ ..., description="The unique identifier of the organization"
57
+ )
58
+ summary_embedding: Optional[List[float]] = Field(
59
+ None, description="The embedding of the summary"
60
+ )
61
+ embedding_config: Optional[EmbeddingConfig] = Field(
62
+ None, description="The embedding configuration used by the event"
63
+ )
64
+
65
+ # NEW: Filter tags for flexible filtering and categorization
66
+ filter_tags: Optional[Dict[str, Any]] = Field(
67
+ default=None,
68
+ description="Custom filter tags for filtering and categorization",
69
+ examples=[
70
+ {
71
+ "project_id": "proj-abc",
72
+ "session_id": "sess-xyz",
73
+ "tags": ["important", "work"],
74
+ "priority": "high"
75
+ }
76
+ ]
77
+ )
78
+
79
+ @field_validator("summary_embedding")
80
+ @classmethod
81
+ def pad_embeddings(cls, embedding: List[float]) -> List[float]:
82
+ """Pad embeddings to `MAX_EMBEDDING_SIZE`. This is necessary to ensure all stored embeddings are the same size."""
83
+ import numpy as np
84
+
85
+ if embedding and len(embedding) != MAX_EMBEDDING_DIM:
86
+ np_embedding = np.array(embedding)
87
+ padded_embedding = np.pad(
88
+ np_embedding,
89
+ (0, MAX_EMBEDDING_DIM - np_embedding.shape[0]),
90
+ mode="constant",
91
+ )
92
+ return padded_embedding.tolist()
93
+ return embedding
94
+
95
+
96
+ class ResourceMemoryItemUpdate(MirixBase):
97
+ """Schema for updating an existing resource memory item."""
98
+
99
+ id: str = Field(..., description="Unique ID for this resource memory entry")
100
+ agent_id: Optional[str] = Field(
101
+ None, description="The id of the agent this resource memory item belongs to"
102
+ )
103
+ title: Optional[str] = Field(None, description="Short name/title of the resource")
104
+ summary: Optional[str] = Field(
105
+ None, description="Short description or summary of the resource"
106
+ )
107
+ resource_type: Optional[str] = Field(
108
+ None, description="File type/format (e.g. 'doc', 'markdown')"
109
+ )
110
+ content: Optional[str] = Field(None, description="Full or partial text content")
111
+ organization_id: Optional[str] = Field(None, description="The organization ID")
112
+ updated_at: datetime = Field(
113
+ default_factory=get_utc_time, description="Update timestamp"
114
+ )
115
+ last_modify: Optional[Dict[str, Any]] = Field(
116
+ None,
117
+ description="Last modification info including timestamp and operation type",
118
+ )
119
+ summary_embedding: Optional[List[float]] = Field(
120
+ None, description="The embedding of the summary"
121
+ )
122
+ embedding_config: Optional[EmbeddingConfig] = Field(
123
+ None, description="The embedding configuration used by the event"
124
+ )
125
+
126
+
127
+ filter_tags: Optional[Dict[str, Any]] = Field(
128
+ None, description="Custom filter tags for filtering and categorization"
129
+ )
130
+
131
+ class ResourceMemoryItemResponse(ResourceMemoryItem):
132
+ """Response schema for resource memory item with additional fields if needed."""
133
+
134
+ pass
@@ -0,0 +1,132 @@
1
+ import hashlib
2
+ import json
3
+ from enum import Enum
4
+ from typing import Any, Dict, List, Literal, Optional, Union
5
+
6
+ from pydantic import BaseModel, Field, model_validator
7
+
8
+ from mirix.schemas.agent import AgentState
9
+ from mirix.schemas.mirix_base import MirixBase, OrmMetadataBase
10
+ from mirix.settings import tool_settings
11
+ from mirix.log import get_logger
12
+
13
+
14
+ # Sandbox Config
15
+
16
+ logger = get_logger(__name__)
17
+ class SandboxType(str, Enum):
18
+ E2B = "e2b"
19
+ LOCAL = "local"
20
+
21
+
22
+ class SandboxRunResult(BaseModel):
23
+ func_return: Optional[Any] = Field(None, description="The function return object")
24
+ agent_state: Optional[AgentState] = Field(None, description="The agent state")
25
+ stdout: Optional[List[str]] = Field(
26
+ None,
27
+ description="Captured stdout (e.g. prints, logs) from the function invocation",
28
+ )
29
+ stderr: Optional[List[str]] = Field(
30
+ None, description="Captured stderr from the function invocation"
31
+ )
32
+ status: Literal["success", "error"] = Field(
33
+ ..., description="The status of the tool execution and return object"
34
+ )
35
+ sandbox_config_fingerprint: str = Field(
36
+ None, description="The fingerprint of the config for the sandbox"
37
+ )
38
+
39
+
40
+ class LocalSandboxConfig(BaseModel):
41
+ sandbox_dir: str = Field(..., description="Directory for the sandbox environment.")
42
+ use_venv: bool = Field(
43
+ False,
44
+ description="Whether or not to use the venv, or run directly in the same run loop.",
45
+ )
46
+ venv_name: str = Field(
47
+ "venv",
48
+ description="The name for the venv in the sandbox directory. We first search for an existing venv with this name, otherwise, we make it from the requirements.txt.",
49
+ )
50
+
51
+ @property
52
+ def type(self) -> "SandboxType":
53
+ return SandboxType.LOCAL
54
+
55
+
56
+ class E2BSandboxConfig(BaseModel):
57
+ timeout: int = Field(5 * 60, description="Time limit for the sandbox (in seconds).")
58
+ template: Optional[str] = Field(
59
+ None, description="The E2B template id (docker image)."
60
+ )
61
+ pip_requirements: Optional[List[str]] = Field(
62
+ None, description="A list of pip packages to install on the E2B Sandbox"
63
+ )
64
+
65
+ @property
66
+ def type(self) -> "SandboxType":
67
+ return SandboxType.E2B
68
+
69
+ @model_validator(mode="before")
70
+ @classmethod
71
+ def set_default_template(cls, data: dict):
72
+ """
73
+ Assign a default template value if the template field is not provided.
74
+ """
75
+ if data.get("template") is None:
76
+ data["template"] = tool_settings.e2b_sandbox_template_id
77
+ return data
78
+
79
+
80
+ class SandboxConfigBase(OrmMetadataBase):
81
+ __id_prefix__ = "sandbox"
82
+
83
+
84
+ class SandboxConfig(SandboxConfigBase):
85
+ id: str = SandboxConfigBase.generate_id_field()
86
+ type: SandboxType = Field(None, description="The type of sandbox.")
87
+ organization_id: Optional[str] = Field(
88
+ None,
89
+ description="The unique identifier of the organization associated with the sandbox.",
90
+ )
91
+ config: Dict = Field(
92
+ default_factory=lambda: {}, description="The JSON sandbox settings data."
93
+ )
94
+
95
+ def get_e2b_config(self) -> E2BSandboxConfig:
96
+ return E2BSandboxConfig(**self.config)
97
+
98
+ def get_local_config(self) -> LocalSandboxConfig:
99
+ return LocalSandboxConfig(**self.config)
100
+
101
+ def fingerprint(self) -> str:
102
+ # Only take into account type, org_id, and the config items
103
+ # Canonicalize input data into JSON with sorted keys
104
+ hash_input = json.dumps(
105
+ {
106
+ "type": self.type.value,
107
+ "organization_id": self.organization_id,
108
+ "config": self.config,
109
+ },
110
+ sort_keys=True, # Ensure stable ordering
111
+ separators=(",", ":"), # Minimize serialization differences
112
+ )
113
+
114
+ # Compute SHA-256 hash
115
+ hash_digest = hashlib.sha256(hash_input.encode("utf-8")).digest()
116
+
117
+ # Convert the digest to an integer for compatibility with Python's hash requirements
118
+ return str(int.from_bytes(hash_digest, byteorder="big"))
119
+
120
+
121
+ class SandboxConfigCreate(MirixBase):
122
+ config: Union[LocalSandboxConfig, E2BSandboxConfig] = Field(
123
+ ..., description="The configuration for the sandbox."
124
+ )
125
+
126
+
127
+ class SandboxConfigUpdate(MirixBase):
128
+ """Pydantic model for updating SandboxConfig fields."""
129
+
130
+ config: Union[LocalSandboxConfig, E2BSandboxConfig] = Field(
131
+ None, description="The JSON configuration data for the sandbox."
132
+ )
@@ -0,0 +1,162 @@
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.constants import MAX_EMBEDDING_DIM
7
+ from mirix.schemas.embedding_config import EmbeddingConfig
8
+ from mirix.schemas.mirix_base import MirixBase
9
+ from mirix.client.utils import get_utc_time
10
+
11
+
12
+ class SemanticMemoryItemBase(MirixBase):
13
+ """
14
+ Base schema for storing semantic memory items (e.g., general knowledge, concepts, facts).
15
+ """
16
+
17
+ __id_prefix__ = "sem_item"
18
+ name: str = Field(
19
+ ..., description="The name or main concept/object for the knowledge entry"
20
+ )
21
+ summary: str = Field(
22
+ ..., description="A concise explanation or summary of the concept"
23
+ )
24
+ details: str = Field(
25
+ ..., description="Detailed explanation or additional context for the concept"
26
+ )
27
+ source: str = Field(
28
+ ...,
29
+ description="Reference or origin of this information (e.g., book, article, movie)",
30
+ )
31
+
32
+
33
+ class SemanticMemoryItem(SemanticMemoryItemBase):
34
+ """
35
+ Full semantic memory item schema, including database-related fields.
36
+ """
37
+
38
+ id: Optional[str] = Field(
39
+ None, description="Unique identifier for the semantic memory item"
40
+ )
41
+ agent_id: Optional[str] = Field(
42
+ None, description="The id of the agent this semantic memory item belongs to"
43
+ )
44
+ user_id: str = Field(
45
+ ..., description="The id of the user who generated the semantic memory"
46
+ )
47
+ created_at: datetime = Field(
48
+ default_factory=get_utc_time, description="Creation timestamp"
49
+ )
50
+ updated_at: Optional[datetime] = Field(None, description="Last update timestamp")
51
+ last_modify: Dict[str, Any] = Field(
52
+ default_factory=lambda: {
53
+ "timestamp": get_utc_time().isoformat(),
54
+ "operation": "created",
55
+ },
56
+ description="Last modification info including timestamp and operation type",
57
+ )
58
+ organization_id: str = Field(
59
+ ..., description="The unique identifier of the organization"
60
+ )
61
+ details_embedding: Optional[List[float]] = Field(
62
+ None, description="The embedding of the details"
63
+ )
64
+ name_embedding: Optional[List[float]] = Field(
65
+ None, description="The embedding of the name"
66
+ )
67
+ summary_embedding: Optional[List[float]] = Field(
68
+ None, description="The embedding of the summary"
69
+ )
70
+ embedding_config: Optional[EmbeddingConfig] = Field(
71
+ None, description="The embedding configuration used by the event"
72
+ )
73
+
74
+ # NEW: Filter tags for flexible filtering and categorization
75
+ filter_tags: Optional[Dict[str, Any]] = Field(
76
+ default=None,
77
+ description="Custom filter tags for filtering and categorization",
78
+ examples=[
79
+ {
80
+ "project_id": "proj-abc",
81
+ "session_id": "sess-xyz",
82
+ "tags": ["important", "work"],
83
+ "priority": "high"
84
+ }
85
+ ]
86
+ )
87
+
88
+ # need to validate both details_embedding and summary_embedding to ensure they are the same size
89
+ @field_validator("details_embedding", "summary_embedding", "name_embedding")
90
+ @classmethod
91
+ def pad_embeddings(cls, embedding: List[float]) -> List[float]:
92
+ """Pad embeddings to `MAX_EMBEDDING_SIZE`. This is necessary to ensure all stored embeddings are the same size."""
93
+ import numpy as np
94
+
95
+ if embedding and len(embedding) != MAX_EMBEDDING_DIM:
96
+ np_embedding = np.array(embedding)
97
+ padded_embedding = np.pad(
98
+ np_embedding,
99
+ (0, MAX_EMBEDDING_DIM - np_embedding.shape[0]),
100
+ mode="constant",
101
+ )
102
+ return padded_embedding.tolist()
103
+ return embedding
104
+
105
+
106
+ class SemanticMemoryItemUpdate(MirixBase):
107
+ """
108
+ Schema for updating an existing semantic memory item.
109
+ """
110
+
111
+ id: str = Field(..., description="Unique ID for this semantic memory entry")
112
+ agent_id: Optional[str] = Field(
113
+ None, description="The id of the agent this semantic memory item belongs to"
114
+ )
115
+ name: Optional[str] = Field(
116
+ None, description="The name or main concept for the knowledge entry"
117
+ )
118
+ summary: Optional[str] = Field(
119
+ None, description="A concise explanation or summary of the concept"
120
+ )
121
+ details: Optional[str] = Field(
122
+ None, description="Detailed explanation or additional context for the concept"
123
+ )
124
+ source: Optional[str] = Field(
125
+ None,
126
+ description="Reference or origin of this information (e.g., book, article, movie)",
127
+ )
128
+ actor: Optional[str] = Field(
129
+ None,
130
+ description="The actor who generated the semantic memory (user or assistant)",
131
+ )
132
+ organization_id: Optional[str] = Field(None, description="The organization ID")
133
+ updated_at: datetime = Field(
134
+ default_factory=get_utc_time, description="Update timestamp"
135
+ )
136
+ last_modify: Optional[Dict[str, Any]] = Field(
137
+ None,
138
+ description="Last modification info including timestamp and operation type",
139
+ )
140
+ details_embedding: Optional[List[float]] = Field(
141
+ None, description="The embedding of the details"
142
+ )
143
+ name_embedding: Optional[List[float]] = Field(
144
+ None, description="The embedding of the name"
145
+ )
146
+ summary_embedding: Optional[List[float]] = Field(
147
+ None, description="The embedding of the summary"
148
+ )
149
+ embedding_config: Optional[EmbeddingConfig] = Field(
150
+ None, description="The embedding configuration used by the event"
151
+ )
152
+ filter_tags: Optional[Dict[str, Any]] = Field(
153
+ None, description="Custom filter tags for filtering and categorization"
154
+ )
155
+
156
+
157
+ class SemanticMemoryItemResponse(SemanticMemoryItem):
158
+ """
159
+ Response schema for semantic memory item.
160
+ """
161
+
162
+ pass
@@ -0,0 +1,96 @@
1
+ from datetime import datetime
2
+ from typing import Optional
3
+
4
+ from pydantic import Field
5
+
6
+ from mirix.schemas.embedding_config import EmbeddingConfig
7
+ from mirix.schemas.mirix_base import MirixBase
8
+
9
+
10
+ class BaseSource(MirixBase):
11
+ """
12
+ Shared attributes accourss all source schemas.
13
+ """
14
+
15
+ __id_prefix__ = "source"
16
+
17
+
18
+ class Source(BaseSource):
19
+ """
20
+ Representation of a source, which is a collection of files and passages.
21
+
22
+ Parameters:
23
+ id (str): The ID of the source
24
+ name (str): The name of the source.
25
+ embedding_config (EmbeddingConfig): The embedding configuration used by the source.
26
+ user_id (str): The ID of the user that created the source.
27
+ metadata_ (dict): Metadata associated with the source.
28
+ description (str): The description of the source.
29
+ """
30
+
31
+ id: str = BaseSource.generate_id_field()
32
+ name: str = Field(..., description="The name of the source.")
33
+ description: Optional[str] = Field(
34
+ None, description="The description of the source."
35
+ )
36
+ embedding_config: EmbeddingConfig = Field(
37
+ ..., description="The embedding configuration used by the source."
38
+ )
39
+ organization_id: Optional[str] = Field(
40
+ None, description="The ID of the organization that created the source."
41
+ )
42
+ metadata_: Optional[dict] = Field(
43
+ None, description="Metadata associated with the source."
44
+ )
45
+
46
+ # metadata fields
47
+ created_by_id: Optional[str] = Field(
48
+ None, description="The id of the user that made this Tool."
49
+ )
50
+ last_updated_by_id: Optional[str] = Field(
51
+ None, description="The id of the user that made this Tool."
52
+ )
53
+ created_at: Optional[datetime] = Field(
54
+ None, description="The timestamp when the source was created."
55
+ )
56
+ updated_at: Optional[datetime] = Field(
57
+ None, description="The timestamp when the source was last updated."
58
+ )
59
+
60
+
61
+ class SourceCreate(BaseSource):
62
+ """
63
+ Schema for creating a new Source.
64
+ """
65
+
66
+ # required
67
+ name: str = Field(..., description="The name of the source.")
68
+ # TODO: @matt, make this required after shub makes the FE changes
69
+ embedding_config: Optional[EmbeddingConfig] = Field(
70
+ None, description="The embedding configuration used by the source."
71
+ )
72
+
73
+ # optional
74
+ description: Optional[str] = Field(
75
+ None, description="The description of the source."
76
+ )
77
+ metadata_: Optional[dict] = Field(
78
+ None, description="Metadata associated with the source."
79
+ )
80
+
81
+
82
+ class SourceUpdate(BaseSource):
83
+ """
84
+ Schema for updating an existing Source.
85
+ """
86
+
87
+ name: Optional[str] = Field(None, description="The name of the source.")
88
+ description: Optional[str] = Field(
89
+ None, description="The description of the source."
90
+ )
91
+ metadata_: Optional[dict] = Field(
92
+ None, description="Metadata associated with the source."
93
+ )
94
+ embedding_config: Optional[EmbeddingConfig] = Field(
95
+ None, description="The embedding configuration used by the source."
96
+ )
mirix/schemas/step.py ADDED
@@ -0,0 +1,53 @@
1
+ from typing import Dict, List, Optional
2
+
3
+ from pydantic import Field
4
+
5
+ from mirix.schemas.message import Message
6
+ from mirix.schemas.mirix_base import MirixBase
7
+
8
+
9
+ class StepBase(MirixBase):
10
+ __id_prefix__ = "step"
11
+
12
+
13
+ class Step(StepBase):
14
+ id: str = Field(..., description="The id of the step. Assigned by the database.")
15
+ origin: Optional[str] = Field(
16
+ None, description="The surface that this agent step was initiated from."
17
+ )
18
+ organization_id: Optional[str] = Field(
19
+ None,
20
+ description="The unique identifier of the organization associated with the step.",
21
+ )
22
+ provider_name: Optional[str] = Field(
23
+ None, description="The name of the provider used for this step."
24
+ )
25
+ model: Optional[str] = Field(
26
+ None, description="The name of the model used for this step."
27
+ )
28
+ context_window_limit: Optional[int] = Field(
29
+ None, description="The context window limit configured for this step."
30
+ )
31
+ completion_tokens: Optional[int] = Field(
32
+ None,
33
+ description="The number of tokens generated by the agent during this step.",
34
+ )
35
+ prompt_tokens: Optional[int] = Field(
36
+ None, description="The number of tokens in the prompt during this step."
37
+ )
38
+ total_tokens: Optional[int] = Field(
39
+ None,
40
+ description="The total number of tokens processed by the agent during this step.",
41
+ )
42
+ completion_tokens_details: Optional[Dict] = Field(
43
+ None, description="Metadata for the agent."
44
+ )
45
+
46
+ tags: List[str] = Field([], description="Metadata tags.")
47
+ tid: Optional[str] = Field(
48
+ None,
49
+ description="The unique identifier of the transaction that processed this step.",
50
+ )
51
+ messages: List[Message] = Field(
52
+ [], description="The messages generated during this step."
53
+ )