@tyvm/knowhow 0.0.116 → 0.0.118

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -283,19 +283,57 @@ export class CustomVariables {
283
283
  /**
284
284
  * Finds the longest common substring between two strings that is >= minLength.
285
285
  * Returns the substring or null if none found.
286
+ *
287
+ * PERF NOTE: This is O(n*m) in the worst case on the sampled chunks.
288
+ * For large strings, we sample multiple fixed-size chunks (first quarter,
289
+ * second quarter, third quarter, last quarter) so we catch patterns that
290
+ * appear anywhere in the string — not just the prefix — while keeping cost bounded.
286
291
  */
287
- private longestCommonSubstring(a: string, b: string, minLength: number): string | null {
292
+ private longestCommonSubstring(
293
+ a: string,
294
+ b: string,
295
+ minLength: number
296
+ ): string | null {
297
+ // Fast path: exact full match
298
+ if (a === b) return a.length >= minLength ? a : null;
299
+
300
+ // For large strings, sample fixed-size chunks from multiple positions
301
+ // so we catch repeated patterns anywhere in the string without O(n*m) blowup.
302
+ // Chunk size: 200 chars each → at most 200*200=40k iterations per chunk pair.
303
+ const CHUNK_SIZE = 200;
304
+
305
+ const getChunks = (s: string): string[] => {
306
+ if (s.length <= CHUNK_SIZE) return [s];
307
+ const q = Math.floor(s.length / 4);
308
+ return [
309
+ s.slice(0, CHUNK_SIZE), // first quarter
310
+ s.slice(q - CHUNK_SIZE / 2, q + CHUNK_SIZE / 2), // around 1/4 mark
311
+ s.slice(2 * q - CHUNK_SIZE / 2, 2 * q + CHUNK_SIZE / 2), // around midpoint
312
+ s.slice(3 * q - CHUNK_SIZE / 2, 3 * q + CHUNK_SIZE / 2), // around 3/4 mark
313
+ s.slice(-CHUNK_SIZE), // last quarter
314
+ ];
315
+ };
316
+
317
+ const chunksA = getChunks(a);
318
+ const chunksB = getChunks(b);
319
+
320
+ // Run LCS on each chunk pair, return the best match found
288
321
  let best = "";
289
- for (let i = 0; i < a.length - minLength + 1; i++) {
290
- for (let j = a.length; j > i + minLength - 1; j--) {
291
- const sub = a.slice(i, j);
292
- if (sub.length <= best.length) break; // already found longer
293
- if (b.includes(sub)) {
294
- best = sub;
295
- break;
322
+ for (const chunkA of chunksA) {
323
+ for (const chunkB of chunksB) {
324
+ for (let i = 0; i < chunkA.length - minLength + 1; i++) {
325
+ for (let j = chunkA.length; j > i + minLength - 1; j--) {
326
+ const sub = chunkA.slice(i, j);
327
+ if (sub.length <= best.length) break; // already found longer
328
+ if (chunkB.includes(sub)) {
329
+ best = sub;
330
+ break;
331
+ }
332
+ }
296
333
  }
297
334
  }
298
335
  }
336
+
299
337
  return best.length >= minLength ? best : null;
300
338
  }
301
339
 
@@ -81,12 +81,14 @@ export class McpService {
81
81
  mcp.authorization_token = token.trim();
82
82
  }
83
83
 
84
+ const scheme = mcp.authorization_scheme === "basic" ? "Basic" : "Bearer";
85
+
84
86
  return new StreamableHTTPClientTransport(new URL(mcp.url), {
85
87
  requestInit: {
86
88
  headers: {
87
89
  "User-Agent": knowhowMcpClient.name,
88
90
  ...(mcp.authorization_token && {
89
- Authorization: `Bearer ${mcp.authorization_token}`,
91
+ Authorization: `${scheme} ${mcp.authorization_token}`,
90
92
  }),
91
93
  },
92
94
  },
package/src/types.ts CHANGED
@@ -112,6 +112,7 @@ export type McpConfig = {
112
112
  params?: Partial<{ socket: WebSocket }>;
113
113
  authorization_token?: string;
114
114
  authorization_token_file?: string;
115
+ authorization_scheme?: "bearer" | "basic";
115
116
  };
116
117
 
117
118
  export type ModelProvider = {
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Benchmark for CustomVariables message processor.
3
+ * Tests with realistic data from the stuck agent (21k char writeFileChunk string).
4
+ * Each test has a hard timeout so we don't get frozen like the agent.
5
+ */
6
+ import { CustomVariables } from "../../src/processors/CustomVariables";
7
+ import { Message } from "../../src/clients/types";
8
+ import { ToolsService } from "../../src/services";
9
+
10
+ function makeMockToolsService(): jest.Mocked<ToolsService> {
11
+ return {
12
+ addTools: jest.fn(),
13
+ addFunctions: jest.fn(),
14
+ getTool: jest.fn().mockReturnValue(undefined),
15
+ callTool: jest.fn(),
16
+ } as any;
17
+ }
18
+
19
+ // Replicate the large string from the stuck agent
20
+ const LARGE_STRING_21K = "# Firecracker Sandbox Disk Architecture v2 — EBS-Backed Storage\n" + "x".repeat(21800);
21
+ const MEDIUM_STRING_200 = "grep -n \"diskGb\\|ebsVolume\\|lastActivityAt\\|idleTimeout\" /Users/micah/dev/knowhow-web/packages/backend/src/services/SandboxService.ts".repeat(2);
22
+ const SHORT_STRING_80 = "grep -r \"snapshot\" /Users/micah/dev/knowhow-web/packages/backend/src";
23
+
24
+ function makeToolCallMessage(toolName: string, arg: string): Message {
25
+ return {
26
+ role: "assistant",
27
+ content: null,
28
+ tool_calls: [
29
+ {
30
+ id: `call_${Math.random().toString(36).slice(2)}`,
31
+ type: "function",
32
+ function: {
33
+ name: toolName,
34
+ arguments: JSON.stringify({ content: arg }),
35
+ },
36
+ },
37
+ ],
38
+ };
39
+ }
40
+
41
+ function makeThread(extraMessages: Message[]): Message[] {
42
+ const systemMsg: Message = {
43
+ role: "system",
44
+ content: "You are a helpful assistant.",
45
+ };
46
+ return [systemMsg, ...extraMessages];
47
+ }
48
+
49
+ /**
50
+ * Run a function with a hard ms timeout.
51
+ * Returns { completed: boolean, elapsedMs: number }
52
+ */
53
+ async function runWithTimeout(
54
+ fn: () => void,
55
+ timeoutMs: number
56
+ ): Promise<{ completed: boolean; elapsedMs: number }> {
57
+ return new Promise((resolve) => {
58
+ let done = false;
59
+ const timer = setTimeout(() => {
60
+ if (!done) {
61
+ done = true;
62
+ resolve({ completed: false, elapsedMs: timeoutMs });
63
+ }
64
+ }, timeoutMs);
65
+
66
+ const start = Date.now();
67
+ // Run in next tick so setTimeout can fire
68
+ setImmediate(() => {
69
+ try {
70
+ fn();
71
+ if (!done) {
72
+ done = true;
73
+ clearTimeout(timer);
74
+ resolve({ completed: true, elapsedMs: Date.now() - start });
75
+ }
76
+ } catch (e) {
77
+ if (!done) {
78
+ done = true;
79
+ clearTimeout(timer);
80
+ resolve({ completed: true, elapsedMs: Date.now() - start });
81
+ }
82
+ }
83
+ });
84
+ });
85
+ }
86
+
87
+ describe("CustomVariables Benchmark", () => {
88
+ // Allow up to 30s for each benchmark test (jest default may be less)
89
+ jest.setTimeout(60000);
90
+
91
+ it("BENCHMARK: longestCommonSubstring with two small strings (baseline)", async () => {
92
+ const cv = new CustomVariables(makeMockToolsService());
93
+ const a = SHORT_STRING_80;
94
+ const b = "cat /Users/micah/dev/knowhow-web/packages/backend/src/services/SandboxService.ts";
95
+
96
+ const start = Date.now();
97
+ // Access the private method via cast
98
+ const result = (cv as any).longestCommonSubstring(a, b, 50);
99
+ const elapsed = Date.now() - start;
100
+
101
+ console.log(`[BENCHMARK] Small vs small (${a.length} x ${b.length} chars): ${elapsed}ms, result length: ${result?.length ?? 0}`);
102
+ expect(elapsed).toBeLessThan(100); // should be instant
103
+ });
104
+
105
+ it("BENCHMARK: longestCommonSubstring with one large string (21k) - DANGER ZONE", async () => {
106
+ const cv = new CustomVariables(makeMockToolsService());
107
+ const a = LARGE_STRING_21K;
108
+ const b = MEDIUM_STRING_200;
109
+
110
+ console.log(`[BENCHMARK] Testing LCS with strings of length ${a.length} x ${b.length}`);
111
+ console.log(`[BENCHMARK] Estimated worst-case iterations: ${a.length * b.length / 1_000_000}M`);
112
+
113
+ const { completed, elapsedMs } = await runWithTimeout(() => {
114
+ (cv as any).longestCommonSubstring(a, b, 50);
115
+ }, 5000); // 5 second timeout
116
+
117
+ console.log(`[BENCHMARK] Large (${a.length}) x Medium (${b.length}): completed=${completed}, elapsed=${elapsedMs}ms`);
118
+ if (!completed) {
119
+ console.log(`[BENCHMARK] ⚠️ LCS DID NOT COMPLETE IN 5 SECONDS - THIS IS THE BUG`);
120
+ }
121
+ // We're just measuring - not enforcing pass/fail here so it doesn't hang CI
122
+ expect(true).toBe(true);
123
+ });
124
+
125
+ it("BENCHMARK: createVariableHintProcessor with realistic agent thread (last 10 msgs)", async () => {
126
+ const cv = new CustomVariables(makeMockToolsService());
127
+
128
+ // Simulate the stuck agent's last 10 messages (from real metadata.json analysis):
129
+ // - one 124-char execCommand
130
+ // - one 67-char readFile
131
+ // - one 21,862-char writeFileChunk
132
+ const messages: Message[] = makeThread([
133
+ // Older messages (60+ of them to simulate real thread)
134
+ ...Array.from({ length: 60 }, (_, i) =>
135
+ ({
136
+ role: i % 2 === 0 ? "user" : "assistant",
137
+ content: `Message ${i}: some content about sandboxes and disk resizing plans.`,
138
+ } as Message)
139
+ ),
140
+ // Last 10 messages - the ones that get scanned
141
+ makeToolCallMessage("execCommand", "mkdir -p /Users/micah/dev/knowhow-web/.knowhow/tasks/host-compaction/"),
142
+ { role: "tool", content: "Created directory", tool_call_id: "x1" } as Message,
143
+ makeToolCallMessage("readFile", "/Users/micah/dev/knowhow-web/.knowhow/tasks/firecracker/disks.md"),
144
+ { role: "tool", content: "File contents...", tool_call_id: "x2" } as Message,
145
+ makeToolCallMessage("execCommand", MEDIUM_STRING_200.slice(0, 124)),
146
+ { role: "tool", content: "grep output", tool_call_id: "x3" } as Message,
147
+ makeToolCallMessage("readFile", "/Users/micah/dev/knowhow-web/.knowhow/tasks/firecracker/disks.md".slice(0, 67)),
148
+ { role: "tool", content: "file read", tool_call_id: "x4" } as Message,
149
+ // The killer - 21k char writeFileChunk
150
+ makeToolCallMessage("writeFileChunk", LARGE_STRING_21K),
151
+ { role: "tool", content: "written", tool_call_id: "x5" } as Message,
152
+ ]);
153
+
154
+ console.log(`[BENCHMARK] Thread has ${messages.length} messages`);
155
+ console.log(`[BENCHMARK] Total thread chars: ${JSON.stringify(messages).length}`);
156
+
157
+ const processor = cv.createRepetitionHintProcessor({
158
+ minLength: 50,
159
+ minRepetitions: 2,
160
+ minSubstringLength: 50,
161
+ recentMessagesWindow: 10,
162
+ throttleMessages: 5,
163
+ });
164
+
165
+ const { completed, elapsedMs } = await runWithTimeout(() => {
166
+ const modifiedMessages = [...messages];
167
+ processor(messages, modifiedMessages);
168
+ }, 10000); // 10 second timeout
169
+
170
+ console.log(`[BENCHMARK] createVariableHintProcessor: completed=${completed}, elapsed=${elapsedMs}ms`);
171
+ if (!completed) {
172
+ console.log(`[BENCHMARK] ⚠️ PROCESSOR DID NOT COMPLETE IN 10 SECONDS - THIS CONFIRMS THE BUG`);
173
+ }
174
+ expect(true).toBe(true);
175
+ });
176
+
177
+ it("BENCHMARK: LCS with two large strings (21k x 21k) - catastrophic case", async () => {
178
+ const cv = new CustomVariables(makeMockToolsService());
179
+ const a = LARGE_STRING_21K;
180
+ const b = LARGE_STRING_21K.split("").reverse().join(""); // different but same length
181
+
182
+ console.log(`[BENCHMARK] Testing LCS with strings of length ${a.length} x ${b.length}`);
183
+ console.log(`[BENCHMARK] Theoretical O(n*m) iterations: ${(a.length * b.length / 1_000_000).toFixed(0)}M`);
184
+
185
+ const { completed, elapsedMs } = await runWithTimeout(() => {
186
+ (cv as any).longestCommonSubstring(a, b, 50);
187
+ }, 3000); // 3 second timeout
188
+
189
+ console.log(`[BENCHMARK] Large (${a.length}) x Large (${b.length}): completed=${completed}, elapsed=${elapsedMs}ms`);
190
+ // After the fix (capping LCS input to 500 chars), this now completes instantly
191
+ expect(completed).toBe(true);
192
+ expect(elapsedMs).toBeLessThan(100); // Should be near-instant with the cap
193
+ });
194
+
195
+ it("BENCHMARK: LCS with strings capped at 500 chars - proposed fix", async () => {
196
+ const cv = new CustomVariables(makeMockToolsService());
197
+ // Simulate the fix: cap strings at 500 chars before LCS
198
+ const MAX_LCS_STRING_LENGTH = 500;
199
+ const a = LARGE_STRING_21K.slice(0, MAX_LCS_STRING_LENGTH);
200
+ const b = LARGE_STRING_21K.split("").reverse().join("").slice(0, MAX_LCS_STRING_LENGTH);
201
+
202
+ console.log(`[BENCHMARK] Testing LCS with capped strings of length ${a.length} x ${b.length}`);
203
+
204
+ const start = Date.now();
205
+ const result = (cv as any).longestCommonSubstring(a, b, 50);
206
+ const elapsed = Date.now() - start;
207
+
208
+ console.log(`[BENCHMARK] Capped (${a.length}) x Capped (${b.length}): ${elapsed}ms, result length: ${result?.length ?? 0}`);
209
+ expect(elapsed).toBeLessThan(50); // Should be instant when capped
210
+ });
211
+
212
+ it("BENCHMARK: processMessage (variable substitution) with large content - should be fast", async () => {
213
+ const cv = new CustomVariables(makeMockToolsService());
214
+
215
+ const largeMessage: Message = {
216
+ role: "assistant",
217
+ content: null,
218
+ tool_calls: [
219
+ {
220
+ id: "call_abc",
221
+ type: "function",
222
+ function: {
223
+ name: "writeFileChunk",
224
+ arguments: JSON.stringify({ content: LARGE_STRING_21K, filePath: "/tmp/test.md" }),
225
+ },
226
+ },
227
+ ],
228
+ };
229
+
230
+ const start = Date.now();
231
+ (cv as any).processMessage(largeMessage);
232
+ const elapsed = Date.now() - start;
233
+
234
+ console.log(`[BENCHMARK] processMessage with 21k char tool call: ${elapsed}ms`);
235
+ expect(elapsed).toBeLessThan(100); // substitution itself should be fast
236
+ });
237
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyvm/knowhow",
3
- "version": "0.0.116",
3
+ "version": "0.0.118",
4
4
  "description": "ai cli with plugins and agents",
5
5
  "main": "ts_build/src/index.js",
6
6
  "bin": {
@@ -10,6 +10,7 @@ const types_1 = require("./types");
10
10
  const CliChatService_1 = require("./chat/CliChatService");
11
11
  const modules_1 = require("./services/modules");
12
12
  const modules_2 = require("./commands/modules");
13
+ const mcp_1 = require("./commands/mcp");
13
14
  const workers_1 = require("./commands/workers");
14
15
  const agent_1 = require("./commands/agent");
15
16
  const misc_1 = require("./commands/misc");
@@ -54,6 +55,7 @@ async function main() {
54
55
  (0, workers_1.addCloudWorkerCommand)(program);
55
56
  (0, misc_1.addGithubCredentialsCommand)(program);
56
57
  (0, modules_2.addModulesCommand)(program);
58
+ (0, mcp_1.addMcpCommands)(program);
57
59
  try {
58
60
  const globalConfig = await (0, config_2.getGlobalConfig)();
59
61
  const allModulePaths = [
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,kDAA0C;AAC1C,qCAAkC;AAClC,qCAAyC;AACzC,qCAAsD;AACtD,mCAA4C;AAC5C,0DAAuD;AACvD,gDAAoD;AAGpD,gDAAuD;AACvD,gDAM4B;AAC5B,4CAM0B;AAC1B,0CAUyB;AAMzB,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAe,EAAE,EAAE;IACnD,MAAM,OAAO,GAAG,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAG1E,OAAO,CAAC,IAAI,CAAC,4CAA4C,OAAO,EAAE,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAI9B,eAAM,CAAC,sBAAsB,EAAE,CAAC;IAIhC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,eAAe,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,eAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;IAED,MAAM,IAAA,sBAAa,GAAE,CAAC;IACtB,MAAM,MAAM,GAAG,MAAM,IAAA,kBAAS,GAAE,CAAC;IACjC,MAAM,WAAW,GAAG,IAAI,+BAAc,CAAC,IAAA,yBAAiB,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAG1E,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC;IACzC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC;IAEjC,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,gCAAgC,CAAC;SAC7C,OAAO,CAAC,sBAAO,CAAC,CAAC;IAGpB,IAAA,qBAAc,EAAC,OAAO,CAAC,CAAC;IACxB,IAAA,sBAAe,EAAC,OAAO,CAAC,CAAC;IACzB,IAAA,uBAAgB,EAAC,OAAO,CAAC,CAAC;IAC1B,IAAA,yBAAkB,EAAC,OAAO,CAAC,CAAC;IAC5B,IAAA,uBAAgB,EAAC,OAAO,CAAC,CAAC;IAC1B,IAAA,uBAAgB,EAAC,OAAO,CAAC,CAAC;IAC1B,IAAA,yBAAkB,EAAC,OAAO,CAAC,CAAC;IAC5B,IAAA,qBAAc,EAAC,OAAO,CAAC,CAAC;IACxB,IAAA,uBAAe,EAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACzC,IAAA,qBAAa,EAAC,OAAO,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;IACpD,IAAA,uBAAe,EAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACzC,IAAA,wBAAgB,EAAC,OAAO,CAAC,CAAC;IAC1B,IAAA,0BAAkB,EAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAC5C,IAAA,0BAAgB,EAAC,OAAO,CAAC,CAAC;IAC1B,IAAA,2BAAiB,EAAC,OAAO,CAAC,CAAC;IAC3B,IAAA,0BAAgB,EAAC,OAAO,CAAC,CAAC;IAC1B,IAAA,yBAAe,EAAC,OAAO,CAAC,CAAC;IACzB,IAAA,+BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,kCAA2B,EAAC,OAAO,CAAC,CAAC;IACrC,IAAA,2BAAiB,EAAC,OAAO,CAAC,CAAC;IAK3B,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,IAAA,wBAAe,GAAE,CAAC;QAC7C,MAAM,cAAc,GAAG;YACrB,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI,EAAE,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;SAC1B,CAAC;QACF,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,mBAAmB,GAAG,IAAI,wBAAc,EAAE,CAAC;YACjD,MAAM,mBAAmB,CAAC,eAAe,CACvC,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,EACtC;gBACE,OAAO,EAAE,OAAO;aACjB,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;IAEb,CAAC;IAED,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE;SACH,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;QACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,EAAE;QACT,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function addMcpCommands(program: Command): void;