openai-sdk-helpers 0.0.5__py3-none-any.whl → 0.0.6__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.
- openai_sdk_helpers/__init__.py +62 -0
- openai_sdk_helpers/agent/__init__.py +31 -0
- openai_sdk_helpers/agent/base.py +330 -0
- openai_sdk_helpers/agent/config.py +66 -0
- openai_sdk_helpers/agent/project_manager.py +511 -0
- openai_sdk_helpers/agent/prompt_utils.py +9 -0
- openai_sdk_helpers/agent/runner.py +215 -0
- openai_sdk_helpers/agent/summarizer.py +85 -0
- openai_sdk_helpers/agent/translator.py +139 -0
- openai_sdk_helpers/agent/utils.py +47 -0
- openai_sdk_helpers/agent/validation.py +97 -0
- openai_sdk_helpers/agent/vector_search.py +462 -0
- openai_sdk_helpers/agent/web_search.py +404 -0
- openai_sdk_helpers/config.py +153 -0
- openai_sdk_helpers/enums/__init__.py +7 -0
- openai_sdk_helpers/enums/base.py +29 -0
- openai_sdk_helpers/environment.py +27 -0
- openai_sdk_helpers/prompt/__init__.py +77 -0
- openai_sdk_helpers/py.typed +0 -0
- openai_sdk_helpers/response/__init__.py +18 -0
- openai_sdk_helpers/response/base.py +501 -0
- openai_sdk_helpers/response/messages.py +211 -0
- openai_sdk_helpers/response/runner.py +104 -0
- openai_sdk_helpers/response/tool_call.py +70 -0
- openai_sdk_helpers/structure/__init__.py +43 -0
- openai_sdk_helpers/structure/agent_blueprint.py +224 -0
- openai_sdk_helpers/structure/base.py +713 -0
- openai_sdk_helpers/structure/plan/__init__.py +13 -0
- openai_sdk_helpers/structure/plan/enum.py +64 -0
- openai_sdk_helpers/structure/plan/plan.py +253 -0
- openai_sdk_helpers/structure/plan/task.py +122 -0
- openai_sdk_helpers/structure/prompt.py +24 -0
- openai_sdk_helpers/structure/responses.py +132 -0
- openai_sdk_helpers/structure/summary.py +65 -0
- openai_sdk_helpers/structure/validation.py +47 -0
- openai_sdk_helpers/structure/vector_search.py +86 -0
- openai_sdk_helpers/structure/web_search.py +46 -0
- openai_sdk_helpers/utils/__init__.py +13 -0
- openai_sdk_helpers/utils/core.py +208 -0
- openai_sdk_helpers/vector_storage/__init__.py +15 -0
- openai_sdk_helpers/vector_storage/cleanup.py +91 -0
- openai_sdk_helpers/vector_storage/storage.py +501 -0
- openai_sdk_helpers/vector_storage/types.py +58 -0
- {openai_sdk_helpers-0.0.5.dist-info → openai_sdk_helpers-0.0.6.dist-info}/METADATA +1 -1
- openai_sdk_helpers-0.0.6.dist-info/RECORD +50 -0
- openai_sdk_helpers-0.0.5.dist-info/RECORD +0 -7
- {openai_sdk_helpers-0.0.5.dist-info → openai_sdk_helpers-0.0.6.dist-info}/WHEEL +0 -0
- {openai_sdk_helpers-0.0.5.dist-info → openai_sdk_helpers-0.0.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""Convenience wrappers for running OpenAI agents.
|
|
2
|
+
|
|
3
|
+
These helpers provide a narrow surface around the lower-level functions in
|
|
4
|
+
``openai-sdk-helpers.agent.base`` so that callers can execute agents with consistent
|
|
5
|
+
signatures whether they need asynchronous, synchronous, or streamed results.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Any, Dict, Optional
|
|
11
|
+
import asyncio
|
|
12
|
+
import threading
|
|
13
|
+
from agents import Agent, Runner, RunResult, RunResultStreaming
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def _run_async(
|
|
17
|
+
agent: Agent,
|
|
18
|
+
input: str,
|
|
19
|
+
context: Optional[Dict[str, Any]] = None,
|
|
20
|
+
output_type: Optional[Any] = None,
|
|
21
|
+
) -> Any:
|
|
22
|
+
"""Run an ``Agent`` asynchronously.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
agent
|
|
27
|
+
Configured agent instance to execute.
|
|
28
|
+
input
|
|
29
|
+
Prompt or query string for the agent.
|
|
30
|
+
context
|
|
31
|
+
Optional context dictionary passed to the agent. Default ``None``.
|
|
32
|
+
output_type
|
|
33
|
+
Optional type used to cast the final output. Default ``None``.
|
|
34
|
+
|
|
35
|
+
Returns
|
|
36
|
+
-------
|
|
37
|
+
Any
|
|
38
|
+
Agent response, optionally converted to ``output_type``.
|
|
39
|
+
"""
|
|
40
|
+
result = await Runner.run(agent, input, context=context)
|
|
41
|
+
if output_type is not None:
|
|
42
|
+
result = result.final_output_as(output_type)
|
|
43
|
+
return result
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _run_sync(
|
|
47
|
+
agent: Agent,
|
|
48
|
+
input: str,
|
|
49
|
+
context: Optional[Dict[str, Any]] = None,
|
|
50
|
+
) -> RunResult:
|
|
51
|
+
"""Run an ``Agent`` synchronously.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
agent
|
|
56
|
+
Configured agent instance to execute.
|
|
57
|
+
input
|
|
58
|
+
Prompt or query string for the agent.
|
|
59
|
+
context
|
|
60
|
+
Optional context dictionary passed to the agent. Default ``None``.
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
RunResult
|
|
65
|
+
Result from the agent execution.
|
|
66
|
+
"""
|
|
67
|
+
coro = Runner.run(agent, input, context=context)
|
|
68
|
+
try:
|
|
69
|
+
loop = asyncio.get_running_loop()
|
|
70
|
+
except RuntimeError:
|
|
71
|
+
return asyncio.run(coro)
|
|
72
|
+
|
|
73
|
+
if loop.is_running():
|
|
74
|
+
result: RunResult | None = None
|
|
75
|
+
|
|
76
|
+
def _thread_runner() -> None:
|
|
77
|
+
nonlocal result
|
|
78
|
+
result = asyncio.run(coro)
|
|
79
|
+
|
|
80
|
+
thread = threading.Thread(target=_thread_runner, daemon=True)
|
|
81
|
+
thread.start()
|
|
82
|
+
thread.join()
|
|
83
|
+
if result is None:
|
|
84
|
+
raise RuntimeError("Agent execution did not return a result.")
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
return loop.run_until_complete(coro)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _run_streamed(
|
|
91
|
+
agent: Agent,
|
|
92
|
+
input: str,
|
|
93
|
+
context: Optional[Dict[str, Any]] = None,
|
|
94
|
+
) -> RunResultStreaming:
|
|
95
|
+
"""Run an ``Agent`` synchronously and return a streaming result.
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
agent
|
|
100
|
+
Configured agent to execute.
|
|
101
|
+
input
|
|
102
|
+
Prompt or query string for the agent.
|
|
103
|
+
context
|
|
104
|
+
Optional context dictionary passed to the agent. Default ``None``.
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
RunResultStreaming
|
|
109
|
+
Instance for streaming outputs.
|
|
110
|
+
"""
|
|
111
|
+
result = Runner.run_streamed(agent, input, context=context)
|
|
112
|
+
return result
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
async def run_async(
|
|
116
|
+
agent: Agent,
|
|
117
|
+
input: str,
|
|
118
|
+
context: Optional[Dict[str, Any]] = None,
|
|
119
|
+
output_type: Optional[Any] = None,
|
|
120
|
+
) -> Any:
|
|
121
|
+
"""Run an ``Agent`` asynchronously.
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
agent
|
|
126
|
+
Configured agent instance to execute.
|
|
127
|
+
input
|
|
128
|
+
Prompt or query string for the agent.
|
|
129
|
+
context
|
|
130
|
+
Optional context dictionary passed to the agent. Default ``None``.
|
|
131
|
+
output_type
|
|
132
|
+
Optional type used to cast the final output. Default ``None``.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
Any
|
|
137
|
+
Agent response, optionally converted to ``output_type``.
|
|
138
|
+
"""
|
|
139
|
+
return await _run_async(
|
|
140
|
+
agent=agent,
|
|
141
|
+
input=input,
|
|
142
|
+
context=context,
|
|
143
|
+
output_type=output_type,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def run_sync(
|
|
148
|
+
agent: Agent,
|
|
149
|
+
input: str,
|
|
150
|
+
context: Optional[Dict[str, Any]] = None,
|
|
151
|
+
output_type: Optional[Any] = None,
|
|
152
|
+
) -> Any:
|
|
153
|
+
"""Run an ``Agent`` synchronously.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
agent
|
|
158
|
+
Configured agent instance to execute.
|
|
159
|
+
input
|
|
160
|
+
Prompt or query string for the agent.
|
|
161
|
+
context
|
|
162
|
+
Optional context dictionary passed to the agent. Default ``None``.
|
|
163
|
+
output_type
|
|
164
|
+
Optional type used to cast the final output. Default ``None``.
|
|
165
|
+
|
|
166
|
+
Returns
|
|
167
|
+
-------
|
|
168
|
+
Any
|
|
169
|
+
Agent response, optionally converted to ``output_type``.
|
|
170
|
+
"""
|
|
171
|
+
result: RunResult = _run_sync(
|
|
172
|
+
agent=agent,
|
|
173
|
+
input=input,
|
|
174
|
+
context=context,
|
|
175
|
+
)
|
|
176
|
+
if output_type:
|
|
177
|
+
return result.final_output_as(output_type)
|
|
178
|
+
return result
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def run_streamed(
|
|
182
|
+
agent: Agent,
|
|
183
|
+
input: str,
|
|
184
|
+
context: Optional[Dict[str, Any]] = None,
|
|
185
|
+
output_type: Optional[Any] = None,
|
|
186
|
+
) -> RunResultStreaming:
|
|
187
|
+
"""Run an ``Agent`` and return a streaming result.
|
|
188
|
+
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
agent
|
|
192
|
+
Configured agent instance to execute.
|
|
193
|
+
input
|
|
194
|
+
Prompt or query string for the agent.
|
|
195
|
+
context
|
|
196
|
+
Optional context dictionary passed to the agent. Default ``None``.
|
|
197
|
+
output_type
|
|
198
|
+
Optional type used to cast the final output. Default ``None``.
|
|
199
|
+
|
|
200
|
+
Returns
|
|
201
|
+
-------
|
|
202
|
+
RunResultStreaming
|
|
203
|
+
Streaming output wrapper from the agent execution.
|
|
204
|
+
"""
|
|
205
|
+
result = _run_streamed(
|
|
206
|
+
agent=agent,
|
|
207
|
+
input=input,
|
|
208
|
+
context=context,
|
|
209
|
+
)
|
|
210
|
+
if output_type:
|
|
211
|
+
return result.final_output_as(output_type)
|
|
212
|
+
return result
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
__all__ = ["run_sync", "run_async", "run_streamed"]
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Lightweight agent for summarizing text."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, Optional
|
|
7
|
+
|
|
8
|
+
from ..structure import SummaryStructure
|
|
9
|
+
from .base import AgentBase
|
|
10
|
+
from .config import AgentConfig
|
|
11
|
+
from .prompt_utils import DEFAULT_PROMPT_DIR
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SummarizerAgent(AgentBase):
|
|
15
|
+
"""Generate concise summaries from provided text.
|
|
16
|
+
|
|
17
|
+
Methods
|
|
18
|
+
-------
|
|
19
|
+
run_agent(text, metadata)
|
|
20
|
+
Summarize the supplied text with optional metadata context.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
*,
|
|
26
|
+
prompt_dir: Optional[Path] = None,
|
|
27
|
+
default_model: Optional[str] = None,
|
|
28
|
+
output_type: type[Any] = SummaryStructure,
|
|
29
|
+
) -> None:
|
|
30
|
+
"""Initialize the summarizer agent configuration.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
prompt_dir : pathlib.Path or None, default=None
|
|
35
|
+
Optional directory containing Jinja prompt templates. Defaults to the
|
|
36
|
+
packaged ``prompt`` directory when not provided.
|
|
37
|
+
default_model : str or None, default=None
|
|
38
|
+
Fallback model identifier when not specified elsewhere.
|
|
39
|
+
output_type : type, default=SummaryStructure
|
|
40
|
+
Type describing the expected summary output.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
None
|
|
45
|
+
"""
|
|
46
|
+
config = AgentConfig(
|
|
47
|
+
name="summarizer",
|
|
48
|
+
description="Summarize passages into concise findings.",
|
|
49
|
+
output_type=output_type,
|
|
50
|
+
)
|
|
51
|
+
prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
|
|
52
|
+
super().__init__(
|
|
53
|
+
config=config, prompt_dir=prompt_directory, default_model=default_model
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
async def run_agent(
|
|
57
|
+
self, text: str, metadata: Optional[Dict[str, Any]] = None
|
|
58
|
+
) -> Any:
|
|
59
|
+
"""Return a summary for ``text``.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
text : str
|
|
64
|
+
Source content to summarize.
|
|
65
|
+
metadata : dict, optional
|
|
66
|
+
Additional metadata to include in the prompt context. Default ``None``.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
Any
|
|
71
|
+
Structured summary produced by the agent.
|
|
72
|
+
"""
|
|
73
|
+
context: Optional[Dict[str, Any]] = None
|
|
74
|
+
if metadata:
|
|
75
|
+
context = {"metadata": metadata}
|
|
76
|
+
|
|
77
|
+
result = await self.run_async(
|
|
78
|
+
input=text,
|
|
79
|
+
context=context,
|
|
80
|
+
output_type=self._output_type,
|
|
81
|
+
)
|
|
82
|
+
return result
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
__all__ = ["SummarizerAgent"]
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""Lightweight agent for translating text into a target language."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, Optional
|
|
7
|
+
|
|
8
|
+
from .base import AgentBase
|
|
9
|
+
from .config import AgentConfig
|
|
10
|
+
from .prompt_utils import DEFAULT_PROMPT_DIR
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TranslatorAgent(AgentBase):
|
|
14
|
+
"""Translate text into a target language.
|
|
15
|
+
|
|
16
|
+
Methods
|
|
17
|
+
-------
|
|
18
|
+
run_agent(text, target_language, context)
|
|
19
|
+
Translate the supplied text into the target language.
|
|
20
|
+
run_sync(text, target_language, context)
|
|
21
|
+
Translate the supplied text synchronously.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
*,
|
|
27
|
+
prompt_dir: Optional[Path] = None,
|
|
28
|
+
default_model: Optional[str] = None,
|
|
29
|
+
) -> None:
|
|
30
|
+
"""Initialize the translation agent configuration.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
prompt_dir : pathlib.Path or None, default=None
|
|
35
|
+
Optional directory containing Jinja prompt templates. Defaults to the
|
|
36
|
+
packaged ``prompt`` directory when not provided.
|
|
37
|
+
default_model : str or None, default=None
|
|
38
|
+
Fallback model identifier when not specified elsewhere.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
None
|
|
43
|
+
"""
|
|
44
|
+
config = AgentConfig(
|
|
45
|
+
name="translator",
|
|
46
|
+
description="Translate text into the requested language.",
|
|
47
|
+
output_type=str,
|
|
48
|
+
)
|
|
49
|
+
prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
|
|
50
|
+
super().__init__(
|
|
51
|
+
config=config, prompt_dir=prompt_directory, default_model=default_model
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
async def run_agent(
|
|
55
|
+
self,
|
|
56
|
+
text: str,
|
|
57
|
+
target_language: str,
|
|
58
|
+
context: Optional[Dict[str, Any]] = None,
|
|
59
|
+
) -> str:
|
|
60
|
+
"""Translate ``text`` to ``target_language``.
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
text : str
|
|
65
|
+
Source content to translate.
|
|
66
|
+
target_language : str
|
|
67
|
+
Language to translate the content into.
|
|
68
|
+
context : dict, optional
|
|
69
|
+
Additional context values to merge into the prompt. Default ``None``.
|
|
70
|
+
|
|
71
|
+
Returns
|
|
72
|
+
-------
|
|
73
|
+
str
|
|
74
|
+
Translated text returned by the agent.
|
|
75
|
+
"""
|
|
76
|
+
template_context: Dict[str, Any] = {"target_language": target_language}
|
|
77
|
+
if context:
|
|
78
|
+
template_context.update(context)
|
|
79
|
+
|
|
80
|
+
result: str = await self.run_async(
|
|
81
|
+
input=text,
|
|
82
|
+
context=template_context,
|
|
83
|
+
output_type=str,
|
|
84
|
+
)
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
def run_sync(
|
|
88
|
+
self,
|
|
89
|
+
input: str,
|
|
90
|
+
context: Optional[Dict[str, Any]] = None,
|
|
91
|
+
output_type: Optional[Any] = None,
|
|
92
|
+
*,
|
|
93
|
+
target_language: Optional[str] = None,
|
|
94
|
+
**kwargs: Any,
|
|
95
|
+
) -> str:
|
|
96
|
+
"""Translate ``input`` to ``target_language`` synchronously.
|
|
97
|
+
|
|
98
|
+
Parameters
|
|
99
|
+
----------
|
|
100
|
+
input : str
|
|
101
|
+
Source content to translate.
|
|
102
|
+
context : dict, optional
|
|
103
|
+
Additional context values to merge into the prompt. Default ``None``.
|
|
104
|
+
output_type : type or None, optional
|
|
105
|
+
Optional output type cast for the response. Default ``None``.
|
|
106
|
+
target_language : str, optional
|
|
107
|
+
Target language to translate the content into. Required unless supplied
|
|
108
|
+
within ``context`` or ``kwargs``.
|
|
109
|
+
**kwargs
|
|
110
|
+
Optional keyword arguments. ``context`` is accepted as an alias for
|
|
111
|
+
``context`` for backward compatibility.
|
|
112
|
+
|
|
113
|
+
Returns
|
|
114
|
+
-------
|
|
115
|
+
str
|
|
116
|
+
Translated text returned by the agent.
|
|
117
|
+
"""
|
|
118
|
+
merged_context: Dict[str, Any] = {}
|
|
119
|
+
|
|
120
|
+
if context:
|
|
121
|
+
merged_context.update(context)
|
|
122
|
+
if "context" in kwargs and kwargs["context"]:
|
|
123
|
+
merged_context.update(kwargs["context"])
|
|
124
|
+
if target_language:
|
|
125
|
+
merged_context["target_language"] = target_language
|
|
126
|
+
|
|
127
|
+
if "target_language" not in merged_context:
|
|
128
|
+
msg = "target_language is required for translation"
|
|
129
|
+
raise ValueError(msg)
|
|
130
|
+
|
|
131
|
+
result: str = super().run_sync(
|
|
132
|
+
input=input,
|
|
133
|
+
context=merged_context,
|
|
134
|
+
output_type=output_type or str,
|
|
135
|
+
)
|
|
136
|
+
return result
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
__all__ = ["TranslatorAgent"]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Utility helpers for synchronous interaction with async agents."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import threading
|
|
7
|
+
from typing import Any, Coroutine, TypeVar
|
|
8
|
+
|
|
9
|
+
T = TypeVar("T")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def run_coroutine_agent_sync(coro: Coroutine[Any, Any, T]) -> T:
|
|
13
|
+
"""Run a coroutine from synchronous code.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
coro : Coroutine[Any, Any, T]
|
|
18
|
+
Coroutine to execute.
|
|
19
|
+
|
|
20
|
+
Returns
|
|
21
|
+
-------
|
|
22
|
+
T
|
|
23
|
+
Result returned by the coroutine.
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
loop = asyncio.get_running_loop()
|
|
27
|
+
except RuntimeError:
|
|
28
|
+
return asyncio.run(coro)
|
|
29
|
+
|
|
30
|
+
if loop.is_running():
|
|
31
|
+
result: T | None = None
|
|
32
|
+
|
|
33
|
+
def _thread_runner() -> None:
|
|
34
|
+
nonlocal result
|
|
35
|
+
result = asyncio.run(coro)
|
|
36
|
+
|
|
37
|
+
thread = threading.Thread(target=_thread_runner, daemon=True)
|
|
38
|
+
thread.start()
|
|
39
|
+
thread.join()
|
|
40
|
+
if result is None:
|
|
41
|
+
raise RuntimeError("Coroutine execution did not return a result.")
|
|
42
|
+
return result
|
|
43
|
+
|
|
44
|
+
return loop.run_until_complete(coro)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
__all__ = ["run_coroutine_agent_sync"]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Agent helper for validating inputs and outputs against guardrails."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, Optional
|
|
7
|
+
|
|
8
|
+
from ..structure.validation import ValidationResultStructure
|
|
9
|
+
from .base import AgentBase
|
|
10
|
+
from .config import AgentConfig
|
|
11
|
+
from .prompt_utils import DEFAULT_PROMPT_DIR
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ValidatorAgent(AgentBase):
|
|
15
|
+
"""Check user prompts and agent responses against safety guardrails.
|
|
16
|
+
|
|
17
|
+
Methods
|
|
18
|
+
-------
|
|
19
|
+
run_agent(user_input, agent_output, policy_notes, extra_context)
|
|
20
|
+
Validate user and agent messages and return a structured report.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
*,
|
|
26
|
+
prompt_dir: Optional[Path] = None,
|
|
27
|
+
default_model: Optional[str] = None,
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Initialize the validator agent configuration.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
prompt_dir : pathlib.Path or None, default=None
|
|
34
|
+
Optional directory containing Jinja prompt templates. Defaults to the
|
|
35
|
+
packaged ``prompt`` directory when not provided.
|
|
36
|
+
default_model : str or None, default=None
|
|
37
|
+
Fallback model identifier when not specified elsewhere.
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
None
|
|
42
|
+
"""
|
|
43
|
+
config = AgentConfig(
|
|
44
|
+
name="validator",
|
|
45
|
+
description="Validate user input and agent output against guardrails.",
|
|
46
|
+
output_type=ValidationResultStructure,
|
|
47
|
+
)
|
|
48
|
+
prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
|
|
49
|
+
super().__init__(
|
|
50
|
+
config=config, prompt_dir=prompt_directory, default_model=default_model
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
async def run_agent(
|
|
54
|
+
self,
|
|
55
|
+
user_input: str,
|
|
56
|
+
*,
|
|
57
|
+
agent_output: Optional[str] = None,
|
|
58
|
+
policy_notes: Optional[str] = None,
|
|
59
|
+
extra_context: Optional[Dict[str, Any]] = None,
|
|
60
|
+
) -> ValidationResultStructure:
|
|
61
|
+
"""Validate user and agent messages.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
user_input : str
|
|
66
|
+
Raw input provided by the user for the agent to evaluate.
|
|
67
|
+
agent_output : str, optional
|
|
68
|
+
Latest agent response to validate against safety guardrails.
|
|
69
|
+
Default ``None`` when only the input should be assessed.
|
|
70
|
+
policy_notes : str, optional
|
|
71
|
+
Additional policy snippets or guardrail expectations to reinforce.
|
|
72
|
+
Default ``None``.
|
|
73
|
+
extra_context : dict, optional
|
|
74
|
+
Additional fields to merge into the validation context. Default ``None``.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
ValidationResultStructure
|
|
79
|
+
Structured validation result describing any violations and actions.
|
|
80
|
+
"""
|
|
81
|
+
context: Dict[str, Any] = {"user_input": user_input}
|
|
82
|
+
if agent_output is not None:
|
|
83
|
+
context["agent_output"] = agent_output
|
|
84
|
+
if policy_notes is not None:
|
|
85
|
+
context["policy_notes"] = policy_notes
|
|
86
|
+
if extra_context:
|
|
87
|
+
context.update(extra_context)
|
|
88
|
+
|
|
89
|
+
result: ValidationResultStructure = await self.run_async(
|
|
90
|
+
input=user_input,
|
|
91
|
+
context=context,
|
|
92
|
+
output_type=ValidationResultStructure,
|
|
93
|
+
)
|
|
94
|
+
return result
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
__all__ = ["ValidatorAgent"]
|