coreason-manifest 0.9.0__py3-none-any.whl → 0.12.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.
- coreason_manifest/__init__.py +47 -13
- coreason_manifest/common.py +64 -0
- coreason_manifest/governance.py +83 -0
- coreason_manifest/schemas/__init__.py +9 -1
- coreason_manifest/schemas/coreason-v2.schema.json +462 -0
- coreason_manifest/utils/__init__.py +10 -0
- coreason_manifest/utils/logger.py +10 -0
- coreason_manifest/v2/__init__.py +1 -0
- coreason_manifest/v2/governance.py +144 -0
- coreason_manifest/v2/io.py +132 -0
- coreason_manifest/v2/resolver.py +67 -0
- coreason_manifest/v2/spec/__init__.py +1 -0
- coreason_manifest/v2/spec/contracts.py +34 -0
- coreason_manifest/v2/spec/definitions.py +196 -0
- coreason_manifest/v2/validator.py +48 -0
- {coreason_manifest-0.9.0.dist-info → coreason_manifest-0.12.0.dist-info}/METADATA +68 -29
- coreason_manifest-0.12.0.dist-info/RECORD +20 -0
- {coreason_manifest-0.9.0.dist-info → coreason_manifest-0.12.0.dist-info}/WHEEL +1 -1
- coreason_manifest/definitions/__init__.py +0 -49
- coreason_manifest/definitions/agent.py +0 -292
- coreason_manifest/definitions/audit.py +0 -122
- coreason_manifest/definitions/events.py +0 -392
- coreason_manifest/definitions/message.py +0 -126
- coreason_manifest/definitions/simulation.py +0 -50
- coreason_manifest/definitions/topology.py +0 -255
- coreason_manifest/recipes.py +0 -76
- coreason_manifest/schemas/agent.schema.json +0 -849
- coreason_manifest-0.9.0.dist-info/RECORD +0 -18
- {coreason_manifest-0.9.0.dist-info → coreason_manifest-0.12.0.dist-info}/licenses/LICENSE +0 -0
- {coreason_manifest-0.9.0.dist-info → coreason_manifest-0.12.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
from datetime import datetime, timezone
|
|
2
|
-
from typing import Any, Dict, Generic, Literal, Optional, Protocol, TypeVar, runtime_checkable
|
|
3
|
-
from uuid import uuid4
|
|
4
|
-
|
|
5
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
-
|
|
7
|
-
# --- CloudEvents v1.0 Implementation ---
|
|
8
|
-
|
|
9
|
-
T = TypeVar("T")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@runtime_checkable
|
|
13
|
-
class CloudEventSource(Protocol):
|
|
14
|
-
def as_cloud_event_payload(self) -> Any: ...
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class CloudEvent(BaseModel, Generic[T]):
|
|
18
|
-
"""Standard CloudEvent v1.0 Envelope."""
|
|
19
|
-
|
|
20
|
-
model_config = ConfigDict(extra="allow", populate_by_name=True)
|
|
21
|
-
|
|
22
|
-
specversion: Literal["1.0"] = "1.0"
|
|
23
|
-
type: str = Field(..., description="Type of occurrence (e.g. ai.coreason.node.started)")
|
|
24
|
-
source: str = Field(..., description="URI identifying the event producer")
|
|
25
|
-
id: str = Field(default_factory=lambda: str(uuid4()), description="Unique event identifier")
|
|
26
|
-
time: datetime = Field(
|
|
27
|
-
default_factory=lambda: datetime.now(timezone.utc), description="Timestamp of when the occurrence happened"
|
|
28
|
-
)
|
|
29
|
-
datacontenttype: Literal["application/json"] = "application/json"
|
|
30
|
-
|
|
31
|
-
data: Optional[T] = Field(None, description="The event payload")
|
|
32
|
-
|
|
33
|
-
# Distributed Tracing Extensions (W3C)
|
|
34
|
-
traceparent: Optional[str] = Field(None, description="W3C Trace Context traceparent")
|
|
35
|
-
tracestate: Optional[str] = Field(None, description="W3C Trace Context tracestate")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# --- OTel Semantic Conventions ---
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class GenAIUsage(BaseModel):
|
|
42
|
-
"""GenAI Usage metrics."""
|
|
43
|
-
|
|
44
|
-
input_tokens: Optional[int] = Field(None, alias="input_tokens")
|
|
45
|
-
output_tokens: Optional[int] = Field(None, alias="output_tokens")
|
|
46
|
-
|
|
47
|
-
model_config = ConfigDict(populate_by_name=True)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
class GenAIRequest(BaseModel):
|
|
51
|
-
"""GenAI Request details."""
|
|
52
|
-
|
|
53
|
-
model: Optional[str] = None
|
|
54
|
-
temperature: Optional[float] = None
|
|
55
|
-
top_p: Optional[float] = None
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class GenAICompletion(BaseModel):
|
|
59
|
-
"""GenAI Completion details."""
|
|
60
|
-
|
|
61
|
-
chunk: Optional[str] = None
|
|
62
|
-
finish_reason: Optional[str] = None
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
class GenAISemantics(BaseModel):
|
|
66
|
-
"""OpenTelemetry GenAI Semantic Conventions."""
|
|
67
|
-
|
|
68
|
-
system: Optional[str] = None
|
|
69
|
-
usage: Optional[GenAIUsage] = None
|
|
70
|
-
request: Optional[GenAIRequest] = None
|
|
71
|
-
completion: Optional[GenAICompletion] = None
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
# --- Graph Event Wrapper ---
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
class GraphEvent(BaseModel):
|
|
78
|
-
"""The atomic unit of communication between the Engine (MACO) and the UI (Flutter).
|
|
79
|
-
|
|
80
|
-
Standardized IDs:
|
|
81
|
-
- run_id: Workflow execution ID.
|
|
82
|
-
- trace_id: OpenTelemetry Distributed Trace ID.
|
|
83
|
-
|
|
84
|
-
Attributes:
|
|
85
|
-
event_type: The type of the event.
|
|
86
|
-
run_id: The unique ID of the workflow run.
|
|
87
|
-
trace_id: The trace ID (defaults to "unknown").
|
|
88
|
-
node_id: The ID of the node associated with the event.
|
|
89
|
-
timestamp: The timestamp of the event.
|
|
90
|
-
sequence_id: Optional sequence ID.
|
|
91
|
-
payload: The event payload containing logic output.
|
|
92
|
-
visual_metadata: Metadata for UI visualization.
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
model_config = ConfigDict(extra="forbid")
|
|
96
|
-
|
|
97
|
-
event_type: Literal[
|
|
98
|
-
"NODE_INIT",
|
|
99
|
-
"NODE_START",
|
|
100
|
-
"NODE_STREAM",
|
|
101
|
-
"NODE_DONE",
|
|
102
|
-
"NODE_SKIPPED",
|
|
103
|
-
"EDGE_ACTIVE",
|
|
104
|
-
"COUNCIL_VOTE",
|
|
105
|
-
"ERROR",
|
|
106
|
-
"NODE_RESTORED",
|
|
107
|
-
"ARTIFACT_GENERATED",
|
|
108
|
-
]
|
|
109
|
-
run_id: str
|
|
110
|
-
trace_id: str = Field(
|
|
111
|
-
default_factory=lambda: "unknown"
|
|
112
|
-
) # Default for compatibility if missing in some legacy calls
|
|
113
|
-
node_id: str # Required per BRD and existing tests
|
|
114
|
-
timestamp: float
|
|
115
|
-
sequence_id: Optional[int] = None # Optional for internal use
|
|
116
|
-
|
|
117
|
-
# The payload contains the actual reasoning/data
|
|
118
|
-
payload: Dict[str, Any] = Field(..., description="The logic output")
|
|
119
|
-
|
|
120
|
-
# Visual Metadata drives the Flutter animation engine
|
|
121
|
-
visual_metadata: Dict[str, str] = Field(
|
|
122
|
-
..., description="Hints for UI: color='#00FF00', animation='pulse', progress='0.5'"
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
# --- Base Models ---
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
class BaseNodePayload(BaseModel):
|
|
130
|
-
"""Base model for node-related events."""
|
|
131
|
-
|
|
132
|
-
model_config = ConfigDict(extra="ignore")
|
|
133
|
-
node_id: str
|
|
134
|
-
|
|
135
|
-
# Common OTel attributes that might appear in payload
|
|
136
|
-
model: Optional[str] = None
|
|
137
|
-
system: Optional[str] = None
|
|
138
|
-
|
|
139
|
-
def as_cloud_event_payload(self) -> Any:
|
|
140
|
-
return self
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# --- Payload Models ---
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
class NodeInit(BaseNodePayload):
|
|
147
|
-
"""Payload for NODE_INIT event."""
|
|
148
|
-
|
|
149
|
-
type: str = "DEFAULT"
|
|
150
|
-
visual_cue: str = "IDLE"
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
class NodeStarted(BaseNodePayload):
|
|
154
|
-
"""Payload for NODE_START event."""
|
|
155
|
-
|
|
156
|
-
timestamp: float
|
|
157
|
-
status: Literal["RUNNING"] = "RUNNING"
|
|
158
|
-
visual_cue: str = "PULSE"
|
|
159
|
-
input_tokens: Optional[int] = None
|
|
160
|
-
|
|
161
|
-
def as_cloud_event_payload(self) -> Any:
|
|
162
|
-
semantics = GenAISemantics()
|
|
163
|
-
has_semantics = False
|
|
164
|
-
|
|
165
|
-
if self.input_tokens is not None:
|
|
166
|
-
semantics.usage = GenAIUsage(input_tokens=self.input_tokens)
|
|
167
|
-
has_semantics = True
|
|
168
|
-
|
|
169
|
-
if self.model:
|
|
170
|
-
semantics.request = GenAIRequest(model=self.model)
|
|
171
|
-
has_semantics = True
|
|
172
|
-
|
|
173
|
-
if self.system:
|
|
174
|
-
semantics.system = self.system
|
|
175
|
-
has_semantics = True
|
|
176
|
-
|
|
177
|
-
return StandardizedNodeStarted(
|
|
178
|
-
node_id=self.node_id,
|
|
179
|
-
status=self.status,
|
|
180
|
-
gen_ai=semantics if has_semantics else None,
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
class NodeCompleted(BaseNodePayload):
|
|
185
|
-
"""Payload for NODE_DONE event."""
|
|
186
|
-
|
|
187
|
-
output_summary: str
|
|
188
|
-
status: Literal["SUCCESS"] = "SUCCESS"
|
|
189
|
-
visual_cue: str = "GREEN_GLOW"
|
|
190
|
-
cost: Optional[float] = None
|
|
191
|
-
|
|
192
|
-
def as_cloud_event_payload(self) -> Any:
|
|
193
|
-
semantics = GenAISemantics()
|
|
194
|
-
has_semantics = False
|
|
195
|
-
|
|
196
|
-
if self.model:
|
|
197
|
-
semantics.request = GenAIRequest(model=self.model)
|
|
198
|
-
has_semantics = True
|
|
199
|
-
|
|
200
|
-
return StandardizedNodeCompleted(
|
|
201
|
-
node_id=self.node_id,
|
|
202
|
-
output_summary=self.output_summary,
|
|
203
|
-
status=self.status,
|
|
204
|
-
gen_ai=semantics if has_semantics else None,
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
class NodeRestored(BaseNodePayload):
|
|
209
|
-
"""Payload for NODE_RESTORED event."""
|
|
210
|
-
|
|
211
|
-
output_summary: str
|
|
212
|
-
status: Literal["RESTORED"] = "RESTORED"
|
|
213
|
-
visual_cue: str = "INSTANT_GREEN"
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
class NodeSkipped(BaseNodePayload):
|
|
217
|
-
"""Payload for NODE_SKIPPED event."""
|
|
218
|
-
|
|
219
|
-
status: Literal["SKIPPED"] = "SKIPPED"
|
|
220
|
-
visual_cue: str = "GREY_OUT"
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
class NodeStream(BaseNodePayload):
|
|
224
|
-
"""Payload for NODE_STREAM event."""
|
|
225
|
-
|
|
226
|
-
chunk: str
|
|
227
|
-
visual_cue: str = "TEXT_BUBBLE"
|
|
228
|
-
|
|
229
|
-
def as_cloud_event_payload(self) -> Any:
|
|
230
|
-
semantics = GenAISemantics(completion=GenAICompletion(chunk=self.chunk))
|
|
231
|
-
if self.model:
|
|
232
|
-
if not semantics.request:
|
|
233
|
-
semantics.request = GenAIRequest()
|
|
234
|
-
semantics.request.model = self.model
|
|
235
|
-
|
|
236
|
-
return StandardizedNodeStream(node_id=self.node_id, gen_ai=semantics)
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
class ArtifactGenerated(BaseNodePayload):
|
|
240
|
-
"""Payload for ARTIFACT_GENERATED event."""
|
|
241
|
-
|
|
242
|
-
artifact_type: str = "PDF"
|
|
243
|
-
url: str
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
class EdgeTraversed(BaseModel):
|
|
247
|
-
"""Payload for EDGE_ACTIVE event."""
|
|
248
|
-
|
|
249
|
-
model_config = ConfigDict(extra="ignore")
|
|
250
|
-
source: str
|
|
251
|
-
target: str
|
|
252
|
-
animation_speed: str = "FAST"
|
|
253
|
-
|
|
254
|
-
def as_cloud_event_payload(self) -> Any:
|
|
255
|
-
return self
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
class CouncilVote(BaseNodePayload):
|
|
259
|
-
"""Payload for COUNCIL_VOTE event."""
|
|
260
|
-
|
|
261
|
-
votes: Dict[str, str]
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
class WorkflowError(BaseNodePayload):
|
|
265
|
-
"""Payload for ERROR event."""
|
|
266
|
-
|
|
267
|
-
error_message: str
|
|
268
|
-
stack_trace: str
|
|
269
|
-
input_snapshot: Dict[str, Any]
|
|
270
|
-
status: Literal["ERROR"] = "ERROR"
|
|
271
|
-
visual_cue: str = "RED_FLASH"
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
# --- Standardized Payloads ---
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
class StandardizedNodeStarted(BaseNodePayload):
|
|
278
|
-
"""Standardized payload for node start with OTel support."""
|
|
279
|
-
|
|
280
|
-
gen_ai: Optional[GenAISemantics] = None
|
|
281
|
-
status: Literal["RUNNING"] = "RUNNING"
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
class StandardizedNodeCompleted(BaseNodePayload):
|
|
285
|
-
"""Standardized payload for node completion with OTel support."""
|
|
286
|
-
|
|
287
|
-
gen_ai: Optional[GenAISemantics] = None
|
|
288
|
-
output_summary: str
|
|
289
|
-
status: Literal["SUCCESS"] = "SUCCESS"
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
class StandardizedNodeStream(BaseNodePayload):
|
|
293
|
-
"""Standardized payload for node stream with OTel support."""
|
|
294
|
-
|
|
295
|
-
gen_ai: Optional[GenAISemantics] = None
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
# --- Aliases for Backward Compatibility ---
|
|
299
|
-
# These ensure that code importing `NodeInitPayload` still works.
|
|
300
|
-
NodeInitPayload = NodeInit
|
|
301
|
-
NodeStartedPayload = NodeStarted
|
|
302
|
-
NodeCompletedPayload = NodeCompleted
|
|
303
|
-
NodeSkippedPayload = NodeSkipped
|
|
304
|
-
NodeStreamPayload = NodeStream
|
|
305
|
-
EdgeTraversedPayload = EdgeTraversed
|
|
306
|
-
ArtifactGeneratedPayload = ArtifactGenerated
|
|
307
|
-
CouncilVotePayload = CouncilVote
|
|
308
|
-
WorkflowErrorPayload = WorkflowError
|
|
309
|
-
|
|
310
|
-
# --- Migration Logic ---
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
def migrate_graph_event_to_cloud_event(event: GraphEvent) -> CloudEvent[Any]:
|
|
314
|
-
"""Migrates a legacy GraphEvent to a CloudEvent v1.0."""
|
|
315
|
-
|
|
316
|
-
ce_type_map = {
|
|
317
|
-
"NODE_START": "ai.coreason.node.started",
|
|
318
|
-
"NODE_STREAM": "ai.coreason.node.stream",
|
|
319
|
-
"NODE_DONE": "ai.coreason.node.completed",
|
|
320
|
-
}
|
|
321
|
-
ce_type = ce_type_map.get(event.event_type, f"ai.coreason.legacy.{event.event_type.lower()}")
|
|
322
|
-
ce_source = f"urn:node:{event.node_id}"
|
|
323
|
-
|
|
324
|
-
# Prepare payload dict with node_id injected
|
|
325
|
-
payload_dict = event.payload.copy()
|
|
326
|
-
payload_dict["node_id"] = event.node_id
|
|
327
|
-
# Inject timestamp if missing (required by some payloads like NodeStarted)
|
|
328
|
-
if "timestamp" not in payload_dict:
|
|
329
|
-
payload_dict["timestamp"] = event.timestamp
|
|
330
|
-
|
|
331
|
-
# Mapping event types to their corresponding payload classes
|
|
332
|
-
event_class_map: Dict[str, Any] = {
|
|
333
|
-
"NODE_INIT": NodeInit,
|
|
334
|
-
"NODE_START": NodeStarted,
|
|
335
|
-
"NODE_DONE": NodeCompleted,
|
|
336
|
-
"NODE_STREAM": NodeStream,
|
|
337
|
-
"NODE_SKIPPED": NodeSkipped,
|
|
338
|
-
"NODE_RESTORED": NodeRestored,
|
|
339
|
-
"ERROR": WorkflowError,
|
|
340
|
-
"ARTIFACT_GENERATED": ArtifactGenerated,
|
|
341
|
-
"COUNCIL_VOTE": CouncilVote,
|
|
342
|
-
"EDGE_ACTIVE": EdgeTraversed,
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
data: Any = None
|
|
346
|
-
payload_class = event_class_map.get(event.event_type)
|
|
347
|
-
|
|
348
|
-
if payload_class:
|
|
349
|
-
try:
|
|
350
|
-
# Instantiate the payload object
|
|
351
|
-
payload_obj = payload_class(**payload_dict)
|
|
352
|
-
if isinstance(payload_obj, CloudEventSource):
|
|
353
|
-
data = payload_obj.as_cloud_event_payload()
|
|
354
|
-
else:
|
|
355
|
-
data = payload_obj # pragma: no cover
|
|
356
|
-
except Exception:
|
|
357
|
-
# Fallback if instantiation fails
|
|
358
|
-
data = event.payload
|
|
359
|
-
else:
|
|
360
|
-
data = event.payload
|
|
361
|
-
|
|
362
|
-
# UI Metadata as extension
|
|
363
|
-
extensions = {
|
|
364
|
-
"com_coreason_ui_cue": event.visual_metadata.get("animation") or event.payload.get("visual_cue"),
|
|
365
|
-
"com_coreason_ui_metadata": event.visual_metadata,
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
# Filter out None values in extensions
|
|
369
|
-
# For dictionaries, we want to filter out empty dicts too.
|
|
370
|
-
filtered_extensions = {}
|
|
371
|
-
for k, v in extensions.items():
|
|
372
|
-
if v is None:
|
|
373
|
-
continue
|
|
374
|
-
if isinstance(v, dict) and not v:
|
|
375
|
-
continue
|
|
376
|
-
if isinstance(v, str) and not v:
|
|
377
|
-
continue
|
|
378
|
-
# Also check if it's a dict containing only empty strings (recursive check not needed for now, just 1 level)
|
|
379
|
-
if isinstance(v, dict) and all(isinstance(val, str) and not val for val in v.values()):
|
|
380
|
-
continue
|
|
381
|
-
|
|
382
|
-
filtered_extensions[k] = v
|
|
383
|
-
|
|
384
|
-
extensions = filtered_extensions
|
|
385
|
-
|
|
386
|
-
return CloudEvent(
|
|
387
|
-
type=ce_type,
|
|
388
|
-
source=ce_source,
|
|
389
|
-
time=datetime.fromtimestamp(event.timestamp, timezone.utc),
|
|
390
|
-
data=data,
|
|
391
|
-
**extensions,
|
|
392
|
-
)
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
|
-
from typing import Any, Dict, List, Literal, Optional, Union
|
|
3
|
-
|
|
4
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
5
|
-
|
|
6
|
-
# --- Enums ---
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Role(str, Enum):
|
|
10
|
-
SYSTEM = "system"
|
|
11
|
-
USER = "user"
|
|
12
|
-
ASSISTANT = "assistant"
|
|
13
|
-
TOOL = "tool"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Modality(str, Enum):
|
|
17
|
-
TEXT = "text"
|
|
18
|
-
IMAGE = "image"
|
|
19
|
-
AUDIO = "audio"
|
|
20
|
-
VIDEO = "video"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# --- Message Parts ---
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class TextPart(BaseModel):
|
|
27
|
-
"""Represents text content sent to or received from the model."""
|
|
28
|
-
|
|
29
|
-
model_config = ConfigDict(extra="ignore")
|
|
30
|
-
type: Literal["text"] = "text"
|
|
31
|
-
content: str
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class BlobPart(BaseModel):
|
|
35
|
-
"""Represents blob binary data sent inline to the model."""
|
|
36
|
-
|
|
37
|
-
model_config = ConfigDict(extra="ignore")
|
|
38
|
-
type: Literal["blob"] = "blob"
|
|
39
|
-
content: str # Base64 encoded string
|
|
40
|
-
modality: Modality
|
|
41
|
-
mime_type: Optional[str] = None
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class FilePart(BaseModel):
|
|
45
|
-
"""Represents an external referenced file sent to the model by file id."""
|
|
46
|
-
|
|
47
|
-
model_config = ConfigDict(extra="ignore")
|
|
48
|
-
type: Literal["file"] = "file"
|
|
49
|
-
file_id: str
|
|
50
|
-
modality: Modality
|
|
51
|
-
mime_type: Optional[str] = None
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class UriPart(BaseModel):
|
|
55
|
-
"""Represents an external referenced file sent to the model by URI."""
|
|
56
|
-
|
|
57
|
-
model_config = ConfigDict(extra="ignore")
|
|
58
|
-
type: Literal["uri"] = "uri"
|
|
59
|
-
uri: str
|
|
60
|
-
modality: Modality
|
|
61
|
-
mime_type: Optional[str] = None
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class ToolCallRequestPart(BaseModel):
|
|
65
|
-
"""Represents a tool call requested by the model."""
|
|
66
|
-
|
|
67
|
-
model_config = ConfigDict(extra="ignore")
|
|
68
|
-
type: Literal["tool_call"] = "tool_call"
|
|
69
|
-
name: str
|
|
70
|
-
arguments: Dict[str, Any] # Structured arguments
|
|
71
|
-
id: Optional[str] = None
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
class ToolCallResponsePart(BaseModel):
|
|
75
|
-
"""Represents a tool call result sent to the model."""
|
|
76
|
-
|
|
77
|
-
model_config = ConfigDict(extra="ignore")
|
|
78
|
-
type: Literal["tool_call_response"] = "tool_call_response"
|
|
79
|
-
response: Any # The result of the tool call
|
|
80
|
-
id: Optional[str] = None
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
class ReasoningPart(BaseModel):
|
|
84
|
-
"""Represents reasoning/thinking content received from the model."""
|
|
85
|
-
|
|
86
|
-
model_config = ConfigDict(extra="ignore")
|
|
87
|
-
type: Literal["reasoning"] = "reasoning"
|
|
88
|
-
content: str
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
# --- Union of All Parts ---
|
|
92
|
-
|
|
93
|
-
Part = Union[TextPart, BlobPart, FilePart, UriPart, ToolCallRequestPart, ToolCallResponsePart, ReasoningPart]
|
|
94
|
-
|
|
95
|
-
# --- Main Message Model ---
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class ChatMessage(BaseModel):
|
|
99
|
-
"""Represents a message in a conversation with an LLM."""
|
|
100
|
-
|
|
101
|
-
model_config = ConfigDict(extra="ignore")
|
|
102
|
-
|
|
103
|
-
role: Role
|
|
104
|
-
parts: List[Part] = Field(..., description="List of message parts that make up the message content.")
|
|
105
|
-
name: Optional[str] = None
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
# --- Backward Compatibility ---
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
class FunctionCall(BaseModel):
|
|
112
|
-
"""Deprecated: Use ToolCallRequestPart instead."""
|
|
113
|
-
|
|
114
|
-
name: str
|
|
115
|
-
arguments: str
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
class ToolCall(BaseModel):
|
|
119
|
-
"""Deprecated: Use ToolCallRequestPart instead."""
|
|
120
|
-
|
|
121
|
-
id: str
|
|
122
|
-
type: str = "function"
|
|
123
|
-
function: FunctionCall
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Message = ChatMessage
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from enum import Enum
|
|
3
|
-
from typing import Any, Dict, List
|
|
4
|
-
from uuid import UUID
|
|
5
|
-
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ValidationLogic(str, Enum):
|
|
10
|
-
"""Logic used to validate the scenario outcome."""
|
|
11
|
-
|
|
12
|
-
EXACT_MATCH = "exact_match"
|
|
13
|
-
FUZZY = "fuzzy"
|
|
14
|
-
CODE_EVAL = "code_eval"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class SimulationScenario(BaseModel):
|
|
18
|
-
"""Definition of a simulation scenario."""
|
|
19
|
-
|
|
20
|
-
id: str = Field(..., description="Unique identifier for the scenario.")
|
|
21
|
-
name: str = Field(..., description="Name of the scenario.")
|
|
22
|
-
objective: str = Field(..., description="The prompt/task instructions.")
|
|
23
|
-
difficulty: int = Field(..., description="Difficulty level (1-3, aligning with GAIA levels).", ge=1, le=3)
|
|
24
|
-
expected_outcome: Any = Field(..., description="The ground truth for validation.")
|
|
25
|
-
validation_logic: ValidationLogic = Field(..., description="Logic used to validate the outcome.")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class SimulationStep(BaseModel):
|
|
29
|
-
"""The atomic unit of execution in a simulation."""
|
|
30
|
-
|
|
31
|
-
step_id: UUID = Field(..., description="Atomic unit of execution ID.")
|
|
32
|
-
timestamp: datetime = Field(..., description="Execution timestamp.")
|
|
33
|
-
node_id: str = Field(..., description="The graph node executed.")
|
|
34
|
-
inputs: Dict[str, Any] = Field(..., description="Snapshot of entry state.")
|
|
35
|
-
thought: str = Field(..., description="The Chain-of-Thought reasoning.")
|
|
36
|
-
action: Dict[str, Any] = Field(..., description="Tool calls or API requests.")
|
|
37
|
-
observation: Dict[str, Any] = Field(..., description="Tool outputs.")
|
|
38
|
-
snapshot: Dict[str, Any] = Field(
|
|
39
|
-
default_factory=dict, description="Full copy of the graph state at the completion of this step."
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class SimulationTrace(BaseModel):
|
|
44
|
-
"""Trace of a simulation execution."""
|
|
45
|
-
|
|
46
|
-
trace_id: UUID = Field(..., description="Unique trace identifier.")
|
|
47
|
-
agent_version: str = Field(..., description="Agent SemVer version.")
|
|
48
|
-
steps: List[SimulationStep] = Field(..., description="List of execution steps.")
|
|
49
|
-
outcome: Dict[str, Any] = Field(..., description="Final result.")
|
|
50
|
-
metrics: Dict[str, Any] = Field(..., description="Execution metrics (e.g., token usage, cost).")
|