Skip to content

Commit c4f25a2

Browse files
Update version to 0.6 and refine model logic
The changes in smart.py include an update to the version number from 0.5 to 0.6. The logic for selecting models based on task difficulty and reasoning requirements has been refined, adding support for an online model. Additionally, the handling of user input tags has been improved to better manage model selection and reasoning flags.
1 parent dd0eee1 commit c4f25a2

File tree

1 file changed

+46
-34
lines changed

1 file changed

+46
-34
lines changed

pipes/smart.py

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
description: SMART is a sequential multi-agent reasoning technique.
66
required_open_webui_version: 0.3.30
77
requirements: langchain-openai==0.1.24, langgraph
8-
version: 0.5
8+
version: 0.6
99
licence: MIT
1010
"""
1111

@@ -31,32 +31,30 @@
3131
Guidelines:
3232
- Don't over or estimate the difficulty of the task. If the user just wants to chat try to see that.
3333
- Don't create tasks where there aren't any. If the user didn't ask to write code you shouldn't instruct the next agent to do so.
34-
- Follow user wishes. The # tags below OVERWRITE ALL YOUR OTHER GUIDELINES. NEVER IGNORE THESE!
35-
- If the user includes "#*no" in their message, ALWAYS set reasoning to NO
36-
- If the user includes "#*yes" in their message, ALWAYS set reasoning to YES
37-
- If the user includes "#!" in their message, ALWAYS set the task difficulty to BELOW 5.
38-
- If the user includes "#!!" in their message, ALWAYS set the task difficulty to EQUAL OR ABOVE 5.
3934
4035
You should respond by following these steps:
4136
1. Within <reasoning> tags, plan what you will write in the other tags. This has to be your first step.
4237
1. First, reason about the task difficulty. What kind of task is it? What do your guidelines say about that?
4338
2. Second, reason about if the reasoning and tool use agent is needed. What do your guidelines say about that?
4439
3. Third, think about what should be contained in your prompt. Don't write the prompt here already. Just think about what should be in it.
45-
2. Within <task_difficulty> tags, write a number between 1 and 10 to indicate how difficult you think the task is. 1 being the easiest and 10 being the hardest.
46-
1. If you choose a number above or equal to 5, a bigger model will be used for the final answer. This is good for example creative tasks but bad for summarization etc. because the cost will be higher.
47-
3. Within <is_reasoning_or_tool_needed> tags, write YES or NO. This will determine if the user request will go straight to the final agent or if it will go to the reasoning and tool use agent.
48-
1. Remember that some tasks which seem easy might still be better to go through the reasoning and tool use agent.
49-
2. Try to reason if LLMs are good at solving the problem or if they usually struggle with that task.
50-
3. Categories of problems that you HAVE TO answer YES to: Any Counting task (Numbers, Letters...), Math, Programming, Logic, Problem Solving, Analysis (even simple one), Trick Questions, Puzzles, Proof Reading, Text Editing, Fact Checking, Research, ...
51-
4. Categories of problems that you HAVE TO answer NO to: Writing, Spelling, Summarizing (text, website, etc.), Translation, Simple Conversation, Simple Clarification, ...
40+
2. Within the <answer> tag, write out your final answer. Your answer should be a comma seperated list.
41+
1. First choose the model the final-agent will use. Try to find a good balance between performance and cost. Larger models are bigger.
42+
- Use #small for the simple queries or queries that mostly involve summarization or simple "mindless" work. This also invloves very simple tool use, like converting a file, etc.
43+
- Use #medium for task that requiere some creativity, writing of code, or complex tool-use.
44+
- Use #large for tasks that are mostly creative or involve the writing of complex code, math, etc.
45+
- Use #online for tasks that mostly requiere the use of the internet. Such as news or queries that will benifit greatly from up-to-date information. However, this model can not use tools.
46+
2. Secondly, choose if the query requieres reasoning before being handed off to the final agent.
47+
- Queries that requeire reasoning are especially queries where llm are bad at. Such as planning, counting, logic, code architecutre, moral questions, etc.
48+
- Queries that don't requeire reasoning are queries that are easy for llms. Such as "knowledge" questions, summarization, writing notes, simple tool use, etc.
49+
- If you think reasoning is needed, include #reasoning. If not #no-reasoning.
50+
- When you choose reasoning, you should (in most cases) choose at least the #medium model.
5251
5352
Example response:
5453
<reasoning>
5554
...
5655
(You are allowed new lines here)
5756
</reasoning>
58-
<task_difficulty>5</task_difficulty>
59-
<is_reasoning_or_tool_needed>YES</is_reasoning_or_tool_needed>
57+
<answer>#medium, #reasoning</answer>
6058
</system_instructions>"""
6159

