Darochin commited on
Commit
5b8dadc
·
verified ·
1 Parent(s): ee24154

Add files using upload-large-folder tool

Browse files
src/auto-reply/reply/commands-context-report.test.ts CHANGED
@@ -32,6 +32,15 @@ function makeParams(
32
  bootstrapMaxChars: options?.omitBootstrapLimits ? undefined : 20_000,
33
  bootstrapTotalMaxChars: options?.omitBootstrapLimits ? undefined : 150_000,
34
  sandbox: { mode: "off", sandboxed: false },
 
 
 
 
 
 
 
 
 
35
  systemPrompt: {
36
  chars: 1_000,
37
  projectContextChars: 500,
@@ -89,4 +98,11 @@ describe("buildContextReply", () => {
89
  expect(result.text).toContain("Bootstrap max/total: 150,000 chars");
90
  expect(result.text).not.toContain("Bootstrap max/file: ? chars");
91
  });
 
 
 
 
 
 
 
92
  });
 
32
  bootstrapMaxChars: options?.omitBootstrapLimits ? undefined : 20_000,
33
  bootstrapTotalMaxChars: options?.omitBootstrapLimits ? undefined : 150_000,
34
  sandbox: { mode: "off", sandboxed: false },
35
+ preparation: {
36
+ totalMs: 123,
37
+ skillsMs: 11,
38
+ bootstrapMs: 22,
39
+ toolsMs: 33,
40
+ runtimeInfoMs: 4,
41
+ docsPathMs: 5,
42
+ systemPromptBuildMs: 6,
43
+ },
44
  systemPrompt: {
45
  chars: 1_000,
46
  projectContextChars: 500,
 
98
  expect(result.text).toContain("Bootstrap max/total: 150,000 chars");
99
  expect(result.text).not.toContain("Bootstrap max/file: ? chars");
100
  });
101
+
102
+ it("shows prompt preparation timings in detail mode when available", async () => {
103
+ const result = await buildContextReply(makeParams("/context detail", false));
104
+ expect(result.text).toContain("Prompt prep total: 123 ms");
105
+ expect(result.text).toContain("- bootstrap/context: 22 ms");
106
+ expect(result.text).toContain("- system prompt build: 6 ms");
107
+ });
108
  });
src/auto-reply/reply/commands-context-report.ts CHANGED
@@ -21,6 +21,10 @@ function formatCharsAndTokens(chars: number): string {
21
  return `${formatInt(chars)} chars (~${formatInt(estimateTokensFromChars(chars))} tok)`;
22
  }
23
 
 
 
 
 
