Skip to content

Commit 05c5633

Browse files
authored
Merge pull request #408 from LlmKira/dev
add `/learn` command
2 parents 32389d4 + 95cd3ed commit 05c5633

File tree

14 files changed

+106
-17
lines changed

14 files changed

+106
-17
lines changed

app/middleware/llm_task.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ async def build_history_messages(self):
151151
message_run = []
152152
if isinstance(system_prompt, str):
153153
message_run.append(SystemMessage(content=system_prompt))
154-
history = await self.message_history.read(lines=10)
154+
history = await self.message_history.read(lines=8)
155155
logger.trace(f"History message {history}")
156156
for de_active_message in history:
157157
try:

app/sender/discord/__init__.py

+13
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
uid_make,
3737
save_credential,
3838
dict2markdown,
39+
learn_instruction,
3940
)
4041
from llmkira.openapi.trigger import get_trigger_loop
4142
from ...components.credential import Credential, ProviderError
@@ -262,6 +263,18 @@ async def listen_login_url_command(
262263
ephemeral=True,
263264
)
264265

266+
@client.include
267+
@crescent.command(
268+
dm_enabled=True,
269+
name="learn",
270+
description="Set instruction text",
271+
)
272+
async def listen_learn_command(ctx: crescent.Context, instruction: str):
273+
reply = await learn_instruction(
274+
uid=uid_make(__sender__, ctx.user.id), instruction=instruction
275+
)
276+
return await ctx.respond(content=convert(reply), ephemeral=True)
277+
265278
@client.include
266279
@crescent.command(
267280
dm_enabled=True,

app/sender/discord/event.py

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def help_message():
1919
`/login` - login
2020
`/login_via_url` - login via url
2121
`/env` - set environment variable, split by ; , use `/env ENV=NONE` to disable a env.
22+
`/learn` - set your system prompt, reset by `/learn reset`
2223
2324
**Please confirm that that bot instance is secure, some plugins may be dangerous on unsafe instance.**
2425
""".format(prefix=BotSetting.prefix)

app/sender/kook/__init__.py

+16
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
uid_make,
3434
save_credential,
3535
dict2markdown,
36+
learn_instruction,
3637
)
3738
from llmkira.openapi.trigger import get_trigger_loop
3839
from ...components.credential import ProviderError, Credential
@@ -275,6 +276,21 @@ async def listen_login_url_command(
275276
type=MessageTypes.KMD,
276277
)
277278

279+
@bot.command(name="learn")
280+
async def listen_learn_command(
281+
msg: Message,
282+
instruction: str,
283+
):
284+
reply = await learn_instruction(
285+
uid=uid_make(__sender__, msg.author_id),
286+
instruction=instruction,
287+
)
288+
return await msg.reply(
289+
content=convert(reply),
290+
is_temp=True,
291+
type=MessageTypes.KMD,
292+
)
293+
278294
@bot.command(name="login")
279295
async def listen_login_command(
280296
msg: Message,

app/sender/kook/event.py

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def help_message():
3838
`/login` - login openai
3939
`/login_via_url` - login via provider url
4040
`/env` - set environment variable, split by ; , use `/env ENV=NONE` to disable a env.
41+
`/learn` - set your system prompt, reset by `/learn reset`
4142
4243
**Please confirm that that bot instance is secure, some plugins may be dangerous on unsafe instance.**
4344
""".format(prefix=BotSetting.prefix)

app/sender/slack/__init__.py

+13
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
uid_make,
2525
login,
2626
dict2markdown,
27+
learn_instruction,
2728
)
2829
from app.setting.slack import BotSetting
2930
from llmkira.kv_manager.env import EnvManager
@@ -223,6 +224,18 @@ async def create_task(
223224
except Exception as e:
224225
logger.exception(e)
225226

227+
@bot.command(command="/learn")
228+
async def listen_learn_command(ack: AsyncAck, respond: AsyncRespond, command):
229+
command: SlashCommand = SlashCommand.model_validate(command)
230+
await ack()
231+
if not command.text:
232+
return
233+
_arg = command.text
234+
reply = await learn_instruction(
235+
uid=uid_make(__sender__, command.user_id), instruction=_arg
236+
)
237+
return await respond(text=reply)
238+
226239
@bot.command(command="/login")
227240
async def listen_login_command(ack: AsyncAck, respond: AsyncRespond, command):
228241
command: SlashCommand = SlashCommand.model_validate(command)

app/sender/slack/event.py

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def help_message():
2525
`/auth` - activate a task (my power),but outside the thread
2626
`/login` - login via url or raw
2727
`/env` - set environment variable, split by ; , use `/env ENV=NONE` to disable a env.
28+
`/learn` - set your system prompt, reset by `/learn reset`
2829
2930
Make sure you invite me before you call me in channel, wink~
3031

app/sender/telegram/__init__.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
login,
2323
TimerObjectContainer,
2424
dict2markdown,
25+
learn_instruction,
2526
)
2627
from app.setting.telegram import BotSetting
2728
from llmkira.kv_manager.env import EnvManager
@@ -141,7 +142,6 @@ async def create_task(message: types.Message, disable_tool_action: bool = True):
141142
message.text = message.text[5:]
142143
if message.text.startswith("/ask"):
143144
message.text = message.text[4:]
144-
message.text = message.text
145145
if not message.text:
146146
return None
147147
__used_file_id = []
@@ -227,6 +227,15 @@ async def create_task(message: types.Message, disable_tool_action: bool = True):
227227
except Exception as e:
228228
logger.exception(e)
229229

