mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
feat(agent): thread runtime model/provider into per-turn context injection
This commit is contained in:
parent
bd1ceace74
commit
2e1ef6b4b1
@ -509,6 +509,8 @@ public class ReasoningNode implements NodeAction {
|
||||
String workspaceBasePath = state.value(vip.mate.agent.graph.state.MateClawStateKeys.WORKSPACE_BASE_PATH, "");
|
||||
String agentIdStr = state.value(MateClawStateKeys.AGENT_ID, "");
|
||||
String userMsg = state.value(MateClawStateKeys.USER_MESSAGE, "");
|
||||
String runtimeModelName = state.value(MateClawStateKeys.RUNTIME_MODEL_NAME, "");
|
||||
String runtimeProviderId = state.value(MateClawStateKeys.RUNTIME_PROVIDER_ID, "");
|
||||
|
||||
// Build the non-history prefix ONCE. The PTL retry branch below
|
||||
// reuses this list verbatim so the retried prompt has exactly the
|
||||
@ -517,7 +519,7 @@ public class ReasoningNode implements NodeAction {
|
||||
// segment which led to "answer regressed after compaction"
|
||||
// complaints on long sessions.
|
||||
List<Message> nonHistoryPrefix = buildNonHistoryPrefix(systemPrompt, workspaceBasePath, agentIdStr, userMsg,
|
||||
accessor.chatOrigin());
|
||||
accessor.chatOrigin(), runtimeModelName, runtimeProviderId);
|
||||
|
||||
// Append the runtime-rendered skill catalog as a SEPARATE SystemMessage
|
||||
// right after the skeleton system prompt. Keeping it out of the baked
|
||||
@ -967,10 +969,13 @@ public class ReasoningNode implements NodeAction {
|
||||
String workspaceBasePath,
|
||||
String agentIdStr,
|
||||
String userMsg,
|
||||
vip.mate.agent.context.ChatOrigin chatOrigin) {
|
||||
vip.mate.agent.context.ChatOrigin chatOrigin,
|
||||
String runtimeModelName,
|
||||
String runtimeProviderId) {
|
||||
List<Message> prefix = new ArrayList<>();
|
||||
prefix.add(new SystemMessage(systemPrompt));
|
||||
prefix.add(new UserMessage(RuntimeContextInjector.buildContextMessage(workspaceBasePath, null, chatOrigin)));
|
||||
prefix.add(new UserMessage(RuntimeContextInjector.buildContextMessage(
|
||||
workspaceBasePath, null, chatOrigin, runtimeModelName, runtimeProviderId)));
|
||||
// When this turn already recalled the user's own current project from
|
||||
// structured memory, skip auto-injecting knowledge-base reference context.
|
||||
// Otherwise the KB pages (reference material, possibly about unrelated
|
||||
|
||||
@ -169,8 +169,11 @@ public class PlanGenerationNode implements NodeAction {
|
||||
vip.mate.agent.context.ChatOrigin chatOrigin =
|
||||
state.<vip.mate.agent.context.ChatOrigin>value(MateClawStateKeys.CHAT_ORIGIN)
|
||||
.orElse(vip.mate.agent.context.ChatOrigin.EMPTY);
|
||||
String runtimeModelName = state.value(MateClawStateKeys.RUNTIME_MODEL_NAME, "");
|
||||
String runtimeProviderId = state.value(MateClawStateKeys.RUNTIME_PROVIDER_ID, "");
|
||||
promptMessages.add(new UserMessage(
|
||||
RuntimeContextInjector.buildContextMessage(workspaceBasePath, null, chatOrigin)));
|
||||
RuntimeContextInjector.buildContextMessage(
|
||||
workspaceBasePath, null, chatOrigin, runtimeModelName, runtimeProviderId)));
|
||||
|
||||
// Advertise available tools so the LLM can recognize when an action is possible,
|
||||
// but do NOT force "any tool usage implies multi-step" — single-hop tool use
|
||||
|
||||
@ -166,6 +166,8 @@ public class StepExecutionNode implements NodeAction {
|
||||
vip.mate.agent.context.ChatOrigin chatOrigin =
|
||||
state.<vip.mate.agent.context.ChatOrigin>value(MateClawStateKeys.CHAT_ORIGIN)
|
||||
.orElse(vip.mate.agent.context.ChatOrigin.EMPTY);
|
||||
String runtimeModelName = state.value(MateClawStateKeys.RUNTIME_MODEL_NAME, "");
|
||||
String runtimeProviderId = state.value(MateClawStateKeys.RUNTIME_PROVIDER_ID, "");
|
||||
|
||||
if (stepIndex >= steps.size()) {
|
||||
log.warn("[StepExecution] stepIndex {} >= steps.size() {}, skipping", stepIndex, steps.size());
|
||||
@ -195,7 +197,8 @@ public class StepExecutionNode implements NodeAction {
|
||||
planningService.updateSubPlanStatus(planId, stepIndex, "running");
|
||||
|
||||
// 构建消息列表
|
||||
List<Message> messages = buildStepMessages(accessor, step, systemPrompt, workspaceBasePath);
|
||||
List<Message> messages = buildStepMessages(accessor, step, systemPrompt, workspaceBasePath,
|
||||
runtimeModelName, runtimeProviderId);
|
||||
|
||||
// 显式工具执行循环
|
||||
String finalResult = null;
|
||||
@ -509,7 +512,8 @@ public class StepExecutionNode implements NodeAction {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private List<Message> buildStepMessages(PlanStateAccessor accessor, String step, String systemPrompt, String workspaceBasePath) {
|
||||
private List<Message> buildStepMessages(PlanStateAccessor accessor, String step, String systemPrompt,
|
||||
String workspaceBasePath, String runtimeModelName, String runtimeProviderId) {
|
||||
List<Message> messages = new ArrayList<>();
|
||||
|
||||
// Layer 1: System prompt(增强指令)
|
||||
@ -537,9 +541,10 @@ public class StepExecutionNode implements NodeAction {
|
||||
messages.add(new SystemMessage(skillCatalog));
|
||||
}
|
||||
}
|
||||
// 注入运行时上下文(当前时间 + 工作目录 + 发起者上下文)
|
||||
// 注入运行时上下文(当前时间 + 工作目录 + 发起者上下文 + 模型身份)
|
||||
messages.add(new UserMessage(
|
||||
RuntimeContextInjector.buildContextMessage(workspaceBasePath, null, accessor.chatOrigin())));
|
||||
RuntimeContextInjector.buildContextMessage(
|
||||
workspaceBasePath, null, accessor.chatOrigin(), runtimeModelName, runtimeProviderId)));
|
||||
|
||||
// Layer 2: Working context(对话历史 + 步骤结果的受控长度摘要)
|
||||
String workingContext = accessor.workingContext();
|
||||
|
||||
@ -48,7 +48,7 @@ class ReasoningNodePtlPromptTest {
|
||||
"/workspace/active",
|
||||
"42",
|
||||
"investigate the bug in module X",
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY);
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY, "", "");
|
||||
|
||||
// Three layers: System, runtime-context UserMessage, wiki UserMessage.
|
||||
assertThat(prefix).hasSize(3);
|
||||
@ -74,10 +74,10 @@ class ReasoningNodePtlPromptTest {
|
||||
|
||||
List<Message> a = node.buildNonHistoryPrefix(
|
||||
"sys", "/workspace", "42", "goal",
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY);
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY, "", "");
|
||||
List<Message> b = node.buildNonHistoryPrefix(
|
||||
"sys", "/workspace", "42", "goal",
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY);
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY, "", "");
|
||||
|
||||
assertThat(a).hasSameSizeAs(b);
|
||||
for (int i = 0; i < a.size(); i++) {
|
||||
@ -98,7 +98,7 @@ class ReasoningNodePtlPromptTest {
|
||||
"/workspace/active",
|
||||
"42",
|
||||
"investigate the bug in module X",
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY);
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY, "", "");
|
||||
|
||||
assertThat(prefix).hasSize(2);
|
||||
assertThat(prefix.get(0)).isInstanceOf(SystemMessage.class);
|
||||
@ -112,7 +112,7 @@ class ReasoningNodePtlPromptTest {
|
||||
|
||||
List<Message> prefix = node.buildNonHistoryPrefix(
|
||||
"sys", "/workspace", "not-a-number", "goal",
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY);
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY, "", "");
|
||||
|
||||
// Non-numeric agentId is the contract carried over from the
|
||||
// pre-refactor codebase — skip wiki injection rather than throwing.
|
||||
@ -132,7 +132,7 @@ class ReasoningNodePtlPromptTest {
|
||||
|
||||
List<Message> prefix = node.buildNonHistoryPrefix(
|
||||
"sys", "/workspace", "42", "goal",
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY);
|
||||
vip.mate.agent.context.ChatOrigin.EMPTY, "", "");
|
||||
|
||||
assertThat(prefix).hasSize(2);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user