mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-05-02 20:03:19 +02:00
Tool services - dynamically pluggable tool implementations for agent frameworks (#658)
* New schema * Tool service implementation * Base class * Joke service, for testing * Update unit tests for tool services
This commit is contained in:
parent
0b83c08ae4
commit
a38ca9474f
13 changed files with 1396 additions and 45 deletions
1
trustgraph-flow/trustgraph/tool_service/__init__.py
Normal file
1
trustgraph-flow/trustgraph/tool_service/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Tool service implementations
|
||||
2
trustgraph-flow/trustgraph/tool_service/joke/__init__.py
Normal file
2
trustgraph-flow/trustgraph/tool_service/joke/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Joke tool service
|
||||
from .service import run
|
||||
204
trustgraph-flow/trustgraph/tool_service/joke/service.py
Normal file
204
trustgraph-flow/trustgraph/tool_service/joke/service.py
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
"""
|
||||
Joke Tool Service - An example dynamic tool service.
|
||||
|
||||
This service demonstrates the tool service integration by:
|
||||
- Using the 'user' field to personalize responses
|
||||
- Using config params (style) to customize joke style
|
||||
- Using arguments (topic) to generate topic-specific jokes
|
||||
|
||||
Example tool-service config:
|
||||
{
|
||||
"id": "joke-service",
|
||||
"topic": "joke",
|
||||
"config-params": [
|
||||
{"name": "style", "required": false}
|
||||
]
|
||||
}
|
||||
|
||||
Example tool config:
|
||||
{
|
||||
"type": "tool-service",
|
||||
"name": "tell-joke",
|
||||
"description": "Tell a joke on a given topic",
|
||||
"service": "joke-service",
|
||||
"style": "pun",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "topic",
|
||||
"type": "string",
|
||||
"description": "The topic for the joke (e.g., programming, animals, food)"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
|
||||
import random
|
||||
import logging
|
||||
|
||||
from ... base import DynamicToolService
|
||||
|
||||
# Module logger
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
default_ident = "joke-service"
|
||||
default_topic = "joke"
|
||||
|
||||
# Joke database organized by topic and style
|
||||
JOKES = {
|
||||
"programming": {
|
||||
"pun": [
|
||||
"Why do programmers prefer dark mode? Because light attracts bugs!",
|
||||
"Why do Java developers wear glasses? Because they can't C#!",
|
||||
"A SQL query walks into a bar, walks up to two tables and asks... 'Can I join you?'",
|
||||
"Why was the JavaScript developer sad? Because he didn't Node how to Express himself!",
|
||||
],
|
||||
"dad-joke": [
|
||||
"I told my computer I needed a break, and now it won't stop sending me Kit-Kat ads.",
|
||||
"My son asked me to explain what a linked list is. I said 'I'll tell you, and then I'll tell you again, and again...'",
|
||||
"I asked my computer for a joke about UDP. I'm not sure if it got it.",
|
||||
],
|
||||
"one-liner": [
|
||||
"There are only 10 types of people: those who understand binary and those who don't.",
|
||||
"A programmer's wife tells him: 'Go to the store and get a loaf of bread. If they have eggs, get a dozen.' He returns with 12 loaves.",
|
||||
"99 little bugs in the code, 99 little bugs. Take one down, patch it around, 127 little bugs in the code.",
|
||||
],
|
||||
},
|
||||
"llama": {
|
||||
"pun": [
|
||||
"Why did the llama get a ticket? Because he was caught spitting in a no-spitting zone!",
|
||||
"What do you call a llama who's a great musician? A llama del Rey!",
|
||||
"Why did the llama cross the road? To prove he wasn't a chicken!",
|
||||
],
|
||||
"dad-joke": [
|
||||
"What did the llama say when he got kicked out of the zoo? 'Alpaca my bags!'",
|
||||
"Why don't llamas ever get lost? Because they always know the way to the Andes!",
|
||||
"What do you call a llama with no legs? A woolly rug!",
|
||||
],
|
||||
"one-liner": [
|
||||
"Llamas are great at meditation. They're always saying 'Dalai Llama.'",
|
||||
"I asked a llama for directions. He said 'No probllama!'",
|
||||
"Never trust a llama. They're always up to something woolly.",
|
||||
],
|
||||
},
|
||||
"animals": {
|
||||
"pun": [
|
||||
"What do you call a fish without eyes? A fsh!",
|
||||
"Why don't scientists trust atoms? Because they make up everything... just like that cat who blamed the dog!",
|
||||
"What do you call a bear with no teeth? A gummy bear!",
|
||||
],
|
||||
"dad-joke": [
|
||||
"I tried to catch some fog earlier. I mist. My dog wasn't impressed either.",
|
||||
"What do you call a dog that does magic tricks? A Labracadabrador!",
|
||||
"Why do cows wear bells? Because their horns don't work!",
|
||||
],
|
||||
"one-liner": [
|
||||
"I'm reading a book about anti-gravity. It's impossible to put down, unlike my cat.",
|
||||
"A horse walks into a bar. The bartender asks 'Why the long face?'",
|
||||
"What's orange and sounds like a parrot? A carrot!",
|
||||
],
|
||||
},
|
||||
"food": {
|
||||
"pun": [
|
||||
"I'm on a seafood diet. I see food and I eat it!",
|
||||
"Why did the tomato turn red? Because it saw the salad dressing!",
|
||||
"What do you call cheese that isn't yours? Nacho cheese!",
|
||||
],
|
||||
"dad-joke": [
|
||||
"I used to hate facial hair, but then it grew on me. Speaking of growing, have you tried my garden salad?",
|
||||
"Why don't eggs tell jokes? They'd crack each other up!",
|
||||
"I told my wife she was drawing her eyebrows too high. She looked surprised, then made me a sandwich.",
|
||||
],
|
||||
"one-liner": [
|
||||
"I'm reading a book about submarines and sandwiches. It's a sub-genre.",
|
||||
"Broken puppets for sale. No strings attached. Also, free spaghetti!",
|
||||
"I ordered a chicken and an egg online. I'll let you know which comes first.",
|
||||
],
|
||||
},
|
||||
"default": {
|
||||
"pun": [
|
||||
"Time flies like an arrow. Fruit flies like a banana!",
|
||||
"I used to be a banker, but I lost interest.",
|
||||
"I'm reading a book on the history of glue. I can't put it down!",
|
||||
],
|
||||
"dad-joke": [
|
||||
"I'm afraid for the calendar. Its days are numbered.",
|
||||
"I only know 25 letters of the alphabet. I don't know y.",
|
||||
"Did you hear about the claustrophobic astronaut? He just needed a little space.",
|
||||
],
|
||||
"one-liner": [
|
||||
"I told my wife she was drawing her eyebrows too high. She looked surprised.",
|
||||
"I'm not lazy, I'm on energy-saving mode.",
|
||||
"Parallel lines have so much in common. It's a shame they'll never meet.",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class Processor(DynamicToolService):
|
||||
"""
|
||||
Joke tool service that demonstrates the tool service integration.
|
||||
"""
|
||||
|
||||
def __init__(self, **params):
|
||||
super(Processor, self).__init__(**params)
|
||||
logger.info("Joke service initialized")
|
||||
|
||||
async def invoke(self, user, config, arguments):
|
||||
"""
|
||||
Generate a joke based on the topic and style.
|
||||
|
||||
Args:
|
||||
user: The user requesting the joke
|
||||
config: Config values including 'style' (pun, dad-joke, one-liner)
|
||||
arguments: Arguments including 'topic' (programming, animals, food)
|
||||
|
||||
Returns:
|
||||
A personalized joke string
|
||||
"""
|
||||
# Get style from config (default: random)
|
||||
style = config.get("style", random.choice(["pun", "dad-joke", "one-liner"]))
|
||||
|
||||
# Get topic from arguments (default: random)
|
||||
topic = arguments.get("topic", "").lower()
|
||||
|
||||
# Map topic to our categories
|
||||
if "program" in topic or "code" in topic or "computer" in topic or "software" in topic:
|
||||
category = "programming"
|
||||
elif "llama" in topic:
|
||||
category = "llama"
|
||||
elif "animal" in topic or "dog" in topic or "cat" in topic or "bird" in topic:
|
||||
category = "animals"
|
||||
elif "food" in topic or "eat" in topic or "cook" in topic or "drink" in topic:
|
||||
category = "food"
|
||||
else:
|
||||
category = "default"
|
||||
|
||||
# Normalize style
|
||||
if style not in ["pun", "dad-joke", "one-liner"]:
|
||||
style = random.choice(["pun", "dad-joke", "one-liner"])
|
||||
|
||||
# Get jokes for this category and style
|
||||
jokes = JOKES.get(category, JOKES["default"]).get(style, JOKES["default"]["pun"])
|
||||
|
||||
# Pick a random joke
|
||||
joke = random.choice(jokes)
|
||||
|
||||
# Personalize the response
|
||||
response = f"Hey {user}! Here's a {style} for you:\n\n{joke}"
|
||||
|
||||
logger.debug(f"Generated joke for user={user}, style={style}, topic={topic}")
|
||||
|
||||
return response
|
||||
|
||||
@staticmethod
|
||||
def add_args(parser):
|
||||
DynamicToolService.add_args(parser)
|
||||
# Override the topic default for this service
|
||||
for action in parser._actions:
|
||||
if '--topic' in action.option_strings:
|
||||
action.default = default_topic
|
||||
break
|
||||
|
||||
|
||||
def run():
|
||||
Processor.launch(default_ident, __doc__)
|
||||
Loading…
Add table
Add a link
Reference in a new issue