230+
@bot.message_handler(commands="learn", chat_types=["private"])
231+
async def listen_learn_command(message: types.Message):
232+
logger.debug("Debug:learn command")
233+
_cmd, _arg = parse_command(command=message.text)
234+
reply = await learn_instruction(
235+
uid=uid_make(__sender__, message.from_user.id), instruction=_arg
236+
)
237+
await bot.reply_to(message, text=reply)
238+
230239
@bot.message_handler(commands="login", chat_types=["private"])
231240
async def listen_login_command(message: types.Message):
232241
logger.debug("Debug:login command")

app/sender/telegram/event.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@
77

88
def help_message():
99
return """
10-
/help - HELP YOURSELF
11-
/chat - Chat with me :)
12-
/task - Function enable
13-
/ask - Chat with func_disable, 禁止函数
14-
/tool - 工具列表
15-
/clear - 删除自己的记录
16-
/auth - POWER
10+
/help - show help message
11+
/chat - just want to chat with me
12+
/task - chat with function_enable
13+
/ask - chat with function_disable
14+
/tool - check all useful tools
15+
/clear - clear the chat history
16+
/auth - auth the tool_call
17+
/learn - set your system prompt, reset by `/learn reset`
1718
1819
Private Chat Only:
1920
/login - login via url or something
20-
/env - 配置变量 split by ; , use `/env ENV=NONE` to disable a env.
21+
/env - set v-env split by ; , use `/env ENV=NONE` to disable a env.
2122
2223
!Please confirm that that bot instance is secure, some plugins may be dangerous on unsafe instance.
2324
"""

app/sender/util_func.py

+31
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from app.components.credential import Credential, ProviderError
1414
from app.components.user_manager import USER_MANAGER
15+
from llmkira.kv_manager.instruction import InstructionManager
1516
from llmkira.task import Task
1617
from llmkira.task.snapshot import SnapData, global_snapshot_storage
1718

@@ -110,6 +111,11 @@ async def auth_reloader(snapshot_credential: str, platform: str, user_id: str) -
110111

111112

112113
def split_setting_string(input_string):
114+
"""
115+
Split setting string
116+
:param input_string: input string
117+
:return: list or None
118+
"""
113119
if not isinstance(input_string, str):
114120
return None
115121
segments = input_string.split("$")
@@ -135,7 +141,32 @@ async def save_credential(uid, credential: Credential):
135141
await USER_MANAGER.save(user_model=user)
136142

137143

144+
async def learn_instruction(uid: str, instruction: str) -> str:
145+
"""
146+
Set instruction text
147+
:param uid: uid_make
148+
:param instruction: instruction text
149+
:return: str message
150+
"""
151+
if len(instruction) > 1500:
152+
return "your instruction text length should be less than 1500"
153+
manager = InstructionManager(user_id=uid)
154+
if len(instruction) < 7:
155+
instruction = ""
156+
await manager.set_instruction(instruction)
157+
return "I already reset your instruction to default..."
158+
else:
159+
await manager.set_instruction(instruction)
160+
return "I keep it in my mind!"
161+
162+
138163
async def login(uid: str, arg_string) -> str:
164+
"""
165+
Login as provider or model
166+
:param uid: uid_make
167+
:param arg_string: input string
168+
:return: str message
169+
"""
139170
error = telegramify_markdown.convert(
140171
"🔑 **Incorrect format.**\n"
141172
"You can set it via `https://<something api.openai.com>/v1$<api key>"

llmkira/extra/plugins/search/engine.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ async def search_in_duckduckgo(search_sentence: str):
6262
_build_result.append(
6363
SearchEngineResult(
6464
title=result.get("title", "Undefined"),
65-
link=result.get("Href", "Undefined"),
65+
link=result.get("href", "Undefined"),
6666
snippet=result.get("body", "Undefined"),
6767
)
6868
)

llmkira/kv_manager/instruction.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ def prefix(self, key: str) -> str:
2323
return f"instruction:{key}"
2424

2525
async def read_instruction(self) -> str:
26+
"""
27+
读取指令,如果没有指令则返回默认指令,指令长度大于5,否则返回默认指令
28+
"""
2629
result = await self.read_data(self.user_id)
27-
if not result:
28-
return f"Now={time_now()}\n{DEFAULT_INSTRUCTION}"
29-
return f"Now={time_now()}\n{result}"
30+
if isinstance(result, str) and len(result) > 5:
31+
return f"Now={time_now()}\n{result}"
32+
return f"Now={time_now()}\n{DEFAULT_INSTRUCTION}"
3033

3134
async def set_instruction(self, instruction: str) -> str:
3235
if not isinstance(instruction, str):

llmkira/openapi/trigger/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ async def get_trigger_loop(platform_name: str, message: str, uid: str = None):
4444
message: Message Content
4545
:return 如果有触发,则返回触发的action,否则返回None 代表没有操作
4646
"""
47-
sorted(__trigger_phrases__, key=lambda x: x.priority)
47+
trigger_sorted = sorted(__trigger_phrases__, key=lambda x: x.priority)
4848
if not message:
4949
message = ""
50-
for trigger in __trigger_phrases__:
50+
for trigger in trigger_sorted:
5151
if trigger.on_platform == platform_name:
5252
try:
5353
if await trigger.on_func(message, uid):

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "llmkira"
3-
version = "1.0.4"
3+
version = "1.0.5"
44
description = "A chain message bot based on OpenAI"
55
authors = [
66
{ name = "sudoskys", email = "[email protected]" },

0 commit comments

Comments
 (0)