Skip to content

Commit 0c842de

Browse files
committed
arch(core): add sop table/update task prompts
1 parent eec6858 commit 0c842de

14 files changed

Lines changed: 233 additions & 321 deletions

File tree

src/server/core/acontext_core/llm/agent/task.py

Lines changed: 0 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -185,157 +185,3 @@ async def task_agent_curd(
185185
break
186186
already_iterations += 1
187187
return Result.resolve(None)
188-
189-
190-
# @track_process
191-
# async def task_agent_curd_debug(
192-
# project_id: asUUID,
193-
# session_id: asUUID,
194-
# previous_messages: List[MessageBlob],
195-
# messages: List[MessageBlob],
196-
# max_iterations=3, # task curd agent only receive one turn of actions
197-
# ) -> Result[None]:
198-
# async with DB_CLIENT.get_session_context() as db_session:
199-
# r = await TD.fetch_current_tasks(db_session, session_id)
200-
# tasks, eil = r.unpack()
201-
# if eil:
202-
# return r
203-
204-
# r = await TD.fetch_planning_task(db_session, session_id)
205-
# planning_section, eil = r.unpack()
206-
# if eil:
207-
# return r
208-
209-
# task_section = pack_task_section(tasks)
210-
# previous_messages_section = pack_previous_messages_section(
211-
# planning_section, tasks, previous_messages
212-
# )
213-
# current_messages_section = pack_current_message_with_ids(messages)
214-
215-
# LOG.info(f"Task Section: {task_section}")
216-
# LOG.info(f"Previous Messages Section: {previous_messages_section}")
217-
# LOG.info(f"Current Messages Section: {current_messages_section}")
218-
219-
# json_tools = [tool.model_dump() for tool in TaskPrompt.tool_schema()]
220-
# already_iterations = 0
221-
# _messages = [
222-
# {
223-
# "role": "user",
224-
# "content": TaskPrompt.pack_task_input(
225-
# previous_messages_section, current_messages_section, task_section
226-
# ),
227-
# }
228-
# ]
229-
230-
# FAKE_TOOLS = {
231-
# 0: [
232-
# {
233-
# "id": "1",
234-
# "type": "function",
235-
# "function": {
236-
# "name": "insert_task",
237-
# "arguments": {
238-
# "after_task_order": 0,
239-
# "task_description": "Search and collect the latest information about iPhone 15 Pro Max",
240-
# },
241-
# },
242-
# },
243-
# {
244-
# "id": "2",
245-
# "type": "function",
246-
# "function": {
247-
# "name": "insert_task",
248-
# "arguments": {
249-
# "after_task_order": 1,
250-
# "task_description": "Report the collected information about iPhone 15 Pro Max to the user",
251-
# },
252-
# },
253-
# },
254-
# ],
255-
# 1: [
256-
# {
257-
# "id": "1",
258-
# "type": "function",
259-
# "function": {
260-
# "name": "append_messages_to_task",
261-
# "arguments": {"task_order": 1, "message_ids": [4, 5, 6, 7, 8]},
262-
# },
263-
# },
264-
# {
265-
# "id": "2",
266-
# "type": "function",
267-
# "function": {
268-
# "name": "update_task",
269-
# "arguments": {"task_order": 1, "task_status": "success"},
270-
# },
271-
# },
272-
# {
273-
# "id": "3",
274-
# "type": "function",
275-
# "function": {
276-
# "name": "append_messages_to_task",
277-
# "arguments": {"task_order": 2, "message_ids": [9]},
278-
# },
279-
# },
280-
# {
281-
# "id": "4",
282-
# "type": "function",
283-
# "function": {
284-
# "name": "update_task",
285-
# "arguments": {"task_order": 2, "task_status": "success"},
286-
# },
287-
# },
288-
# ],
289-
# }
290-
# while already_iterations < max_iterations:
291-
# from ...schema.llm import LLMToolCall
292-
293-
# if already_iterations not in FAKE_TOOLS:
294-
# print("No fake tools found, stop iterations")
295-
# break
296-
# use_tools = FAKE_TOOLS[already_iterations]
297-
# use_tools = [LLMToolCall(**tool) for tool in use_tools]
298-
# just_finish = False
299-
# tool_response = []
300-
# USE_CTX = None
301-
# for tool_call in use_tools:
302-
# try:
303-
# tool_name = tool_call.function.name
304-
# if tool_name == "finish":
305-
# just_finish = True
306-
# continue
307-
# tool_arguments = tool_call.function.arguments
308-
# tool = TASK_TOOLS[tool_name]
309-
# with bound_logging_vars(tool=tool_name):
310-
# async with DB_CLIENT.get_session_context() as db_session:
311-
# USE_CTX = await build_task_ctx(
312-
# db_session,
313-
# project_id,
314-
# session_id,
315-
# messages,
316-
# before_use_ctx=USE_CTX,
317-
# )
318-
# r = await tool.handler(USE_CTX, tool_arguments)
319-
# t, eil = r.unpack()
320-
# if eil:
321-
# return r
322-
# LOG.info(f"Tool Call: {tool_name} - {tool_arguments} -> {t}")
323-
# tool_response.append(
324-
# {
325-
# "role": "tool",
326-
# "tool_call_id": tool_call.id,
327-
# "content": t,
328-
# }
329-
# )
330-
# if tool_name in NEED_UPDATE_CTX:
331-
# USE_CTX = None
332-
# except KeyError as e:
333-
# return Result.reject(f"Tool {tool_name} not found: {str(e)}")
334-
# except Exception as e:
335-
# return Result.reject(f"Tool {tool_name} error: {str(e)}")
336-
# _messages.extend(tool_response)
337-
# if just_finish:
338-
# LOG.info("finish function is called")
339-
# break
340-
# already_iterations += 1
341-
# return Result.resolve(None)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import re
2+
from typing import List
3+
from urllib import response
4+
from ...env import LOG, DEFAULT_CORE_CONFIG, bound_logging_vars
5+
from ...infra.db import AsyncSession, DB_CLIENT
6+
from ...schema.result import Result
7+
from ...schema.utils import asUUID
8+
from ...schema.session.task import TaskSchema, TaskStatus
9+
from ...schema.session.message import MessageBlob
10+
from ...service.data import task as TD
11+
from ..complete import llm_complete, response_to_sendable_message
12+
from ..prompt.task import TaskPrompt, TASK_TOOLS
13+
from ...util.generate_ids import track_process
14+
from ..tool.sop_lib.ctx import SOPCtx
15+
16+
17+
@track_process
18+
async def sop_agent_curd(
19+
project_id: asUUID,
20+
space_id: asUUID,
21+
planning_task: TaskSchema,
22+
current_task: TaskSchema,
23+
max_iterations=3, # task curd agent only receive one turn of actions
24+
):
25+
pass

src/server/core/acontext_core/llm/prompt/task.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def system_prompt(cls) -> str:
2929
## Planning Detection
3030
- Planning messages often consist of user and agent discussions, clarify what's tasks to do at next.
3131
- Append those messages to planning section.
32+
- Make sure the planning section have the full context of user requirements.
3233
3334
## Task Creation/Modifcation
3435
- Tasks are often confirmed by the agent's response to user's requirements, don't invent them.
@@ -50,10 +51,10 @@ def system_prompt(cls) -> str:
5051
- Update task statuses or descriptions when confident about relationships
5152
5253
## Update Task Status
53-
- `running`: When task work begins or is actively discussed
54-
- `success`: When completion is confirmed or deliverables provided
55-
- `failed`: When explicit errors occur or tasks are abandoned
5654
- `pending`: For tasks not yet started
55+
- `running`: When task work begins, or re-run because the previous works were failed or wrong.
56+
- `failed`: When explicit errors occur or tasks are abandoned, or user directly tell that some tasks are failed or wrong.
57+
- `success`: Only when task's completion is confirmed by user, or agent starts to process the next task without explicitly report errors or failure.
5758
5859
5960
## Input Format
@@ -66,12 +67,15 @@ def system_prompt(cls) -> str:
6667
## Report your Thinking
6768
Use extremely brief wordings to report:
6869
1. Any user requirement or planning?
69-
2. How existing tasks are related to current conversation?
70-
3. Any new task is created?
71-
4. Which Messages are contributed to planning? Which of them are contributed to which task?
72-
5. Which task's status/description need to be updated?
73-
6. Describe your tool-call actions to correctly manage the tasks.
74-
7. Confirm your will call `finish` tool after every tools are called
70+
2. Does the user report that any task failed and need to re-run?
71+
3. How existing tasks are related to current conversation?
72+
4. Any new task is created?
73+
5. Which Messages are contributed to planning?
74+
6. Which of them are contributed to which task?
75+
7. Which task's status/description need to be updated?
76+
8. Briefly describe your tool-call actions to correctly manage the tasks.
77+
78+
Make sure your will call `finish` tool after every tools are called
7579
"""
7680

7781
@classmethod

src/server/core/acontext_core/llm/tool/sop_lib/ctx.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
class SOPCtx:
88
db_session: AsyncSession
99
project_id: asUUID
10-
session_id: asUUID
10+
space_id: asUUID
11+
task_id: asUUID

src/server/core/acontext_core/llm/tool/task_lib/append.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ async def _append_messages_to_task_handler(
3737
)
3838
if actually_task.status in (TaskStatus.SUCCESS, TaskStatus.FAILED):
3939
return Result.resolve(
40-
f"Task {task_order} is already {actually_task.status}, appending failed."
40+
f"Appending failed. Task {task_order} is already {actually_task.status}. Update its status to 'running' first then append messages."
4141
)
4242
r = await TD.append_messages_to_task(
4343
ctx.db_session,
@@ -62,7 +62,7 @@ async def _append_messages_to_task_handler(
6262
"description": """Link current message ids to a task for tracking progress and context.
6363
Use this to associate conversation messages with relevant tasks.
6464
Make sure you append messages first(if any), then update the task status.
65-
If the task is marked as 'success' or 'failed', don't append messages to it.""",
65+
If you decide to append message to a task marked as 'success' or 'failed', update it's status to 'running' first""",
6666
"parameters": {
6767
"type": "object",
6868
"properties": {

src/server/core/acontext_core/schema/block/sop_block.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
class SOPStep(BaseModel):
77
tool_name: str
88
tool_arguments_with_placeholder: dict[str, Any]
9-
purpose_annotation: Optional[str] = None
9+
props: Optional[dict] = None
1010

1111

1212
class SOPData(BaseModel):
1313
use_when: str
1414
notes: str
15-
sop: List[SOPStep]
15+
tool_sops: List[SOPStep]
1616

1717

1818
class SOPBlock(SOPData):

src/server/core/acontext_core/schema/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ class ProjectConfig(BaseModel):
99
project_session_message_buffer_max_turns: int = 6
1010
project_session_message_buffer_max_overflow: int = 12
1111
project_session_message_buffer_ttl_seconds: int = 10
12+
default_task_agent_max_iterations: int = 3
13+
default_sop_agent_max_iterations: int = 3
1214

1315

1416
class CoreConfig(BaseModel):

src/server/core/acontext_core/schema/orm/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from .message import Message, Part, Asset, ToolCallMeta
66
from .task import Task
77
from .block import Block
8+
from .tool_reference import ToolReference
9+
from .tool_sop import ToolSOP
810

911
__all__ = [
1012
"ORM_BASE",
@@ -17,4 +19,6 @@
1719
"Asset",
1820
"Task",
1921
"Block",
22+
"ToolReference",
23+
"ToolSOP",
2024
]

src/server/core/acontext_core/schema/orm/block.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,19 @@
3131
"name": "text",
3232
"allow_children": True,
3333
"require_parent": True,
34+
"props_schema": {
35+
"use_when": str,
36+
"notes": str,
37+
},
3438
},
3539
"sop": {
3640
"name": "sop",
3741
"allow_children": True,
3842
"require_parent": True,
43+
"props_schema": {
44+
"use_when": str,
45+
"notes": str,
46+
},
3947
},
4048
}
4149

src/server/core/acontext_core/schema/orm/tool_sop.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
class ToolSOP(CommonMixin):
1818
__tablename__ = "tool_sops"
1919

20-
__table_args__ = (Index("ix_tool_sop_project_id", "project_id"),)
20+
__table_args__ = (Index("ix_tool_sop_tool_reference_id", "tool_reference_id"),)
2121

22-
purpose_annotation: str = field(metadata={"db": Column(String, nullable=False)})
2322
placeholder_arguments: dict = field(metadata={"db": Column(JSONB, nullable=False)})
2423

25-
tool_id: asUUID = field(
24+
tool_reference_id: asUUID = field(
2625
metadata={
2726
"db": Column(
2827
UUID(as_uuid=True),
@@ -41,6 +40,10 @@ class ToolSOP(CommonMixin):
4140
}
4241
)
4342

43+
props: Optional[dict] = field(
44+
default=None, metadata={"db": Column(JSONB, nullable=True)}
45+
)
46+
4447
# Relationships
4548
tool_reference: "ToolReference" = field(
4649
init=False,

0 commit comments

Comments
 (0)