lionagi 0.7.0__py3-none-any.whl → 0.7.2__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.
- lionagi/operations/ReAct/ReAct.py +2 -2
- lionagi/operations/_act/act.py +10 -3
- lionagi/operations/communicate/communicate.py +0 -59
- lionagi/operations/interpret/interpret.py +1 -2
- lionagi/operations/operate/operate.py +10 -5
- lionagi/operations/parse/parse.py +0 -36
- lionagi/operations/plan/plan.py +3 -3
- lionagi/operatives/action/manager.py +105 -82
- lionagi/operatives/action/request_response_model.py +31 -0
- lionagi/operatives/action/tool.py +50 -20
- lionagi/protocols/_concepts.py +1 -1
- lionagi/protocols/adapters/adapter.py +25 -0
- lionagi/protocols/adapters/json_adapter.py +107 -27
- lionagi/protocols/adapters/pandas_/csv_adapter.py +55 -11
- lionagi/protocols/adapters/pandas_/excel_adapter.py +52 -10
- lionagi/protocols/adapters/pandas_/pd_dataframe_adapter.py +54 -4
- lionagi/protocols/adapters/pandas_/pd_series_adapter.py +40 -0
- lionagi/protocols/generic/element.py +1 -1
- lionagi/protocols/generic/pile.py +5 -8
- lionagi/protocols/graph/edge.py +1 -1
- lionagi/protocols/graph/graph.py +16 -8
- lionagi/protocols/graph/node.py +1 -1
- lionagi/protocols/mail/exchange.py +126 -15
- lionagi/protocols/mail/mail.py +33 -0
- lionagi/protocols/mail/mailbox.py +62 -0
- lionagi/protocols/mail/manager.py +97 -41
- lionagi/protocols/mail/package.py +57 -3
- lionagi/protocols/messages/action_request.py +77 -26
- lionagi/protocols/messages/action_response.py +55 -26
- lionagi/protocols/messages/assistant_response.py +50 -15
- lionagi/protocols/messages/base.py +36 -0
- lionagi/protocols/messages/instruction.py +175 -145
- lionagi/protocols/messages/manager.py +152 -56
- lionagi/protocols/messages/message.py +61 -25
- lionagi/protocols/messages/system.py +54 -19
- lionagi/service/imodel.py +24 -0
- lionagi/session/branch.py +40 -32
- lionagi/utils.py +1 -0
- lionagi/version.py +1 -1
- {lionagi-0.7.0.dist-info → lionagi-0.7.2.dist-info}/METADATA +1 -1
- {lionagi-0.7.0.dist-info → lionagi-0.7.2.dist-info}/RECORD +43 -43
- {lionagi-0.7.0.dist-info → lionagi-0.7.2.dist-info}/WHEEL +0 -0
- {lionagi-0.7.0.dist-info → lionagi-0.7.2.dist-info}/licenses/LICENSE +0 -0
@@ -2,6 +2,11 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
|
5
|
+
"""
|
6
|
+
Defines the `Instruction` class, representing user commands or instructions
|
7
|
+
sent to the system. Supports optional context, images, and schema requests.
|
8
|
+
"""
|
9
|
+
|
5
10
|
from typing import Any, Literal, override
|
6
11
|
|
7
12
|
from pydantic import BaseModel, JsonValue, field_serializer
|
@@ -14,13 +19,14 @@ from .message import RoledMessage, SenderRecipient
|
|
14
19
|
|
15
20
|
def prepare_request_response_format(request_fields: dict) -> str:
|
16
21
|
"""
|
17
|
-
|
22
|
+
Creates a mandated JSON code block for the response
|
23
|
+
based on requested fields.
|
18
24
|
|
19
25
|
Args:
|
20
|
-
request_fields: Dictionary of fields
|
26
|
+
request_fields: Dictionary of fields for the response format.
|
21
27
|
|
22
28
|
Returns:
|
23
|
-
str:
|
29
|
+
str: A string instructing the user to return valid JSON.
|
24
30
|
"""
|
25
31
|
return (
|
26
32
|
"**MUST RETURN JSON-PARSEABLE RESPONSE ENCLOSED BY JSON CODE BLOCKS."
|
@@ -28,35 +34,36 @@ def prepare_request_response_format(request_fields: dict) -> str:
|
|
28
34
|
).strip()
|
29
35
|
|
30
36
|
|
31
|
-
def format_image_item(idx: str,
|
37
|
+
def format_image_item(idx: str, detail: str) -> dict[str, Any]:
|
32
38
|
"""
|
33
|
-
|
39
|
+
Wrap image data in a standard dictionary format.
|
34
40
|
|
35
41
|
Args:
|
36
|
-
idx:
|
37
|
-
|
42
|
+
idx: A base64 image ID or URL reference.
|
43
|
+
detail: The image detail level.
|
38
44
|
|
39
45
|
Returns:
|
40
|
-
dict:
|
46
|
+
dict: A dictionary describing the image.
|
41
47
|
"""
|
42
48
|
return {
|
43
49
|
"type": "image_url",
|
44
50
|
"image_url": {
|
45
51
|
"url": f"data:image/jpeg;base64,{idx}",
|
46
|
-
"detail":
|
52
|
+
"detail": detail,
|
47
53
|
},
|
48
54
|
}
|
49
55
|
|
50
56
|
|
51
57
|
def format_text_item(item: Any) -> str:
|
52
58
|
"""
|
53
|
-
|
59
|
+
Turn a single item (or dict) into a string. If multiple items,
|
60
|
+
combine them line by line.
|
54
61
|
|
55
62
|
Args:
|
56
|
-
item:
|
63
|
+
item: Any item, possibly a list/dict with text data.
|
57
64
|
|
58
65
|
Returns:
|
59
|
-
str:
|
66
|
+
str: Concatenated text lines.
|
60
67
|
"""
|
61
68
|
msg = ""
|
62
69
|
item = [item] if not isinstance(item, list) else item
|
@@ -73,13 +80,14 @@ def format_text_item(item: Any) -> str:
|
|
73
80
|
|
74
81
|
def format_text_content(content: dict) -> str:
|
75
82
|
"""
|
76
|
-
|
83
|
+
Convert a dictionary with keys like 'guidance', 'instruction', 'context', etc.
|
84
|
+
into a readable text block.
|
77
85
|
|
78
86
|
Args:
|
79
|
-
content:
|
87
|
+
content (dict): The content dictionary.
|
80
88
|
|
81
89
|
Returns:
|
82
|
-
str:
|
90
|
+
str: A textual summary.
|
83
91
|
"""
|
84
92
|
if "plain_content" in content and isinstance(
|
85
93
|
content["plain_content"], str
|
@@ -140,17 +148,17 @@ def format_image_content(
|
|
140
148
|
text_content: str,
|
141
149
|
images: list,
|
142
150
|
image_detail: Literal["low", "high", "auto"],
|
143
|
-
) -> dict[str, Any]:
|
151
|
+
) -> list[dict[str, Any]]:
|
144
152
|
"""
|
145
|
-
|
153
|
+
Merge textual content with a list of image dictionaries for consumption.
|
146
154
|
|
147
155
|
Args:
|
148
|
-
text_content: The
|
149
|
-
images:
|
150
|
-
image_detail:
|
156
|
+
text_content (str): The textual portion
|
157
|
+
images (list): A list of base64 or references
|
158
|
+
image_detail (Literal["low","high","auto"]): How detailed the images are
|
151
159
|
|
152
160
|
Returns:
|
153
|
-
dict:
|
161
|
+
list[dict[str,Any]]: A combined structure of text + image dicts.
|
154
162
|
"""
|
155
163
|
content = [{"type": "text", "text": text_content}]
|
156
164
|
content.extend(format_image_item(i, image_detail) for i in images)
|
@@ -169,24 +177,34 @@ def prepare_instruction_content(
|
|
169
177
|
tool_schemas: dict | None = None,
|
170
178
|
) -> dict:
|
171
179
|
"""
|
172
|
-
|
180
|
+
Combine various pieces (instruction, guidance, context, etc.) into
|
181
|
+
a single dictionary describing the user's instruction.
|
173
182
|
|
174
183
|
Args:
|
175
|
-
guidance
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
+
guidance (str | None):
|
185
|
+
Optional guiding text.
|
186
|
+
instruction (str | None):
|
187
|
+
Main instruction or command to be executed.
|
188
|
+
context (str | dict | list | None):
|
189
|
+
Additional context about the environment or previous steps.
|
190
|
+
request_fields (dict | list[str] | None):
|
191
|
+
If the user requests certain fields in the response.
|
192
|
+
plain_content (str | None):
|
193
|
+
A raw plain text fallback.
|
194
|
+
request_model (BaseModel | None):
|
195
|
+
If there's a pydantic model for the request schema.
|
196
|
+
images (str | list | None):
|
197
|
+
Optional images, base64-coded or references.
|
198
|
+
image_detail (str | None):
|
199
|
+
The detail level for images ("low", "high", "auto").
|
200
|
+
tool_schemas (dict | None):
|
201
|
+
Extra data describing available tools.
|
184
202
|
|
185
203
|
Returns:
|
186
|
-
|
204
|
+
dict: The combined instruction content.
|
187
205
|
|
188
206
|
Raises:
|
189
|
-
ValueError: If
|
207
|
+
ValueError: If request_fields and request_model are both given.
|
190
208
|
"""
|
191
209
|
if request_fields and request_model:
|
192
210
|
raise ValueError(
|
@@ -227,10 +245,15 @@ def prepare_instruction_content(
|
|
227
245
|
if plain_content:
|
228
246
|
out_["plain_content"] = plain_content
|
229
247
|
|
248
|
+
# remove keys with None/UNDEFINED
|
230
249
|
return {k: v for k, v in out_.items() if v not in [None, UNDEFINED]}
|
231
250
|
|
232
251
|
|
233
252
|
class Instruction(RoledMessage):
|
253
|
+
"""
|
254
|
+
A user-facing message that conveys commands or tasks. It supports
|
255
|
+
optional images, tool references, and schema-based requests.
|
256
|
+
"""
|
234
257
|
|
235
258
|
@classmethod
|
236
259
|
def create(
|
@@ -247,9 +270,44 @@ class Instruction(RoledMessage):
|
|
247
270
|
image_detail: Literal["low", "high", "auto"] = None,
|
248
271
|
request_model: BaseModel | type[BaseModel] = None,
|
249
272
|
response_format: BaseModel | type[BaseModel] = None,
|
250
|
-
tool_schemas: dict = None,
|
251
|
-
):
|
273
|
+
tool_schemas: list[dict] = None,
|
274
|
+
) -> "Instruction":
|
275
|
+
"""
|
276
|
+
Construct a new Instruction.
|
277
|
+
|
278
|
+
Args:
|
279
|
+
instruction (JsonValue, optional):
|
280
|
+
The main user instruction.
|
281
|
+
context (JsonValue, optional):
|
282
|
+
Additional context or environment info.
|
283
|
+
guidance (JsonValue, optional):
|
284
|
+
Guidance or disclaimers for the instruction.
|
285
|
+
images (list, optional):
|
286
|
+
A set of images relevant to the instruction.
|
287
|
+
request_fields (JsonValue, optional):
|
288
|
+
The fields the user wants in the assistant's response.
|
289
|
+
plain_content (JsonValue, optional):
|
290
|
+
A raw plain text fallback.
|
291
|
+
image_detail ("low"|"high"|"auto", optional):
|
292
|
+
The detail level for included images.
|
293
|
+
request_model (BaseModel|type[BaseModel], optional):
|
294
|
+
A Pydantic schema for the request.
|
295
|
+
response_format (BaseModel|type[BaseModel], optional):
|
296
|
+
Alias for request_model.
|
297
|
+
tool_schemas (list[dict] | dict, optional):
|
298
|
+
Extra tool reference data.
|
299
|
+
sender (SenderRecipient, optional):
|
300
|
+
The sender role or ID.
|
301
|
+
recipient (SenderRecipient, optional):
|
302
|
+
The recipient role or ID.
|
303
|
+
|
304
|
+
Returns:
|
305
|
+
Instruction: A newly created instruction object.
|
252
306
|
|
307
|
+
Raises:
|
308
|
+
ValueError: If more than one of `request_fields`, `request_model`,
|
309
|
+
or `response_format` is passed at once.
|
310
|
+
"""
|
253
311
|
if (
|
254
312
|
sum(
|
255
313
|
bool(i)
|
@@ -281,162 +339,123 @@ class Instruction(RoledMessage):
|
|
281
339
|
|
282
340
|
@property
|
283
341
|
def guidance(self) -> str | None:
|
284
|
-
"""Get the guidance content of the instruction."""
|
285
342
|
return self.content.get("guidance", None)
|
286
343
|
|
287
344
|
@guidance.setter
|
288
345
|
def guidance(self, guidance: str) -> None:
|
289
|
-
"""Set the guidance content of the instruction."""
|
290
346
|
if guidance is None:
|
291
347
|
self.content.pop("guidance", None)
|
292
|
-
|
293
|
-
|
294
|
-
if not isinstance(guidance, str):
|
295
|
-
guidance = str(guidance)
|
296
|
-
self.content["guidance"] = guidance
|
348
|
+
else:
|
349
|
+
self.content["guidance"] = str(guidance)
|
297
350
|
|
298
351
|
@property
|
299
352
|
def instruction(self) -> JsonValue | None:
|
300
|
-
"""Get the main instruction content."""
|
301
353
|
if "plain_content" in self.content:
|
302
354
|
return self.content["plain_content"]
|
303
|
-
|
304
|
-
return self.content.get("instruction", None)
|
355
|
+
return self.content.get("instruction", None)
|
305
356
|
|
306
357
|
@instruction.setter
|
307
|
-
def instruction(self,
|
308
|
-
|
309
|
-
if instruction is None:
|
358
|
+
def instruction(self, val: JsonValue) -> None:
|
359
|
+
if val is None:
|
310
360
|
self.content.pop("instruction", None)
|
311
|
-
|
312
|
-
|
313
|
-
self.content["instruction"] = instruction
|
361
|
+
else:
|
362
|
+
self.content["instruction"] = val
|
314
363
|
|
315
364
|
@property
|
316
365
|
def context(self) -> JsonValue | None:
|
317
|
-
"""Get the context of the instruction."""
|
318
366
|
return self.content.get("context", None)
|
319
367
|
|
320
368
|
@context.setter
|
321
|
-
def context(self,
|
322
|
-
|
323
|
-
if context is None:
|
369
|
+
def context(self, ctx: JsonValue) -> None:
|
370
|
+
if ctx is None:
|
324
371
|
self.content["context"] = []
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
self.content["context"] = context
|
372
|
+
else:
|
373
|
+
self.content["context"] = (
|
374
|
+
list(ctx) if isinstance(ctx, list) else [ctx]
|
375
|
+
)
|
330
376
|
|
331
377
|
@property
|
332
378
|
def tool_schemas(self) -> JsonValue | None:
|
333
|
-
"""Get the schemas of the tools in the instruction."""
|
334
379
|
return self.content.get("tool_schemas", None)
|
335
380
|
|
336
381
|
@tool_schemas.setter
|
337
|
-
def tool_schemas(self,
|
338
|
-
|
339
|
-
if not tool_schemas:
|
382
|
+
def tool_schemas(self, val: list[dict] | dict) -> None:
|
383
|
+
if not val:
|
340
384
|
self.content.pop("tool_schemas", None)
|
341
385
|
return
|
342
|
-
|
343
|
-
self.content["tool_schemas"] = tool_schemas
|
386
|
+
self.content["tool_schemas"] = val
|
344
387
|
|
345
388
|
@property
|
346
389
|
def plain_content(self) -> str | None:
|
347
|
-
"""Get the plain text content of the instruction."""
|
348
390
|
return self.content.get("plain_content", None)
|
349
391
|
|
350
392
|
@plain_content.setter
|
351
|
-
def plain_content(self,
|
352
|
-
""
|
353
|
-
self.content["plain_content"] = plain_content
|
393
|
+
def plain_content(self, pc: str) -> None:
|
394
|
+
self.content["plain_content"] = pc
|
354
395
|
|
355
396
|
@property
|
356
397
|
def image_detail(self) -> Literal["low", "high", "auto"] | None:
|
357
|
-
"""Get the image detail level of the instruction."""
|
358
398
|
return self.content.get("image_detail", None)
|
359
399
|
|
360
400
|
@image_detail.setter
|
361
|
-
def image_detail(
|
362
|
-
self
|
363
|
-
) -> None:
|
364
|
-
"""Set the image detail level of the instruction."""
|
365
|
-
self.content["image_detail"] = image_detail
|
401
|
+
def image_detail(self, detail: Literal["low", "high", "auto"]) -> None:
|
402
|
+
self.content["image_detail"] = detail
|
366
403
|
|
367
404
|
@property
|
368
405
|
def images(self) -> list:
|
369
|
-
"""Get the images associated with the instruction."""
|
370
406
|
return self.content.get("images", [])
|
371
407
|
|
372
408
|
@images.setter
|
373
|
-
def images(self,
|
374
|
-
""
|
375
|
-
if not isinstance(images, list):
|
376
|
-
images = [images]
|
377
|
-
self.content["images"] = images
|
409
|
+
def images(self, imgs: list) -> None:
|
410
|
+
self.content["images"] = imgs if isinstance(imgs, list) else [imgs]
|
378
411
|
|
379
412
|
@property
|
380
413
|
def request_fields(self) -> dict | None:
|
381
|
-
"""Get the requested fields in the instruction."""
|
382
414
|
return self.content.get("request_fields", None)
|
383
415
|
|
384
416
|
@request_fields.setter
|
385
|
-
def request_fields(self,
|
386
|
-
""
|
387
|
-
self.content["request_fields"] = request_fields
|
417
|
+
def request_fields(self, fields: dict) -> None:
|
418
|
+
self.content["request_fields"] = fields
|
388
419
|
self.content["request_response_format"] = (
|
389
|
-
prepare_request_response_format(
|
420
|
+
prepare_request_response_format(fields)
|
390
421
|
)
|
391
422
|
|
392
423
|
@property
|
393
424
|
def response_format(self) -> type[BaseModel] | None:
|
394
|
-
"""Get the request model of the instruction."""
|
395
425
|
return self.content.get("request_model", None)
|
396
426
|
|
397
427
|
@response_format.setter
|
398
|
-
def response_format(self,
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
This also updates request fields and context based on the model.
|
403
|
-
"""
|
404
|
-
if isinstance(request_model, BaseModel):
|
405
|
-
self.content["request_model"] = type(request_model)
|
428
|
+
def response_format(self, model: type[BaseModel]) -> None:
|
429
|
+
if isinstance(model, BaseModel):
|
430
|
+
self.content["request_model"] = type(model)
|
406
431
|
else:
|
407
|
-
self.content["request_model"] =
|
432
|
+
self.content["request_model"] = model
|
408
433
|
|
409
434
|
self.request_fields = {}
|
410
|
-
self.extend_context(
|
411
|
-
|
412
|
-
)
|
413
|
-
self.request_fields = breakdown_pydantic_annotation(request_model)
|
435
|
+
self.extend_context(respond_schema_info=model.model_json_schema())
|
436
|
+
self.request_fields = breakdown_pydantic_annotation(model)
|
414
437
|
|
415
438
|
@property
|
416
439
|
def respond_schema_info(self) -> dict | None:
|
417
|
-
"""Get the response schema information."""
|
418
440
|
return self.content.get("respond_schema_info", None)
|
419
441
|
|
420
442
|
@respond_schema_info.setter
|
421
|
-
def respond_schema_info(self,
|
422
|
-
|
423
|
-
if respond_schema_info is None:
|
443
|
+
def respond_schema_info(self, info: dict) -> None:
|
444
|
+
if info is None:
|
424
445
|
self.content.pop("respond_schema_info", None)
|
425
446
|
else:
|
426
|
-
self.content["respond_schema_info"] =
|
447
|
+
self.content["respond_schema_info"] = info
|
427
448
|
|
428
449
|
@property
|
429
450
|
def request_response_format(self) -> str | None:
|
430
|
-
"""Get the request response format."""
|
431
451
|
return self.content.get("request_response_format", None)
|
432
452
|
|
433
453
|
@request_response_format.setter
|
434
|
-
def request_response_format(self,
|
435
|
-
|
436
|
-
if not request_response_format:
|
454
|
+
def request_response_format(self, val: str) -> None:
|
455
|
+
if not val:
|
437
456
|
self.content.pop("request_response_format", None)
|
438
457
|
else:
|
439
|
-
self.content["request_response_format"] =
|
458
|
+
self.content["request_response_format"] = val
|
440
459
|
|
441
460
|
def extend_images(
|
442
461
|
self,
|
@@ -444,38 +463,34 @@ class Instruction(RoledMessage):
|
|
444
463
|
image_detail: Literal["low", "high", "auto"] = None,
|
445
464
|
) -> None:
|
446
465
|
"""
|
447
|
-
|
466
|
+
Append images to the existing list.
|
448
467
|
|
449
468
|
Args:
|
450
|
-
images:
|
451
|
-
image_detail:
|
469
|
+
images: The new images to add, a single or multiple.
|
470
|
+
image_detail: If provided, updates the image detail field.
|
452
471
|
"""
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
self.images = _ima
|
457
|
-
|
472
|
+
arr: list = self.images
|
473
|
+
arr.extend(images if isinstance(images, list) else [images])
|
474
|
+
self.images = arr
|
458
475
|
if image_detail:
|
459
476
|
self.image_detail = image_detail
|
460
477
|
|
461
478
|
def extend_context(self, *args, **kwargs) -> None:
|
462
479
|
"""
|
463
|
-
|
480
|
+
Append additional context to the existing context array.
|
464
481
|
|
465
482
|
Args:
|
466
|
-
*args: Positional
|
467
|
-
**kwargs:
|
483
|
+
*args: Positional args are appended as list items.
|
484
|
+
**kwargs: Key-value pairs are appended as separate dict items.
|
468
485
|
"""
|
469
|
-
|
470
|
-
|
486
|
+
ctx: list = self.context or []
|
471
487
|
if args:
|
472
|
-
|
488
|
+
ctx.extend(args)
|
473
489
|
if kwargs:
|
474
|
-
|
475
|
-
for k, v in
|
476
|
-
|
477
|
-
|
478
|
-
self.context = context
|
490
|
+
kw = copy(kwargs)
|
491
|
+
for k, v in kw.items():
|
492
|
+
ctx.append({k: v})
|
493
|
+
self.context = ctx
|
479
494
|
|
480
495
|
def update(
|
481
496
|
self,
|
@@ -494,22 +509,23 @@ class Instruction(RoledMessage):
|
|
494
509
|
recipient: SenderRecipient = None,
|
495
510
|
):
|
496
511
|
"""
|
497
|
-
|
512
|
+
Batch-update this Instruction.
|
498
513
|
|
499
514
|
Args:
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
images:
|
507
|
-
image_detail:
|
508
|
-
tool_schemas: New tool schemas
|
509
|
-
|
515
|
+
guidance (JsonValue): New guidance text.
|
516
|
+
instruction (JsonValue): Main user instruction.
|
517
|
+
request_fields (JsonValue): Updated request fields.
|
518
|
+
plain_content (JsonValue): Plain text fallback.
|
519
|
+
request_model (BaseModel|type[BaseModel]): Pydantic schema model.
|
520
|
+
response_format (BaseModel|type[BaseModel]): Alias for request_model.
|
521
|
+
images (list|str): Additional images to add.
|
522
|
+
image_detail ("low"|"high"|"auto"): Image detail level.
|
523
|
+
tool_schemas (dict): New tool schemas.
|
524
|
+
sender (SenderRecipient): New sender.
|
525
|
+
recipient (SenderRecipient): New recipient.
|
510
526
|
|
511
527
|
Raises:
|
512
|
-
ValueError: If
|
528
|
+
ValueError: If request_model and request_fields are both set.
|
513
529
|
"""
|
514
530
|
if response_format and request_model:
|
515
531
|
raise ValueError(
|
@@ -559,8 +575,14 @@ class Instruction(RoledMessage):
|
|
559
575
|
|
560
576
|
@override
|
561
577
|
@property
|
562
|
-
def rendered(self) ->
|
563
|
-
"""
|
578
|
+
def rendered(self) -> Any:
|
579
|
+
"""
|
580
|
+
Convert content into a text or combined text+image structure.
|
581
|
+
|
582
|
+
Returns:
|
583
|
+
If no images are included, returns a single text block.
|
584
|
+
Otherwise returns an array of text + image dicts.
|
585
|
+
"""
|
564
586
|
content = copy(self.content)
|
565
587
|
text_content = format_text_content(content)
|
566
588
|
if "images" not in content:
|
@@ -575,8 +597,16 @@ class Instruction(RoledMessage):
|
|
575
597
|
|
576
598
|
@field_serializer("content")
|
577
599
|
def _serialize_content(self, values) -> dict:
|
578
|
-
"""
|
600
|
+
"""
|
601
|
+
Remove certain ephemeral fields before saving.
|
602
|
+
|
603
|
+
Returns:
|
604
|
+
dict: The sanitized content dictionary.
|
605
|
+
"""
|
579
606
|
values.pop("request_model", None)
|
580
607
|
values.pop("request_fields", None)
|
581
608
|
|
582
609
|
return values
|
610
|
+
|
611
|
+
|
612
|
+
# File: lionagi/protocols/messages/instruction.py
|