24
  function parseContextArgs(commandBodyNormalized: string): string {
25
  if (commandBodyNormalized === "/context") {
26
  return "";
@@ -52,8 +56,15 @@ async function resolveContextReport(
52
 
53
  const bootstrapMaxChars = resolveBootstrapMaxChars(params.cfg);
54
  const bootstrapTotalMaxChars = resolveBootstrapTotalMaxChars(params.cfg);
55
- const { systemPrompt, tools, skillsPrompt, bootstrapFiles, injectedFiles, sandboxRuntime } =
56
- await resolveCommandsSystemPromptBundle(params);
 
 
 
 
 
 
 
57
 
58
  return buildSystemPromptReport({
59
  source: "estimate",
@@ -66,6 +77,7 @@ async function resolveContextReport(
66
  bootstrapMaxChars,
67
  bootstrapTotalMaxChars,
68
  sandbox: { mode: sandboxRuntime.mode, sandboxed: sandboxRuntime.sandboxed },
 
69
  systemPrompt,
70
  bootstrapFiles,
71
  injectedFiles,
@@ -141,6 +153,18 @@ export async function buildContextReply(params: HandleCommandsParams): Promise<R
141
  ? `Tools: ${formatNameList(toolNames, 30)}`
142
  : "Tools: (none)";
143
  const systemPromptLine = `System prompt (${report.source}): ${formatCharsAndTokens(report.systemPrompt.chars)} (Project Context ${formatCharsAndTokens(report.systemPrompt.projectContextChars)})`;
 
 
 
 
 
 
 
 
 
 
 
 
144
  const workspaceLabel = report.workspaceDir ?? params.workspaceDir;
145
  const bootstrapMaxChars =
146
  typeof report.bootstrapMaxChars === "number" &&
@@ -200,6 +224,7 @@ export async function buildContextReply(params: HandleCommandsParams): Promise<R
200
  `Bootstrap max/total: ${bootstrapTotalLabel}`,
201
  sandboxLine,
202
  systemPromptLine,
 
203
  ...(bootstrapWarningLines.length ? ["", ...bootstrapWarningLines] : []),
204
  "",
205
  "Injected workspace files:",
 
21
  return `${formatInt(chars)} chars (~${formatInt(estimateTokensFromChars(chars))} tok)`;
22
  }
23
 
24
+ function formatDurationMs(ms: number): string {
25
+ return `${formatInt(ms)} ms`;
26
+ }
27
+
28
  function parseContextArgs(commandBodyNormalized: string): string {
29
  if (commandBodyNormalized === "/context") {
30
  return "";
 
56
 
57
  const bootstrapMaxChars = resolveBootstrapMaxChars(params.cfg);
58
  const bootstrapTotalMaxChars = resolveBootstrapTotalMaxChars(params.cfg);
59
+ const {
60
+ systemPrompt,
61
+ tools,
62
+ skillsPrompt,
63
+ bootstrapFiles,
64
+ injectedFiles,
65
+ sandboxRuntime,
66
+ preparation,
67
+ } = await resolveCommandsSystemPromptBundle(params);
68
 
69
  return buildSystemPromptReport({
70
  source: "estimate",
 
77
  bootstrapMaxChars,
78
  bootstrapTotalMaxChars,
79
  sandbox: { mode: sandboxRuntime.mode, sandboxed: sandboxRuntime.sandboxed },
80
+ preparation,
81
  systemPrompt,
82
  bootstrapFiles,
83
  injectedFiles,
 
153
  ? `Tools: ${formatNameList(toolNames, 30)}`
154
  : "Tools: (none)";
155
  const systemPromptLine = `System prompt (${report.source}): ${formatCharsAndTokens(report.systemPrompt.chars)} (Project Context ${formatCharsAndTokens(report.systemPrompt.projectContextChars)})`;
156
+ const preparation = report.preparation;
157
+ const prepLines = preparation
158
+ ? [
159
+ `Prompt prep total: ${formatDurationMs(preparation.totalMs)}`,
160
+ `- skills: ${formatDurationMs(preparation.skillsMs ?? 0)}`,
161
+ `- bootstrap/context: ${formatDurationMs(preparation.bootstrapMs ?? 0)}`,
162
+ `- tools: ${formatDurationMs(preparation.toolsMs ?? 0)}`,
163
+ `- runtime info: ${formatDurationMs(preparation.runtimeInfoMs ?? 0)}`,
164
+ `- docs path: ${formatDurationMs(preparation.docsPathMs ?? 0)}`,
165
+ `- system prompt build: ${formatDurationMs(preparation.systemPromptBuildMs ?? 0)}`,
166
+ ]
167
+ : [];
168
  const workspaceLabel = report.workspaceDir ?? params.workspaceDir;
169
  const bootstrapMaxChars =
170
  typeof report.bootstrapMaxChars === "number" &&
 
224
  `Bootstrap max/total: ${bootstrapTotalLabel}`,
225
  sandboxLine,
226
  systemPromptLine,
227
+ ...(prepLines.length ? ["", ...prepLines] : []),
228
  ...(bootstrapWarningLines.length ? ["", ...bootstrapWarningLines] : []),
229
  "",
230
  "Injected workspace files:",
src/auto-reply/reply/commands-system-prompt.ts CHANGED
@@ -22,18 +22,30 @@ export type CommandsSystemPromptBundle = {
22
  bootstrapFiles: WorkspaceBootstrapFile[];
23
  injectedFiles: EmbeddedContextFile[];
24
  sandboxRuntime: ReturnType<typeof resolveSandboxRuntimeStatus>;
 
 
 
 
 
 
 
 
25
  };
26
 
27
  export async function resolveCommandsSystemPromptBundle(
28
  params: HandleCommandsParams,
29
  ): Promise<CommandsSystemPromptBundle> {
30
  const workspaceDir = params.workspaceDir;
 
 
31
  const { bootstrapFiles, contextFiles: injectedFiles } = await resolveBootstrapContextForRun({
32
  workspaceDir,
33
  config: params.cfg,
34
  sessionKey: params.sessionKey,
35
  sessionId: params.sessionEntry?.sessionId,
36
  });
 
 
37
  const skillsSnapshot = (() => {
38
  try {
39
  return buildWorkspaceSkillSnapshot(workspaceDir, {
@@ -45,11 +57,13 @@ export async function resolveCommandsSystemPromptBundle(
45
  return { prompt: "", skills: [], resolvedSkills: [] };
46
  }
47
  })();
 
48
  const skillsPrompt = skillsSnapshot.prompt ?? "";
49
  const sandboxRuntime = resolveSandboxRuntimeStatus({
50
  cfg: params.cfg,
51
  sessionKey: params.ctx.SessionKey ?? params.sessionKey,
52
  });
 
53
  const tools = (() => {
54
  try {
55
  return createOpenClawCodingTools({
@@ -70,6 +84,7 @@ export async function resolveCommandsSystemPromptBundle(
70
  return [];
71
  }
72
  })();
 
73
  const toolSummaries = buildToolSummaryMap(tools);
74
  const toolNames = tools.map((t) => t.name);
75
  const { sessionAgentId } = resolveSessionAgentIds({
@@ -82,6 +97,7 @@ export async function resolveCommandsSystemPromptBundle(
82
  agentId: sessionAgentId,
83
  });
84
  const defaultModelLabel = `${defaultModelRef.provider}/${defaultModelRef.model}`;
 
85
  const { runtimeInfo, userTimezone, userTime, userTimeFormat } = buildSystemPromptParams({
86
  config: params.cfg,
87
  agentId: sessionAgentId,
@@ -96,6 +112,7 @@ export async function resolveCommandsSystemPromptBundle(
96
  defaultModel: defaultModelLabel,
97
  },
98
  });
 
99
  const sandboxInfo = sandboxRuntime.sandboxed
100
  ? {
101
  enabled: true,
@@ -109,6 +126,7 @@ export async function resolveCommandsSystemPromptBundle(
109
  : { enabled: false };
110
  const ttsHint = params.cfg ? buildTtsSystemPromptHint(params.cfg) : undefined;
111
 
 
112
  const systemPrompt = buildAgentSystemPrompt({
113
  workspaceDir,
114
  defaultThinkLevel: params.resolvedThinkLevel,
@@ -131,6 +149,22 @@ export async function resolveCommandsSystemPromptBundle(
131
  sandboxInfo,
132
  memoryCitationsMode: params.cfg?.memory?.citations,
133
  });
 
134
 
135
- return { systemPrompt, tools, skillsPrompt, bootstrapFiles, injectedFiles, sandboxRuntime };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
 
22
  bootstrapFiles: WorkspaceBootstrapFile[];
23
  injectedFiles: EmbeddedContextFile[];
24
  sandboxRuntime: ReturnType<typeof resolveSandboxRuntimeStatus>;
25
+ preparation: {
26
+ totalMs: number;
27
+ skillsMs?: number;
28
+ bootstrapMs?: number;
29
+ toolsMs?: number;
30
+ runtimeInfoMs?: number;
31
+ systemPromptBuildMs?: number;
32
+ };
33
  };
34
 
35
  export async function resolveCommandsSystemPromptBundle(
36
  params: HandleCommandsParams,
37
  ): Promise<CommandsSystemPromptBundle> {
38
  const workspaceDir = params.workspaceDir;
39
+ const preparationStartedAt = Date.now();
40
+ const bootstrapStartedAt = Date.now();
41
  const { bootstrapFiles, contextFiles: injectedFiles } = await resolveBootstrapContextForRun({
42
  workspaceDir,
43
  config: params.cfg,
44
  sessionKey: params.sessionKey,
45
  sessionId: params.sessionEntry?.sessionId,
46
  });
47
+ const bootstrapMs = Date.now() - bootstrapStartedAt;
48
+ const skillsStartedAt = Date.now();
49
  const skillsSnapshot = (() => {
50
  try {
51
  return buildWorkspaceSkillSnapshot(workspaceDir, {
 
57
  return { prompt: "", skills: [], resolvedSkills: [] };
58
  }
59
  })();
60
+ const skillsMs = Date.now() - skillsStartedAt;
61
  const skillsPrompt = skillsSnapshot.prompt ?? "";
62
  const sandboxRuntime = resolveSandboxRuntimeStatus({
63
  cfg: params.cfg,
64
  sessionKey: params.ctx.SessionKey ?? params.sessionKey,
65
  });
66
+ const toolsStartedAt = Date.now();
67
  const tools = (() => {
68
  try {
69
  return createOpenClawCodingTools({
 
84
  return [];
85
  }
86
  })();
87
+ const toolsMs = Date.now() - toolsStartedAt;
88
  const toolSummaries = buildToolSummaryMap(tools);
89
  const toolNames = tools.map((t) => t.name);
90
  const { sessionAgentId } = resolveSessionAgentIds({
 
97
  agentId: sessionAgentId,
98
  });
99
  const defaultModelLabel = `${defaultModelRef.provider}/${defaultModelRef.model}`;
100
+ const runtimeInfoStartedAt = Date.now();
101
  const { runtimeInfo, userTimezone, userTime, userTimeFormat } = buildSystemPromptParams({
102
  config: params.cfg,
103
  agentId: sessionAgentId,
 
112
  defaultModel: defaultModelLabel,
113
  },
114
  });
115
+ const runtimeInfoMs = Date.now() - runtimeInfoStartedAt;
116
  const sandboxInfo = sandboxRuntime.sandboxed
117
  ? {
118
  enabled: true,
 
126
  : { enabled: false };
127
  const ttsHint = params.cfg ? buildTtsSystemPromptHint(params.cfg) : undefined;
128
 
129
+ const systemPromptBuildStartedAt = Date.now();
130
  const systemPrompt = buildAgentSystemPrompt({
131
  workspaceDir,
132
  defaultThinkLevel: params.resolvedThinkLevel,
 
149
  sandboxInfo,
150
  memoryCitationsMode: params.cfg?.memory?.citations,
151
  });
152
+ const systemPromptBuildMs = Date.now() - systemPromptBuildStartedAt;
153
 
154
+ return {
155
+ systemPrompt,
156
+ tools,
157
+ skillsPrompt,
158
+ bootstrapFiles,
159
+ injectedFiles,
160
+ sandboxRuntime,
161
+ preparation: {
162
+ totalMs: Date.now() - preparationStartedAt,
163
+ skillsMs,
164
+ bootstrapMs,
165
+ toolsMs,
166
+ runtimeInfoMs,
167
+ systemPromptBuildMs,
168
+ },
169
+ };
170
  }