uipath-langchain 0.0.133__py3-none-any.whl → 0.1.28__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.
- uipath_langchain/_cli/cli_init.py +130 -191
- uipath_langchain/_cli/cli_new.py +2 -3
- uipath_langchain/_resources/AGENTS.md +21 -0
- uipath_langchain/_resources/REQUIRED_STRUCTURE.md +92 -0
- uipath_langchain/_tracing/__init__.py +3 -2
- uipath_langchain/_tracing/_instrument_traceable.py +11 -12
- uipath_langchain/_utils/_request_mixin.py +327 -51
- uipath_langchain/_utils/_settings.py +2 -2
- uipath_langchain/agent/exceptions/__init__.py +6 -0
- uipath_langchain/agent/exceptions/exceptions.py +11 -0
- uipath_langchain/agent/guardrails/__init__.py +21 -0
- uipath_langchain/agent/guardrails/actions/__init__.py +11 -0
- uipath_langchain/agent/guardrails/actions/base_action.py +24 -0
- uipath_langchain/agent/guardrails/actions/block_action.py +42 -0
- uipath_langchain/agent/guardrails/actions/escalate_action.py +499 -0
- uipath_langchain/agent/guardrails/actions/log_action.py +58 -0
- uipath_langchain/agent/guardrails/guardrail_nodes.py +173 -0
- uipath_langchain/agent/guardrails/guardrails_factory.py +70 -0
- uipath_langchain/agent/guardrails/guardrails_subgraph.py +283 -0
- uipath_langchain/agent/guardrails/types.py +20 -0
- uipath_langchain/agent/react/__init__.py +14 -0
- uipath_langchain/agent/react/agent.py +117 -0
- uipath_langchain/agent/react/constants.py +2 -0
- uipath_langchain/agent/react/init_node.py +20 -0
- uipath_langchain/agent/react/llm_node.py +43 -0
- uipath_langchain/agent/react/router.py +97 -0
- uipath_langchain/agent/react/terminate_node.py +82 -0
- uipath_langchain/agent/react/tools/__init__.py +7 -0
- uipath_langchain/agent/react/tools/tools.py +50 -0
- uipath_langchain/agent/react/types.py +39 -0
- uipath_langchain/agent/react/utils.py +49 -0
- uipath_langchain/agent/tools/__init__.py +17 -0
- uipath_langchain/agent/tools/context_tool.py +53 -0
- uipath_langchain/agent/tools/escalation_tool.py +111 -0
- uipath_langchain/agent/tools/integration_tool.py +181 -0
- uipath_langchain/agent/tools/process_tool.py +49 -0
- uipath_langchain/agent/tools/static_args.py +138 -0
- uipath_langchain/agent/tools/structured_tool_with_output_type.py +14 -0
- uipath_langchain/agent/tools/tool_factory.py +45 -0
- uipath_langchain/agent/tools/tool_node.py +22 -0
- uipath_langchain/agent/tools/utils.py +11 -0
- uipath_langchain/chat/__init__.py +4 -0
- uipath_langchain/chat/bedrock.py +187 -0
- uipath_langchain/chat/mapper.py +309 -0
- uipath_langchain/chat/models.py +248 -35
- uipath_langchain/chat/openai.py +133 -0
- uipath_langchain/chat/supported_models.py +42 -0
- uipath_langchain/chat/vertex.py +255 -0
- uipath_langchain/embeddings/embeddings.py +131 -34
- uipath_langchain/middlewares.py +0 -6
- uipath_langchain/retrievers/context_grounding_retriever.py +7 -9
- uipath_langchain/runtime/__init__.py +36 -0
- uipath_langchain/runtime/_serialize.py +46 -0
- uipath_langchain/runtime/config.py +61 -0
- uipath_langchain/runtime/errors.py +43 -0
- uipath_langchain/runtime/factory.py +315 -0
- uipath_langchain/runtime/graph.py +159 -0
- uipath_langchain/runtime/runtime.py +453 -0
- uipath_langchain/runtime/schema.py +386 -0
- uipath_langchain/runtime/storage.py +115 -0
- uipath_langchain/vectorstores/context_grounding_vectorstore.py +90 -110
- {uipath_langchain-0.0.133.dist-info → uipath_langchain-0.1.28.dist-info}/METADATA +44 -23
- uipath_langchain-0.1.28.dist-info/RECORD +76 -0
- {uipath_langchain-0.0.133.dist-info → uipath_langchain-0.1.28.dist-info}/WHEEL +1 -1
- uipath_langchain-0.1.28.dist-info/entry_points.txt +5 -0
- uipath_langchain/_cli/_runtime/_context.py +0 -21
- uipath_langchain/_cli/_runtime/_conversation.py +0 -298
- uipath_langchain/_cli/_runtime/_exception.py +0 -17
- uipath_langchain/_cli/_runtime/_input.py +0 -139
- uipath_langchain/_cli/_runtime/_output.py +0 -234
- uipath_langchain/_cli/_runtime/_runtime.py +0 -379
- uipath_langchain/_cli/_utils/_graph.py +0 -199
- uipath_langchain/_cli/cli_dev.py +0 -44
- uipath_langchain/_cli/cli_eval.py +0 -78
- uipath_langchain/_cli/cli_run.py +0 -82
- uipath_langchain/_tracing/_oteladapter.py +0 -222
- uipath_langchain/_tracing/_utils.py +0 -28
- uipath_langchain/builder/agent_config.py +0 -191
- uipath_langchain/tools/preconfigured.py +0 -191
- uipath_langchain-0.0.133.dist-info/RECORD +0 -41
- uipath_langchain-0.0.133.dist-info/entry_points.txt +0 -2
- /uipath_langchain/{tools/__init__.py → py.typed} +0 -0
- {uipath_langchain-0.0.133.dist-info → uipath_langchain-0.1.28.dist-info}/licenses/LICENSE +0 -0
uipath_langchain/_cli/cli_run.py
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import os
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
|
-
from openinference.instrumentation.langchain import (
|
|
6
|
-
LangChainInstrumentor,
|
|
7
|
-
get_current_span,
|
|
8
|
-
)
|
|
9
|
-
from uipath._cli._runtime._contracts import (
|
|
10
|
-
UiPathRuntimeFactory,
|
|
11
|
-
)
|
|
12
|
-
from uipath._cli.middlewares import MiddlewareResult
|
|
13
|
-
|
|
14
|
-
from .._tracing import LangChainExporter, _instrument_traceable_attributes
|
|
15
|
-
from ._runtime._exception import LangGraphRuntimeError
|
|
16
|
-
from ._runtime._runtime import ( # type: ignore[attr-defined]
|
|
17
|
-
LangGraphRuntime,
|
|
18
|
-
LangGraphRuntimeContext,
|
|
19
|
-
)
|
|
20
|
-
from ._utils._graph import LangGraphConfig
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def langgraph_run_middleware(
|
|
24
|
-
entrypoint: Optional[str], input: Optional[str], resume: bool, **kwargs
|
|
25
|
-
) -> MiddlewareResult:
|
|
26
|
-
"""Middleware to handle LangGraph execution"""
|
|
27
|
-
config = LangGraphConfig()
|
|
28
|
-
if not config.exists:
|
|
29
|
-
return MiddlewareResult(
|
|
30
|
-
should_continue=True
|
|
31
|
-
) # Continue with normal flow if no langgraph.json
|
|
32
|
-
|
|
33
|
-
try:
|
|
34
|
-
context = LangGraphRuntimeContext.with_defaults(**kwargs)
|
|
35
|
-
context.langgraph_config = config
|
|
36
|
-
context.entrypoint = entrypoint
|
|
37
|
-
context.input = input
|
|
38
|
-
context.resume = resume
|
|
39
|
-
|
|
40
|
-
_instrument_traceable_attributes()
|
|
41
|
-
|
|
42
|
-
def generate_runtime(ctx: LangGraphRuntimeContext) -> LangGraphRuntime:
|
|
43
|
-
runtime = LangGraphRuntime(ctx)
|
|
44
|
-
# If not resuming and no job id, delete the previous state file
|
|
45
|
-
if not ctx.resume and ctx.job_id is None:
|
|
46
|
-
if os.path.exists(runtime.state_file_path):
|
|
47
|
-
os.remove(runtime.state_file_path)
|
|
48
|
-
return runtime
|
|
49
|
-
|
|
50
|
-
async def execute():
|
|
51
|
-
runtime_factory = UiPathRuntimeFactory(
|
|
52
|
-
LangGraphRuntime,
|
|
53
|
-
LangGraphRuntimeContext,
|
|
54
|
-
runtime_generator=generate_runtime,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
if context.job_id:
|
|
58
|
-
runtime_factory.add_span_exporter(LangChainExporter())
|
|
59
|
-
|
|
60
|
-
runtime_factory.add_instrumentor(LangChainInstrumentor, get_current_span)
|
|
61
|
-
|
|
62
|
-
await runtime_factory.execute(context)
|
|
63
|
-
|
|
64
|
-
asyncio.run(execute())
|
|
65
|
-
|
|
66
|
-
return MiddlewareResult(
|
|
67
|
-
should_continue=False,
|
|
68
|
-
error_message=None,
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
except LangGraphRuntimeError as e:
|
|
72
|
-
return MiddlewareResult(
|
|
73
|
-
should_continue=False,
|
|
74
|
-
error_message=e.error_info.detail,
|
|
75
|
-
should_include_stacktrace=True,
|
|
76
|
-
)
|
|
77
|
-
except Exception as e:
|
|
78
|
-
return MiddlewareResult(
|
|
79
|
-
should_continue=False,
|
|
80
|
-
error_message=f"Error: {str(e)}",
|
|
81
|
-
should_include_stacktrace=True,
|
|
82
|
-
)
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
from typing import Any, Dict, List
|
|
4
|
-
|
|
5
|
-
from opentelemetry.sdk.trace.export import (
|
|
6
|
-
SpanExportResult,
|
|
7
|
-
)
|
|
8
|
-
from uipath.tracing import LlmOpsHttpExporter
|
|
9
|
-
|
|
10
|
-
logger = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def _safe_parse_json(s: Any) -> Any:
|
|
14
|
-
"""Safely parse a JSON string, returning the original if not a string or on error."""
|
|
15
|
-
if not isinstance(s, str):
|
|
16
|
-
return s
|
|
17
|
-
try:
|
|
18
|
-
return json.loads(s)
|
|
19
|
-
except (json.JSONDecodeError, TypeError):
|
|
20
|
-
return s
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def _get_llm_messages(attributes: Dict[str, Any], prefix: str) -> List[Dict[str, Any]]:
|
|
24
|
-
"""Extracts and reconstructs LLM messages from flattened attributes."""
|
|
25
|
-
messages: dict[int, dict[str, Any]] = {}
|
|
26
|
-
message_prefix = f"{prefix}."
|
|
27
|
-
|
|
28
|
-
for key, value in attributes.items():
|
|
29
|
-
if key.startswith(message_prefix):
|
|
30
|
-
parts = key[len(message_prefix) :].split(".")
|
|
31
|
-
if len(parts) >= 2 and parts[0].isdigit():
|
|
32
|
-
index = int(parts[0])
|
|
33
|
-
if index not in messages:
|
|
34
|
-
messages[index] = {}
|
|
35
|
-
current: Any = messages[index]
|
|
36
|
-
|
|
37
|
-
for i, part in enumerate(parts[1:-1]):
|
|
38
|
-
key_part: str | int = part
|
|
39
|
-
if part.isdigit() and (
|
|
40
|
-
i + 2 < len(parts) and parts[i + 2].isdigit()
|
|
41
|
-
):
|
|
42
|
-
key_part = int(part)
|
|
43
|
-
|
|
44
|
-
if isinstance(current, dict):
|
|
45
|
-
if key_part not in current:
|
|
46
|
-
current[key_part] = {}
|
|
47
|
-
current = current[key_part]
|
|
48
|
-
elif isinstance(current, list) and isinstance(key_part, int):
|
|
49
|
-
if key_part >= len(current):
|
|
50
|
-
current.append({})
|
|
51
|
-
current = current[key_part]
|
|
52
|
-
|
|
53
|
-
current[parts[-1]] = value
|
|
54
|
-
|
|
55
|
-
# Convert dict to list, ordered by index
|
|
56
|
-
return [messages[i] for i in sorted(messages.keys())]
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class LangChainExporter(LlmOpsHttpExporter):
|
|
60
|
-
# Mapping of old attribute names to new attribute names or (new name, function)
|
|
61
|
-
ATTRIBUTE_MAPPING: dict[str, str | tuple[str, Any]] = {
|
|
62
|
-
"input.value": ("input", _safe_parse_json),
|
|
63
|
-
"output.value": ("output", _safe_parse_json),
|
|
64
|
-
"llm.model_name": "model",
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
# Mapping of span types
|
|
68
|
-
SPAN_TYPE_MAPPING: dict[str, str] = {
|
|
69
|
-
"LLM": "completion",
|
|
70
|
-
"TOOL": "toolCall",
|
|
71
|
-
# Add more mappings as needed
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
75
|
-
super().__init__(*args, **kwargs)
|
|
76
|
-
|
|
77
|
-
def _map_llm_call_attributes(self, attributes: Dict[str, Any]) -> Dict[str, Any]:
|
|
78
|
-
"""Maps attributes for LLM calls, handling flattened keys."""
|
|
79
|
-
result = attributes.copy() # Keep original attributes including basic mappings
|
|
80
|
-
|
|
81
|
-
# Token Usage
|
|
82
|
-
token_keys = {
|
|
83
|
-
"llm.token_count.prompt": "promptTokens",
|
|
84
|
-
"llm.token_count.completion": "completionTokens",
|
|
85
|
-
"llm.token_count.total": "totalTokens",
|
|
86
|
-
}
|
|
87
|
-
usage = {
|
|
88
|
-
new_key: attributes.get(old_key)
|
|
89
|
-
for old_key, new_key in token_keys.items()
|
|
90
|
-
if old_key in attributes
|
|
91
|
-
}
|
|
92
|
-
if usage:
|
|
93
|
-
result["usage"] = usage
|
|
94
|
-
|
|
95
|
-
# Input/Output Messages
|
|
96
|
-
result["input"] = _get_llm_messages(attributes, "llm.input_messages")
|
|
97
|
-
output_messages = _get_llm_messages(attributes, "llm.output_messages")
|
|
98
|
-
result["output"] = output_messages
|
|
99
|
-
|
|
100
|
-
# Invocation Parameters
|
|
101
|
-
invocation_params = _safe_parse_json(
|
|
102
|
-
attributes.get("llm.invocation_parameters", "{}")
|
|
103
|
-
)
|
|
104
|
-
if isinstance(invocation_params, dict):
|
|
105
|
-
result["model"] = invocation_params.get("model", result.get("model"))
|
|
106
|
-
settings: dict[str, Any] = {}
|
|
107
|
-
if "max_tokens" in invocation_params:
|
|
108
|
-
settings["maxTokens"] = invocation_params["max_tokens"]
|
|
109
|
-
if "temperature" in invocation_params:
|
|
110
|
-
settings["temperature"] = invocation_params["temperature"]
|
|
111
|
-
if settings:
|
|
112
|
-
result["settings"] = settings
|
|
113
|
-
|
|
114
|
-
# Tool Calls
|
|
115
|
-
tool_calls: list[dict[str, Any]] = []
|
|
116
|
-
for msg in output_messages:
|
|
117
|
-
# Ensure msg is a dictionary before proceeding
|
|
118
|
-
if not isinstance(msg, dict):
|
|
119
|
-
continue
|
|
120
|
-
msg_tool_calls = msg.get("message", {}).get("tool_calls", [])
|
|
121
|
-
|
|
122
|
-
# Ensure msg_tool_calls is a list
|
|
123
|
-
if not isinstance(msg_tool_calls, list):
|
|
124
|
-
continue
|
|
125
|
-
|
|
126
|
-
for tc in msg_tool_calls:
|
|
127
|
-
if not isinstance(tc, dict):
|
|
128
|
-
continue
|
|
129
|
-
tool_call_data = tc.get("tool_call", {})
|
|
130
|
-
if not isinstance(tool_call_data, dict):
|
|
131
|
-
continue
|
|
132
|
-
tool_calls.append(
|
|
133
|
-
{
|
|
134
|
-
"id": tool_call_data.get("id"),
|
|
135
|
-
"name": tool_call_data.get("function", {}).get("name"),
|
|
136
|
-
"arguments": _safe_parse_json(
|
|
137
|
-
tool_call_data.get("function", {}).get("arguments", "{}")
|
|
138
|
-
),
|
|
139
|
-
}
|
|
140
|
-
)
|
|
141
|
-
if tool_calls:
|
|
142
|
-
result["toolCalls"] = tool_calls
|
|
143
|
-
|
|
144
|
-
return result
|
|
145
|
-
|
|
146
|
-
def _map_tool_call_attributes(self, attributes: Dict[str, Any]) -> Dict[str, Any]:
|
|
147
|
-
"""Maps attributes for tool calls."""
|
|
148
|
-
result = attributes.copy() # Keep original attributes
|
|
149
|
-
|
|
150
|
-
result["type"] = "toolCall"
|
|
151
|
-
result["callId"] = attributes.get("call_id") or attributes.get("id")
|
|
152
|
-
result["toolName"] = attributes.get("tool.name")
|
|
153
|
-
result["arguments"] = _safe_parse_json(
|
|
154
|
-
attributes.get("input", attributes.get("input.value", "{}"))
|
|
155
|
-
)
|
|
156
|
-
result["toolType"] = "Integration"
|
|
157
|
-
result["result"] = _safe_parse_json(
|
|
158
|
-
attributes.get("output", attributes.get("output.value"))
|
|
159
|
-
)
|
|
160
|
-
result["error"] = None
|
|
161
|
-
|
|
162
|
-
return result
|
|
163
|
-
|
|
164
|
-
def _process_span_attributes(self, span_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
165
|
-
"""Extracts, transforms, and maps attributes for a span."""
|
|
166
|
-
if "Attributes" not in span_data:
|
|
167
|
-
return span_data
|
|
168
|
-
|
|
169
|
-
logger.info(f"Processing span: {span_data}")
|
|
170
|
-
|
|
171
|
-
attributes_val = span_data["Attributes"]
|
|
172
|
-
if isinstance(attributes_val, str):
|
|
173
|
-
try:
|
|
174
|
-
attributes: Dict[str, Any] = json.loads(attributes_val)
|
|
175
|
-
except json.JSONDecodeError as e:
|
|
176
|
-
logger.warning(f"Failed to parse attributes JSON: {e}")
|
|
177
|
-
return span_data
|
|
178
|
-
elif isinstance(attributes_val, dict):
|
|
179
|
-
attributes = attributes_val
|
|
180
|
-
else:
|
|
181
|
-
return span_data
|
|
182
|
-
|
|
183
|
-
# Determine SpanType
|
|
184
|
-
if "openinference.span.kind" in attributes:
|
|
185
|
-
span_type = attributes["openinference.span.kind"]
|
|
186
|
-
span_data["SpanType"] = self.SPAN_TYPE_MAPPING.get(span_type, span_type)
|
|
187
|
-
|
|
188
|
-
# Apply basic attribute mapping
|
|
189
|
-
for old_key, mapping in self.ATTRIBUTE_MAPPING.items():
|
|
190
|
-
if old_key in attributes:
|
|
191
|
-
if isinstance(mapping, tuple):
|
|
192
|
-
new_key, func = mapping
|
|
193
|
-
attributes[new_key] = func(attributes[old_key])
|
|
194
|
-
else:
|
|
195
|
-
new_key = mapping
|
|
196
|
-
attributes[new_key] = attributes[old_key]
|
|
197
|
-
|
|
198
|
-
# Apply detailed mapping based on SpanType
|
|
199
|
-
span_type = span_data.get("SpanType")
|
|
200
|
-
if span_type == "completion":
|
|
201
|
-
processed_attributes = self._map_llm_call_attributes(attributes)
|
|
202
|
-
elif span_type == "toolCall":
|
|
203
|
-
processed_attributes = self._map_tool_call_attributes(attributes)
|
|
204
|
-
else:
|
|
205
|
-
processed_attributes = attributes.copy()
|
|
206
|
-
|
|
207
|
-
span_data["Attributes"] = json.dumps(processed_attributes)
|
|
208
|
-
|
|
209
|
-
logger.info(f"Transformed span: {span_data}")
|
|
210
|
-
return span_data
|
|
211
|
-
|
|
212
|
-
def _send_with_retries(
|
|
213
|
-
self, url: str, payload: List[Dict[str, Any]], max_retries: int = 4
|
|
214
|
-
) -> SpanExportResult:
|
|
215
|
-
# Transform attributes in each span's payload before sending
|
|
216
|
-
transformed_payload = [self._process_span_attributes(span) for span in payload]
|
|
217
|
-
|
|
218
|
-
return super()._send_with_retries(
|
|
219
|
-
url=url,
|
|
220
|
-
payload=transformed_payload,
|
|
221
|
-
max_retries=max_retries,
|
|
222
|
-
)
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class IgnoreSpecificUrl(logging.Filter):
|
|
5
|
-
def __init__(self, url_to_ignore):
|
|
6
|
-
super().__init__()
|
|
7
|
-
self.url_to_ignore = url_to_ignore
|
|
8
|
-
|
|
9
|
-
def filter(self, record):
|
|
10
|
-
try:
|
|
11
|
-
if record.msg == 'HTTP Request: %s %s "%s %d %s"':
|
|
12
|
-
# Ignore the log if the URL matches the one we want to ignore
|
|
13
|
-
method = record.args[0]
|
|
14
|
-
url = record.args[1]
|
|
15
|
-
|
|
16
|
-
if method == "POST" and url.path.endswith(self.url_to_ignore):
|
|
17
|
-
# Check if the URL contains the specific path we want to ignore
|
|
18
|
-
return True
|
|
19
|
-
return False
|
|
20
|
-
|
|
21
|
-
except Exception:
|
|
22
|
-
return False
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def _setup_tracer_httpx_logging(url: str):
|
|
26
|
-
# Create a custom logger for httpx
|
|
27
|
-
# Add the custom filter to the root logger
|
|
28
|
-
logging.getLogger("httpx").addFilter(IgnoreSpecificUrl(url))
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
|
-
from typing import Annotated, Any, Dict, List, Literal, Optional, Union
|
|
3
|
-
|
|
4
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class AgentMessageRole(str, Enum):
|
|
8
|
-
"""Enum for message roles"""
|
|
9
|
-
|
|
10
|
-
SYSTEM = "System"
|
|
11
|
-
USER = "User"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class AgentMessage(BaseModel):
|
|
15
|
-
"""Message model for agent conversations"""
|
|
16
|
-
|
|
17
|
-
role: AgentMessageRole
|
|
18
|
-
content: str
|
|
19
|
-
|
|
20
|
-
model_config = ConfigDict(
|
|
21
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class AgentSettings(BaseModel):
|
|
26
|
-
"""Settings for agent configuration"""
|
|
27
|
-
|
|
28
|
-
engine: str = Field(..., description="Engine type, e.g., 'basic-v1'")
|
|
29
|
-
model: str = Field(..., description="LLM model identifier")
|
|
30
|
-
max_tokens: int = Field(
|
|
31
|
-
..., alias="maxTokens", description="Maximum number of tokens"
|
|
32
|
-
)
|
|
33
|
-
temperature: float = Field(..., description="Temperature for response generation")
|
|
34
|
-
|
|
35
|
-
model_config = ConfigDict(
|
|
36
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class AgentResourceType(str, Enum):
|
|
41
|
-
"""Enum for resource types"""
|
|
42
|
-
|
|
43
|
-
TOOL = "tool"
|
|
44
|
-
CONTEXT = "context"
|
|
45
|
-
ESCALATION = "escalation"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class AgentBaseResourceConfig(BaseModel):
|
|
49
|
-
"""Base resource model with common properties"""
|
|
50
|
-
|
|
51
|
-
name: str
|
|
52
|
-
description: str
|
|
53
|
-
|
|
54
|
-
model_config = ConfigDict(
|
|
55
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class AgentUnknownResourceConfig(AgentBaseResourceConfig):
|
|
60
|
-
"""Fallback for unknown or future resource types"""
|
|
61
|
-
|
|
62
|
-
resource_type: str = Field(alias="$resourceType")
|
|
63
|
-
|
|
64
|
-
model_config = ConfigDict(extra="allow")
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class AgentToolSettings(BaseModel):
|
|
68
|
-
"""Settings for tool configuration"""
|
|
69
|
-
|
|
70
|
-
max_attempts: int = Field(0, alias="maxAttempts")
|
|
71
|
-
retry_delay: int = Field(0, alias="retryDelay")
|
|
72
|
-
timeout: int = Field(0)
|
|
73
|
-
|
|
74
|
-
model_config = ConfigDict(
|
|
75
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
class AgentToolProperties(BaseModel):
|
|
80
|
-
"""Properties specific to tool configuration"""
|
|
81
|
-
|
|
82
|
-
folder_path: Optional[str] = Field(None, alias="folderPath")
|
|
83
|
-
process_name: Optional[str] = Field(None, alias="processName")
|
|
84
|
-
|
|
85
|
-
model_config = ConfigDict(
|
|
86
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class AgentToolResourceConfig(AgentBaseResourceConfig):
|
|
91
|
-
"""Tool resource with tool-specific properties"""
|
|
92
|
-
|
|
93
|
-
resource_type: Literal[AgentResourceType.TOOL] = Field(alias="$resourceType")
|
|
94
|
-
type: str = Field(..., description="Tool type")
|
|
95
|
-
arguments: Dict[str, Any] = Field(
|
|
96
|
-
default_factory=dict, description="Tool arguments"
|
|
97
|
-
)
|
|
98
|
-
input_schema: Dict[str, Any] = Field(
|
|
99
|
-
..., alias="inputSchema", description="Input schema for the tool"
|
|
100
|
-
)
|
|
101
|
-
output_schema: Dict[str, Any] = Field(
|
|
102
|
-
..., alias="outputSchema", description="Output schema for the tool"
|
|
103
|
-
)
|
|
104
|
-
properties: AgentToolProperties = Field(..., description="Tool-specific properties")
|
|
105
|
-
settings: AgentToolSettings = Field(
|
|
106
|
-
default_factory=AgentToolSettings, description="Tool settings"
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
model_config = ConfigDict(
|
|
110
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
class AgentContextSettings(BaseModel):
|
|
115
|
-
"""Settings for context configuration"""
|
|
116
|
-
|
|
117
|
-
result_count: int = Field(alias="resultCount")
|
|
118
|
-
retrieval_mode: Literal["Semantic", "Structured"] = Field(alias="retrievalMode")
|
|
119
|
-
threshold: float = Field(default=0)
|
|
120
|
-
|
|
121
|
-
model_config = ConfigDict(
|
|
122
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
class AgentContextResourceConfig(AgentBaseResourceConfig):
|
|
127
|
-
"""Context resource with context-specific properties"""
|
|
128
|
-
|
|
129
|
-
resource_type: Literal[AgentResourceType.CONTEXT] = Field(alias="$resourceType")
|
|
130
|
-
folder_path: str = Field(alias="folderPath")
|
|
131
|
-
index_name: str = Field(alias="indexName")
|
|
132
|
-
settings: AgentContextSettings = Field(..., description="Context settings")
|
|
133
|
-
|
|
134
|
-
model_config = ConfigDict(
|
|
135
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
class AgentEscalationResourceConfig(AgentBaseResourceConfig):
|
|
140
|
-
"""Escalation resource with escalation-specific properties"""
|
|
141
|
-
|
|
142
|
-
resource_type: Literal[AgentResourceType.ESCALATION] = Field(alias="$resourceType")
|
|
143
|
-
|
|
144
|
-
model_config = ConfigDict(
|
|
145
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
# Discriminated union for known types
|
|
150
|
-
KnownAgentResourceConfig = Annotated[
|
|
151
|
-
Union[
|
|
152
|
-
AgentToolResourceConfig,
|
|
153
|
-
AgentContextResourceConfig,
|
|
154
|
-
AgentEscalationResourceConfig,
|
|
155
|
-
],
|
|
156
|
-
Field(discriminator="resource_type"),
|
|
157
|
-
]
|
|
158
|
-
|
|
159
|
-
# Final union includes unknowns as a catch-all
|
|
160
|
-
AgentResourceConfig = Union[
|
|
161
|
-
KnownAgentResourceConfig,
|
|
162
|
-
AgentUnknownResourceConfig,
|
|
163
|
-
]
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
class AgentConfig(BaseModel):
|
|
167
|
-
"""Main agent model"""
|
|
168
|
-
|
|
169
|
-
id: str = Field(..., description="Agent id or project name")
|
|
170
|
-
name: str = Field(..., description="Agent name or project name")
|
|
171
|
-
input_schema: Dict[str, Any] = Field(
|
|
172
|
-
..., alias="inputSchema", description="JSON schema for input arguments"
|
|
173
|
-
)
|
|
174
|
-
output_schema: Dict[str, Any] = Field(
|
|
175
|
-
..., alias="outputSchema", description="JSON schema for output arguments"
|
|
176
|
-
)
|
|
177
|
-
messages: List[AgentMessage] = Field(
|
|
178
|
-
..., description="List of system and user messages"
|
|
179
|
-
)
|
|
180
|
-
features: List[Any] = Field(
|
|
181
|
-
default_factory=list, description="Currently empty feature list"
|
|
182
|
-
)
|
|
183
|
-
version: str = Field("1.0.0", description="Agent version")
|
|
184
|
-
settings: AgentSettings = Field(..., description="Agent settings configuration")
|
|
185
|
-
resources: List[AgentResourceConfig] = Field(
|
|
186
|
-
..., description="List of tools, context, and escalation resources"
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
model_config = ConfigDict(
|
|
190
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
191
|
-
)
|