jaf-py 2.4.1__py3-none-any.whl → 2.4.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.
- jaf/__init__.py +15 -0
- jaf/core/agent_tool.py +6 -4
- jaf/core/analytics.py +4 -3
- jaf/core/engine.py +401 -37
- jaf/core/state.py +156 -0
- jaf/core/tracing.py +114 -23
- jaf/core/types.py +113 -3
- jaf/memory/approval_storage.py +306 -0
- jaf/memory/types.py +1 -0
- jaf/memory/utils.py +1 -1
- jaf/providers/model.py +277 -17
- jaf/server/__init__.py +2 -0
- jaf/server/server.py +665 -22
- jaf/server/types.py +149 -4
- jaf/utils/__init__.py +50 -0
- jaf/utils/attachments.py +401 -0
- jaf/utils/document_processor.py +561 -0
- {jaf_py-2.4.1.dist-info → jaf_py-2.4.2.dist-info}/METADATA +10 -2
- {jaf_py-2.4.1.dist-info → jaf_py-2.4.2.dist-info}/RECORD +23 -18
- {jaf_py-2.4.1.dist-info → jaf_py-2.4.2.dist-info}/WHEEL +0 -0
- {jaf_py-2.4.1.dist-info → jaf_py-2.4.2.dist-info}/entry_points.txt +0 -0
- {jaf_py-2.4.1.dist-info → jaf_py-2.4.2.dist-info}/licenses/LICENSE +0 -0
- {jaf_py-2.4.1.dist-info → jaf_py-2.4.2.dist-info}/top_level.txt +0 -0
jaf/__init__.py
CHANGED
|
@@ -16,6 +16,21 @@ from .core.tools import (
|
|
|
16
16
|
)
|
|
17
17
|
from .core.tracing import ConsoleTraceCollector, TraceCollector
|
|
18
18
|
from .core.types import *
|
|
19
|
+
# Import attachment utilities for convenience
|
|
20
|
+
from .utils.attachments import (
|
|
21
|
+
make_image_attachment,
|
|
22
|
+
make_file_attachment,
|
|
23
|
+
make_document_attachment,
|
|
24
|
+
validate_attachment,
|
|
25
|
+
AttachmentValidationError,
|
|
26
|
+
)
|
|
27
|
+
from .utils.document_processor import (
|
|
28
|
+
extract_document_content,
|
|
29
|
+
is_document_supported,
|
|
30
|
+
get_document_description,
|
|
31
|
+
ProcessedDocument,
|
|
32
|
+
DocumentProcessingError,
|
|
33
|
+
)
|
|
19
34
|
from .exceptions import (
|
|
20
35
|
A2AException,
|
|
21
36
|
A2AProtocolError,
|
jaf/core/agent_tool.py
CHANGED
|
@@ -27,6 +27,7 @@ from .types import (
|
|
|
27
27
|
RunState,
|
|
28
28
|
RunResult,
|
|
29
29
|
Message,
|
|
30
|
+
get_text_content,
|
|
30
31
|
ContentRole,
|
|
31
32
|
generate_run_id,
|
|
32
33
|
generate_trace_id,
|
|
@@ -201,12 +202,13 @@ def create_agent_tool(
|
|
|
201
202
|
return str(result.outcome.output)
|
|
202
203
|
else:
|
|
203
204
|
# Fall back to the last assistant message
|
|
205
|
+
from .types import get_text_content
|
|
204
206
|
assistant_messages = [
|
|
205
207
|
msg for msg in result.final_state.messages
|
|
206
|
-
if msg.role == ContentRole.ASSISTANT and msg.content
|
|
208
|
+
if msg.role == ContentRole.ASSISTANT and get_text_content(msg.content)
|
|
207
209
|
]
|
|
208
210
|
if assistant_messages:
|
|
209
|
-
return assistant_messages[-1].content
|
|
211
|
+
return get_text_content(assistant_messages[-1].content)
|
|
210
212
|
return "Agent completed successfully but produced no output"
|
|
211
213
|
else:
|
|
212
214
|
# Error case
|
|
@@ -278,8 +280,8 @@ def create_json_output_extractor() -> Callable[[RunResult], str]:
|
|
|
278
280
|
def json_extractor(run_result: RunResult) -> str:
|
|
279
281
|
# Scan the agent's outputs in reverse order until we find a JSON-like message
|
|
280
282
|
for message in reversed(run_result.final_state.messages):
|
|
281
|
-
if message.role == ContentRole.ASSISTANT and message.content:
|
|
282
|
-
content = message.content.strip()
|
|
283
|
+
if message.role == ContentRole.ASSISTANT and get_text_content(message.content):
|
|
284
|
+
content = get_text_content(message.content).strip()
|
|
283
285
|
if content.startswith('{') or content.startswith('['):
|
|
284
286
|
try:
|
|
285
287
|
# Validate it's proper JSON
|
jaf/core/analytics.py
CHANGED
|
@@ -12,7 +12,7 @@ from typing import Dict, List, Optional, Any, Tuple, Set
|
|
|
12
12
|
from collections import defaultdict, Counter
|
|
13
13
|
from datetime import datetime, timedelta
|
|
14
14
|
|
|
15
|
-
from .types import Message, ContentRole, RunState, TraceEvent
|
|
15
|
+
from .types import Message, ContentRole, RunState, TraceEvent, get_text_content
|
|
16
16
|
from .performance import PerformanceMetrics
|
|
17
17
|
|
|
18
18
|
|
|
@@ -129,10 +129,11 @@ class ConversationAnalyzer:
|
|
|
129
129
|
total_words = 0
|
|
130
130
|
|
|
131
131
|
for message in messages:
|
|
132
|
-
|
|
132
|
+
content_text = get_text_content(message.content)
|
|
133
|
+
if not content_text:
|
|
133
134
|
continue
|
|
134
135
|
|
|
135
|
-
words =
|
|
136
|
+
words = content_text.lower().split()
|
|
136
137
|
total_words += len(words)
|
|
137
138
|
|
|
138
139
|
for word in words:
|