signalwire-agents 0.1.13__py3-none-any.whl → 1.0.17.dev4__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.
- signalwire_agents/__init__.py +99 -15
- signalwire_agents/agent_server.py +248 -60
- signalwire_agents/agents/bedrock.py +296 -0
- signalwire_agents/cli/__init__.py +9 -0
- signalwire_agents/cli/build_search.py +951 -41
- signalwire_agents/cli/config.py +80 -0
- signalwire_agents/cli/core/__init__.py +10 -0
- signalwire_agents/cli/core/agent_loader.py +470 -0
- signalwire_agents/cli/core/argparse_helpers.py +179 -0
- signalwire_agents/cli/core/dynamic_config.py +71 -0
- signalwire_agents/cli/core/service_loader.py +303 -0
- signalwire_agents/cli/dokku.py +2320 -0
- signalwire_agents/cli/execution/__init__.py +10 -0
- signalwire_agents/cli/execution/datamap_exec.py +446 -0
- signalwire_agents/cli/execution/webhook_exec.py +134 -0
- signalwire_agents/cli/init_project.py +2636 -0
- signalwire_agents/cli/output/__init__.py +10 -0
- signalwire_agents/cli/output/output_formatter.py +255 -0
- signalwire_agents/cli/output/swml_dump.py +186 -0
- signalwire_agents/cli/simulation/__init__.py +10 -0
- signalwire_agents/cli/simulation/data_generation.py +374 -0
- signalwire_agents/cli/simulation/data_overrides.py +200 -0
- signalwire_agents/cli/simulation/mock_env.py +282 -0
- signalwire_agents/cli/swaig_test_wrapper.py +52 -0
- signalwire_agents/cli/test_swaig.py +566 -2366
- signalwire_agents/cli/types.py +81 -0
- signalwire_agents/core/__init__.py +2 -2
- signalwire_agents/core/agent/__init__.py +12 -0
- signalwire_agents/core/agent/config/__init__.py +12 -0
- signalwire_agents/core/agent/deployment/__init__.py +9 -0
- signalwire_agents/core/agent/deployment/handlers/__init__.py +9 -0
- signalwire_agents/core/agent/prompt/__init__.py +14 -0
- signalwire_agents/core/agent/prompt/manager.py +306 -0
- signalwire_agents/core/agent/routing/__init__.py +9 -0
- signalwire_agents/core/agent/security/__init__.py +9 -0
- signalwire_agents/core/agent/swml/__init__.py +9 -0
- signalwire_agents/core/agent/tools/__init__.py +15 -0
- signalwire_agents/core/agent/tools/decorator.py +97 -0
- signalwire_agents/core/agent/tools/registry.py +210 -0
- signalwire_agents/core/agent_base.py +845 -2916
- signalwire_agents/core/auth_handler.py +233 -0
- signalwire_agents/core/config_loader.py +259 -0
- signalwire_agents/core/contexts.py +418 -0
- signalwire_agents/core/data_map.py +3 -15
- signalwire_agents/core/function_result.py +116 -44
- signalwire_agents/core/logging_config.py +162 -18
- signalwire_agents/core/mixins/__init__.py +28 -0
- signalwire_agents/core/mixins/ai_config_mixin.py +442 -0
- signalwire_agents/core/mixins/auth_mixin.py +280 -0
- signalwire_agents/core/mixins/prompt_mixin.py +358 -0
- signalwire_agents/core/mixins/serverless_mixin.py +460 -0
- signalwire_agents/core/mixins/skill_mixin.py +55 -0
- signalwire_agents/core/mixins/state_mixin.py +153 -0
- signalwire_agents/core/mixins/tool_mixin.py +230 -0
- signalwire_agents/core/mixins/web_mixin.py +1142 -0
- signalwire_agents/core/security_config.py +333 -0
- signalwire_agents/core/skill_base.py +84 -1
- signalwire_agents/core/skill_manager.py +62 -20
- signalwire_agents/core/swaig_function.py +18 -5
- signalwire_agents/core/swml_builder.py +207 -11
- signalwire_agents/core/swml_handler.py +27 -21
- signalwire_agents/core/swml_renderer.py +123 -312
- signalwire_agents/core/swml_service.py +171 -203
- signalwire_agents/mcp_gateway/__init__.py +29 -0
- signalwire_agents/mcp_gateway/gateway_service.py +564 -0
- signalwire_agents/mcp_gateway/mcp_manager.py +513 -0
- signalwire_agents/mcp_gateway/session_manager.py +218 -0
- signalwire_agents/prefabs/concierge.py +0 -3
- signalwire_agents/prefabs/faq_bot.py +0 -3
- signalwire_agents/prefabs/info_gatherer.py +0 -3
- signalwire_agents/prefabs/receptionist.py +0 -3
- signalwire_agents/prefabs/survey.py +0 -3
- signalwire_agents/schema.json +9218 -5489
- signalwire_agents/search/__init__.py +7 -1
- signalwire_agents/search/document_processor.py +490 -31
- signalwire_agents/search/index_builder.py +307 -37
- signalwire_agents/search/migration.py +418 -0
- signalwire_agents/search/models.py +30 -0
- signalwire_agents/search/pgvector_backend.py +748 -0
- signalwire_agents/search/query_processor.py +162 -31
- signalwire_agents/search/search_engine.py +916 -35
- signalwire_agents/search/search_service.py +376 -53
- signalwire_agents/skills/README.md +452 -0
- signalwire_agents/skills/__init__.py +14 -2
- signalwire_agents/skills/api_ninjas_trivia/README.md +215 -0
- signalwire_agents/skills/api_ninjas_trivia/__init__.py +12 -0
- signalwire_agents/skills/api_ninjas_trivia/skill.py +237 -0
- signalwire_agents/skills/datasphere/README.md +210 -0
- signalwire_agents/skills/datasphere/skill.py +84 -3
- signalwire_agents/skills/datasphere_serverless/README.md +258 -0
- signalwire_agents/skills/datasphere_serverless/__init__.py +9 -0
- signalwire_agents/skills/datasphere_serverless/skill.py +82 -1
- signalwire_agents/skills/datetime/README.md +132 -0
- signalwire_agents/skills/datetime/__init__.py +9 -0
- signalwire_agents/skills/datetime/skill.py +20 -7
- signalwire_agents/skills/joke/README.md +149 -0
- signalwire_agents/skills/joke/__init__.py +9 -0
- signalwire_agents/skills/joke/skill.py +21 -0
- signalwire_agents/skills/math/README.md +161 -0
- signalwire_agents/skills/math/__init__.py +9 -0
- signalwire_agents/skills/math/skill.py +18 -4
- signalwire_agents/skills/mcp_gateway/README.md +230 -0
- signalwire_agents/skills/mcp_gateway/__init__.py +10 -0
- signalwire_agents/skills/mcp_gateway/skill.py +421 -0
- signalwire_agents/skills/native_vector_search/README.md +210 -0
- signalwire_agents/skills/native_vector_search/__init__.py +9 -0
- signalwire_agents/skills/native_vector_search/skill.py +569 -101
- signalwire_agents/skills/play_background_file/README.md +218 -0
- signalwire_agents/skills/play_background_file/__init__.py +12 -0
- signalwire_agents/skills/play_background_file/skill.py +242 -0
- signalwire_agents/skills/registry.py +395 -40
- signalwire_agents/skills/spider/README.md +236 -0
- signalwire_agents/skills/spider/__init__.py +13 -0
- signalwire_agents/skills/spider/skill.py +598 -0
- signalwire_agents/skills/swml_transfer/README.md +395 -0
- signalwire_agents/skills/swml_transfer/__init__.py +10 -0
- signalwire_agents/skills/swml_transfer/skill.py +359 -0
- signalwire_agents/skills/weather_api/README.md +178 -0
- signalwire_agents/skills/weather_api/__init__.py +12 -0
- signalwire_agents/skills/weather_api/skill.py +191 -0
- signalwire_agents/skills/web_search/README.md +163 -0
- signalwire_agents/skills/web_search/__init__.py +9 -0
- signalwire_agents/skills/web_search/skill.py +586 -112
- signalwire_agents/skills/wikipedia_search/README.md +228 -0
- signalwire_agents/{core/state → skills/wikipedia_search}/__init__.py +5 -4
- signalwire_agents/skills/{wikipedia → wikipedia_search}/skill.py +33 -3
- signalwire_agents/web/__init__.py +17 -0
- signalwire_agents/web/web_service.py +559 -0
- signalwire_agents-1.0.17.dev4.data/data/share/man/man1/sw-agent-init.1 +400 -0
- signalwire_agents-1.0.17.dev4.data/data/share/man/man1/sw-search.1 +483 -0
- signalwire_agents-1.0.17.dev4.data/data/share/man/man1/swaig-test.1 +308 -0
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/METADATA +347 -215
- signalwire_agents-1.0.17.dev4.dist-info/RECORD +147 -0
- signalwire_agents-1.0.17.dev4.dist-info/entry_points.txt +6 -0
- signalwire_agents/core/state/file_state_manager.py +0 -219
- signalwire_agents/core/state/state_manager.py +0 -101
- signalwire_agents/skills/wikipedia/__init__.py +0 -9
- signalwire_agents-0.1.13.data/data/schema.json +0 -5611
- signalwire_agents-0.1.13.dist-info/RECORD +0 -67
- signalwire_agents-0.1.13.dist-info/entry_points.txt +0 -3
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/WHEEL +0 -0
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/licenses/LICENSE +0 -0
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/top_level.txt +0 -0
|
@@ -14,6 +14,7 @@ This module provides a fluent builder API for creating SWML documents.
|
|
|
14
14
|
It allows for chaining method calls to build up a document step by step.
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
+
import types
|
|
17
18
|
from typing import Dict, List, Any, Optional, Union, TypeVar
|
|
18
19
|
try:
|
|
19
20
|
from typing import Self # Python 3.11+
|
|
@@ -43,6 +44,12 @@ class SWMLBuilder:
|
|
|
43
44
|
service: The SWMLService to delegate to
|
|
44
45
|
"""
|
|
45
46
|
self.service = service
|
|
47
|
+
|
|
48
|
+
# Dictionary to cache dynamically created methods
|
|
49
|
+
self._verb_methods_cache = {}
|
|
50
|
+
|
|
51
|
+
# Create auto-vivified methods for all verbs
|
|
52
|
+
self._create_verb_methods()
|
|
46
53
|
|
|
47
54
|
def answer(self, max_duration: Optional[int] = None, codecs: Optional[str] = None) -> Self:
|
|
48
55
|
"""
|
|
@@ -55,7 +62,12 @@ class SWMLBuilder:
|
|
|
55
62
|
Returns:
|
|
56
63
|
Self for method chaining
|
|
57
64
|
"""
|
|
58
|
-
|
|
65
|
+
config = {}
|
|
66
|
+
if max_duration is not None:
|
|
67
|
+
config["max_duration"] = max_duration
|
|
68
|
+
if codecs is not None:
|
|
69
|
+
config["codecs"] = codecs
|
|
70
|
+
self.service.add_verb("answer", config)
|
|
59
71
|
return self
|
|
60
72
|
|
|
61
73
|
def hangup(self, reason: Optional[str] = None) -> Self:
|
|
@@ -68,7 +80,10 @@ class SWMLBuilder:
|
|
|
68
80
|
Returns:
|
|
69
81
|
Self for method chaining
|
|
70
82
|
"""
|
|
71
|
-
|
|
83
|
+
config = {}
|
|
84
|
+
if reason is not None:
|
|
85
|
+
config["reason"] = reason
|
|
86
|
+
self.service.add_verb("hangup", config)
|
|
72
87
|
return self
|
|
73
88
|
|
|
74
89
|
def ai(self,
|
|
@@ -92,14 +107,26 @@ class SWMLBuilder:
|
|
|
92
107
|
Returns:
|
|
93
108
|
Self for method chaining
|
|
94
109
|
"""
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
config = {}
|
|
111
|
+
|
|
112
|
+
# Handle prompt (either text or POM, but not both)
|
|
113
|
+
if prompt_text is not None:
|
|
114
|
+
config["prompt"] = prompt_text
|
|
115
|
+
elif prompt_pom is not None:
|
|
116
|
+
config["prompt"] = prompt_pom
|
|
117
|
+
|
|
118
|
+
# Add optional parameters
|
|
119
|
+
if post_prompt is not None:
|
|
120
|
+
config["post_prompt"] = post_prompt
|
|
121
|
+
if post_prompt_url is not None:
|
|
122
|
+
config["post_prompt_url"] = post_prompt_url
|
|
123
|
+
if swaig is not None:
|
|
124
|
+
config["SWAIG"] = swaig
|
|
125
|
+
|
|
126
|
+
# Add any additional kwargs
|
|
127
|
+
config.update(kwargs)
|
|
128
|
+
|
|
129
|
+
self.service.add_verb("ai", config)
|
|
103
130
|
return self
|
|
104
131
|
|
|
105
132
|
def play(self, url: Optional[str] = None, urls: Optional[List[str]] = None,
|
|
@@ -215,4 +242,173 @@ class SWMLBuilder:
|
|
|
215
242
|
Self for method chaining
|
|
216
243
|
"""
|
|
217
244
|
self.service.reset_document()
|
|
218
|
-
return self
|
|
245
|
+
return self
|
|
246
|
+
|
|
247
|
+
def _create_verb_methods(self) -> None:
|
|
248
|
+
"""
|
|
249
|
+
Create auto-vivified methods for all verbs at initialization time
|
|
250
|
+
|
|
251
|
+
This creates methods for all SWML verbs defined in the schema,
|
|
252
|
+
allowing for fluent chaining like builder.denoise().goto().play()
|
|
253
|
+
"""
|
|
254
|
+
# Get all verb names from the schema
|
|
255
|
+
if not hasattr(self.service, 'schema_utils') or not self.service.schema_utils:
|
|
256
|
+
return
|
|
257
|
+
|
|
258
|
+
verb_names = self.service.schema_utils.get_all_verb_names()
|
|
259
|
+
|
|
260
|
+
# Create a method for each verb
|
|
261
|
+
for verb_name in verb_names:
|
|
262
|
+
# Skip verbs that already have specific methods
|
|
263
|
+
if hasattr(self, verb_name):
|
|
264
|
+
continue
|
|
265
|
+
|
|
266
|
+
# Handle sleep verb specially since it takes an integer directly
|
|
267
|
+
if verb_name == "sleep":
|
|
268
|
+
def sleep_method(self_instance, duration=None, **kwargs):
|
|
269
|
+
"""
|
|
270
|
+
Add the sleep verb to the document.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
duration: The amount of time to sleep in milliseconds
|
|
274
|
+
"""
|
|
275
|
+
# Sleep verb takes a direct integer parameter in SWML
|
|
276
|
+
if duration is not None:
|
|
277
|
+
self_instance.service.add_verb("sleep", duration)
|
|
278
|
+
elif kwargs:
|
|
279
|
+
# Try to get the value from kwargs
|
|
280
|
+
self_instance.service.add_verb("sleep", next(iter(kwargs.values())))
|
|
281
|
+
else:
|
|
282
|
+
raise TypeError("sleep() missing required argument: 'duration'")
|
|
283
|
+
return self_instance
|
|
284
|
+
|
|
285
|
+
# Set it as an attribute of self
|
|
286
|
+
setattr(self, verb_name, types.MethodType(sleep_method, self))
|
|
287
|
+
|
|
288
|
+
# Also cache it for later
|
|
289
|
+
self._verb_methods_cache[verb_name] = sleep_method
|
|
290
|
+
continue
|
|
291
|
+
|
|
292
|
+
# Generate the method implementation for normal verbs
|
|
293
|
+
def make_verb_method(name):
|
|
294
|
+
def verb_method(self_instance, **kwargs):
|
|
295
|
+
"""
|
|
296
|
+
Dynamically generated method for SWML verb - returns self for chaining
|
|
297
|
+
"""
|
|
298
|
+
config = {}
|
|
299
|
+
for key, value in kwargs.items():
|
|
300
|
+
if value is not None:
|
|
301
|
+
config[key] = value
|
|
302
|
+
self_instance.service.add_verb(name, config)
|
|
303
|
+
return self_instance
|
|
304
|
+
|
|
305
|
+
# Add docstring to the method
|
|
306
|
+
if hasattr(self.service.schema_utils, 'get_verb_properties'):
|
|
307
|
+
verb_properties = self.service.schema_utils.get_verb_properties(name)
|
|
308
|
+
if "description" in verb_properties:
|
|
309
|
+
verb_method.__doc__ = f"Add the {name} verb to the document.\n\n{verb_properties['description']}\n\nReturns: Self for method chaining"
|
|
310
|
+
else:
|
|
311
|
+
verb_method.__doc__ = f"Add the {name} verb to the document.\n\nReturns: Self for method chaining"
|
|
312
|
+
else:
|
|
313
|
+
verb_method.__doc__ = f"Add the {name} verb to the document.\n\nReturns: Self for method chaining"
|
|
314
|
+
|
|
315
|
+
return verb_method
|
|
316
|
+
|
|
317
|
+
# Create the method with closure over the verb name
|
|
318
|
+
method = make_verb_method(verb_name)
|
|
319
|
+
|
|
320
|
+
# Set it as an attribute of self
|
|
321
|
+
setattr(self, verb_name, types.MethodType(method, self))
|
|
322
|
+
|
|
323
|
+
# Also cache it for later
|
|
324
|
+
self._verb_methods_cache[verb_name] = method
|
|
325
|
+
|
|
326
|
+
def __getattr__(self, name: str) -> Any:
|
|
327
|
+
"""
|
|
328
|
+
Dynamically generate and return SWML verb methods when accessed
|
|
329
|
+
|
|
330
|
+
This method is called when an attribute lookup fails through the normal
|
|
331
|
+
mechanisms. It checks if the attribute name corresponds to a SWML verb
|
|
332
|
+
defined in the schema, and if so, dynamically creates a method for that verb.
|
|
333
|
+
|
|
334
|
+
Args:
|
|
335
|
+
name: The name of the attribute being accessed
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
The dynamically created verb method if name is a valid SWML verb,
|
|
339
|
+
otherwise raises AttributeError
|
|
340
|
+
|
|
341
|
+
Raises:
|
|
342
|
+
AttributeError: If name is not a valid SWML verb
|
|
343
|
+
"""
|
|
344
|
+
# First check if this is a valid SWML verb
|
|
345
|
+
if not hasattr(self.service, 'schema_utils') or not self.service.schema_utils:
|
|
346
|
+
msg = f"'{self.__class__.__name__}' object has no attribute '{name}' (no schema available)"
|
|
347
|
+
raise AttributeError(msg)
|
|
348
|
+
|
|
349
|
+
verb_names = self.service.schema_utils.get_all_verb_names()
|
|
350
|
+
|
|
351
|
+
if name in verb_names:
|
|
352
|
+
# Check if we already have this method in the cache
|
|
353
|
+
if not hasattr(self, '_verb_methods_cache'):
|
|
354
|
+
self._verb_methods_cache = {}
|
|
355
|
+
|
|
356
|
+
if name in self._verb_methods_cache:
|
|
357
|
+
return types.MethodType(self._verb_methods_cache[name], self)
|
|
358
|
+
|
|
359
|
+
# Handle sleep verb specially since it takes an integer directly
|
|
360
|
+
if name == "sleep":
|
|
361
|
+
def sleep_method(self_instance, duration=None, **kwargs):
|
|
362
|
+
"""
|
|
363
|
+
Add the sleep verb to the document.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
duration: The amount of time to sleep in milliseconds
|
|
367
|
+
"""
|
|
368
|
+
# Sleep verb takes a direct integer parameter in SWML
|
|
369
|
+
if duration is not None:
|
|
370
|
+
self_instance.service.add_verb("sleep", duration)
|
|
371
|
+
elif kwargs:
|
|
372
|
+
# Try to get the value from kwargs
|
|
373
|
+
self_instance.service.add_verb("sleep", next(iter(kwargs.values())))
|
|
374
|
+
else:
|
|
375
|
+
raise TypeError("sleep() missing required argument: 'duration'")
|
|
376
|
+
return self_instance
|
|
377
|
+
|
|
378
|
+
# Cache the method for future use
|
|
379
|
+
self._verb_methods_cache[name] = sleep_method
|
|
380
|
+
|
|
381
|
+
# Return the bound method
|
|
382
|
+
return types.MethodType(sleep_method, self)
|
|
383
|
+
|
|
384
|
+
# Generate the method implementation for normal verbs
|
|
385
|
+
def verb_method(self_instance, **kwargs):
|
|
386
|
+
"""
|
|
387
|
+
Dynamically generated method for SWML verb - returns self for chaining
|
|
388
|
+
"""
|
|
389
|
+
config = {}
|
|
390
|
+
for key, value in kwargs.items():
|
|
391
|
+
if value is not None:
|
|
392
|
+
config[key] = value
|
|
393
|
+
self_instance.service.add_verb(name, config)
|
|
394
|
+
return self_instance
|
|
395
|
+
|
|
396
|
+
# Add docstring to the method
|
|
397
|
+
if hasattr(self.service.schema_utils, 'get_verb_properties'):
|
|
398
|
+
verb_properties = self.service.schema_utils.get_verb_properties(name)
|
|
399
|
+
if "description" in verb_properties:
|
|
400
|
+
verb_method.__doc__ = f"Add the {name} verb to the document.\n\n{verb_properties['description']}\n\nReturns: Self for method chaining"
|
|
401
|
+
else:
|
|
402
|
+
verb_method.__doc__ = f"Add the {name} verb to the document.\n\nReturns: Self for method chaining"
|
|
403
|
+
else:
|
|
404
|
+
verb_method.__doc__ = f"Add the {name} verb to the document.\n\nReturns: Self for method chaining"
|
|
405
|
+
|
|
406
|
+
# Cache the method for future use
|
|
407
|
+
self._verb_methods_cache[name] = verb_method
|
|
408
|
+
|
|
409
|
+
# Return the bound method
|
|
410
|
+
return types.MethodType(verb_method, self)
|
|
411
|
+
|
|
412
|
+
# Not a valid verb
|
|
413
|
+
msg = f"'{self.__class__.__name__}' object has no attribute '{name}'"
|
|
414
|
+
raise AttributeError(msg)
|
|
@@ -103,19 +103,19 @@ class AIVerbHandler(SWMLVerbHandler):
|
|
|
103
103
|
errors.append("'prompt' must be an object")
|
|
104
104
|
return False, errors
|
|
105
105
|
|
|
106
|
-
# Check that prompt contains
|
|
106
|
+
# Check that prompt contains either text or pom (required)
|
|
107
107
|
has_text = "text" in prompt
|
|
108
108
|
has_pom = "pom" in prompt
|
|
109
109
|
has_contexts = "contexts" in prompt
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
# Require either text or pom (mutually exclusive)
|
|
112
|
+
base_prompt_count = sum([has_text, has_pom])
|
|
113
|
+
if base_prompt_count == 0:
|
|
114
|
+
errors.append("'prompt' must contain either 'text' or 'pom' as base prompt")
|
|
115
|
+
elif base_prompt_count > 1:
|
|
116
|
+
errors.append("'prompt' can only contain one of: 'text' or 'pom' (mutually exclusive)")
|
|
112
117
|
|
|
113
|
-
|
|
114
|
-
errors.append("'prompt' must contain one of: 'text', 'pom', or 'contexts'")
|
|
115
|
-
elif options_count > 1:
|
|
116
|
-
errors.append("'prompt' can only contain one of: 'text', 'pom', or 'contexts'")
|
|
117
|
-
|
|
118
|
-
# Validate contexts structure if present
|
|
118
|
+
# Contexts are optional and can be combined with text or pom
|
|
119
119
|
if has_contexts:
|
|
120
120
|
contexts = prompt["contexts"]
|
|
121
121
|
if not isinstance(contexts, dict):
|
|
@@ -141,9 +141,9 @@ class AIVerbHandler(SWMLVerbHandler):
|
|
|
141
141
|
Build a configuration for the AI verb
|
|
142
142
|
|
|
143
143
|
Args:
|
|
144
|
-
prompt_text: Text prompt for the AI (mutually exclusive with prompt_pom
|
|
145
|
-
prompt_pom: POM structure for the AI prompt (mutually exclusive with prompt_text
|
|
146
|
-
contexts:
|
|
144
|
+
prompt_text: Text prompt for the AI (mutually exclusive with prompt_pom)
|
|
145
|
+
prompt_pom: POM structure for the AI prompt (mutually exclusive with prompt_text)
|
|
146
|
+
contexts: Optional contexts and steps configuration (can be combined with text or pom)
|
|
147
147
|
post_prompt: Optional post-prompt text
|
|
148
148
|
post_prompt_url: Optional URL for post-prompt processing
|
|
149
149
|
swaig: Optional SWAIG configuration
|
|
@@ -154,19 +154,25 @@ class AIVerbHandler(SWMLVerbHandler):
|
|
|
154
154
|
"""
|
|
155
155
|
config = {}
|
|
156
156
|
|
|
157
|
-
#
|
|
158
|
-
|
|
159
|
-
if
|
|
160
|
-
raise ValueError("
|
|
161
|
-
elif
|
|
162
|
-
raise ValueError("prompt_text
|
|
157
|
+
# Require either text or pom as base prompt (mutually exclusive)
|
|
158
|
+
base_prompt_count = sum(x is not None for x in [prompt_text, prompt_pom])
|
|
159
|
+
if base_prompt_count == 0:
|
|
160
|
+
raise ValueError("Either prompt_text or prompt_pom must be provided as base prompt")
|
|
161
|
+
elif base_prompt_count > 1:
|
|
162
|
+
raise ValueError("prompt_text and prompt_pom are mutually exclusive")
|
|
163
163
|
|
|
164
|
+
# Build prompt object with base prompt
|
|
165
|
+
prompt_config = {}
|
|
164
166
|
if prompt_text is not None:
|
|
165
|
-
|
|
167
|
+
prompt_config["text"] = prompt_text
|
|
166
168
|
elif prompt_pom is not None:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
169
|
+
prompt_config["pom"] = prompt_pom
|
|
170
|
+
|
|
171
|
+
# Add contexts if provided (optional, activates steps feature)
|
|
172
|
+
if contexts is not None:
|
|
173
|
+
prompt_config["contexts"] = contexts
|
|
174
|
+
|
|
175
|
+
config["prompt"] = prompt_config
|
|
170
176
|
|
|
171
177
|
# Add post-prompt if provided
|
|
172
178
|
if post_prompt is not None:
|