6260
REASONING_PROMPT = """<system_instructions>
@@ -176,6 +174,9 @@ class Valves(BaseModel):
176174
HUGE_MODEL: str = Field(
177175
default="anthropic/claude-3.5-sonnet", description="Model for the largest tasks"
178176
)
177+
ONLINE_MODEL: str = Field(
178+
default="perplexity/llama-3.1-sonar-large-128k-online", description="Online Model"
179+
)
179180
REASONING_MODEL: str = Field(
180181
default="anthropic/claude-3.5-sonnet"
181182
)
@@ -249,6 +250,8 @@ async def pipe(
249250
large_model_id = self.valves.LARGE_MODEL
250251
huge_model_id = self.valves.HUGE_MODEL
251252

253+
online_model_id = self.valves.ONLINE_MODEL
254+
252255
planning_model_id = small_model_id
253256

254257
if self.valves.USE_GROQ_PLANNING_MODEL != "False":
@@ -322,41 +325,50 @@ async def pipe(
322325
content = planning_buffer
323326

324327
# Get the planning result from the xml tags
325-
task_difficulty = re.findall(r"<task_difficulty>(.*?)</task_difficulty>", content)
326-
task_difficulty = task_difficulty[0] if task_difficulty else "unknown"
328+
csv_hastag_list = re.findall(r"<answer>(.*?)</answer>", content)
329+
csv_hastag_list = csv_hastag_list[0] if csv_hastag_list else "unknown"
327330

328-
is_reasoning_needed = re.findall(r"<is_reasoning_or_tool_needed>(.*?)</is_reasoning_or_tool_needed>", content)
329-
is_reasoning_needed = is_reasoning_needed[0] if is_reasoning_needed else "unknown"
330-
331-
model_to_use_id = small_model_id
332-
if float(task_difficulty) >= 4:
331+
if "#small" in csv_hastag_list:
332+
model_to_use_id = small_model_id
333+
elif "#medium" in csv_hastag_list:
333334
model_to_use_id = large_model_id
334-
if float(task_difficulty) >= 8:
335+
elif "#large" in csv_hastag_list:
335336
model_to_use_id = huge_model_id
337+
elif "#online" in csv_hastag_list:
338+
model_to_use_id = online_model_id
339+
else:
340+
model_to_use_id = small_model_id
341+
342+
is_reasoning_needed = "YES" if "#reasoning" in csv_hastag_list else "NO"
336343

337-
await send_status(
338-
status_message=f"Planning complete. Task difficulty: {task_difficulty}. Using Model: {model_to_use_id}. Reasoning needed: {is_reasoning_needed}.",
339-
done=True,
340-
)
341344
await send_citation(
342345
url=f"SMART Planning",
343346
title="SMART Planning",
344347
content=f"{content=}",
345348
)
346349

347350
# Try to find #!, #!!, #*yes, #*no, in the user message, let them overwrite the model choice
348-
if "#!!!" in body["messages"][-1]["content"]:
351+
if "#!!!" in body["messages"][-1]["content"] or "#large" in body["messages"][-1]["content"]:
349352
model_to_use_id = huge_model_id
350-
elif "#!!" in body["messages"][-1]["content"]:
353+
elif "#!!" in body["messages"][-1]["content"] or "#medium" in body["messages"][-1]["content"]:
351354
model_to_use_id = large_model_id
352-
elif "#!" in body["messages"][-1]["content"]:
355+
elif "#!" in body["messages"][-1]["content"] or "#small" in body["messages"][-1]["content"]:
353356
model_to_use_id = small_model_id
357+
358+
if "#online" in body["messages"][-1]["content"]:
359+
is_reasoning_needed = "NO"
360+
model_to_use_id = online_model_id
354361

355362
if "#*yes" in body["messages"][-1]["content"] or "#yes" in body["messages"][-1]["content"]:
356363
is_reasoning_needed = "YES"
357364
elif "#*no" in body["messages"][-1]["content"] or "#no" in body["messages"][-1]["content"]:
358365
is_reasoning_needed = "NO"
359366

367+
await send_status(
368+
status_message=f"Planning complete. Using Model: {model_to_use_id}. Reasoning needed: {is_reasoning_needed}.",
369+
done=True,
370+
)
371+
360372
tools = []
361373
for key, value in __tools__.items():
362374
tools.append(
@@ -375,7 +387,7 @@ async def pipe(
375387

376388
if is_reasoning_needed == "NO":
377389
messages_to_use[0]["content"] = messages_to_use[0]["content"] + USER_INTERACTION_PROMPT
378-
messages_to_use[-1]["content"] = str(messages_to_use[-1]["content"]).replace("#*yes", "").replace("#*no", "").replace("#!!", "").replace("#!", "")
390+
messages_to_use[-1]["content"] = str(messages_to_use[-1]["content"]).replace("#*yes", "").replace("#*no", "").replace("#!!", "").replace("#!", "").replace("#!!!", "").replace("#no", "").replace("#yes", "").replace("#large", "").replace("#medium", "").replace("#small", "").replace("#online", "")
379391

380392
graph = create_react_agent(model_to_use, tools=tools)
381393
inputs = {"messages": body["messages"]}
@@ -404,7 +416,7 @@ async def pipe(
404416
)
405417

406418
await send_status(
407-
status_message=f"Done! Took: {round(time.time() - start_time, 1)}s.",
419+
status_message=f"Done! Took: {round(time.time() - start_time, 1)}s. Used {model_to_use_id}. Reasoning was {'used' if is_reasoning_needed == True else 'not used'}.",
408420
done=True,
409421
)
410422
return
@@ -438,7 +450,7 @@ async def pipe(
438450
if last_msg["role"] == "user":
439451
reasoning_context += f"--- LAST USER MESSAGE/PROMPT ---\n{last_msg['content']}"
440452

441-
reasoning_context = reasoning_context.replace("#*yes", "").replace("#*no", "").replace("#!!", "").replace("#!", "")
453+
reasoning_context = reasoning_context.replace("#*yes", "").replace("#*no", "").replace("#!!", "").replace("#!", "").replace("#!!!", "").replace("#no", "").replace("#yes", "").replace("#large", "").replace("#medium", "").replace("#small", "").replace("#online", "")
442454

443455
reasoning_messages = [
444456
{
@@ -592,7 +604,7 @@ async def pipe(
592604

593605
if not num_tool_calls >= 4:
594606
await send_status(
595-
status_message=f"Done! Took: {round(time.time() - start_time, 1)}s.",
607+
status_message=f"Done! Took: {round(time.time() - start_time, 1)}s. Used {model_to_use_id}. Reasoning was {'used' if is_reasoning_needed == True else 'not used'}.",
596608
done=True,
597609
)
598610
return

0 commit comments

Comments
 (0)