Showing the changes to packages/kernel (2 of 2 files). Show all
Unified · Split
| @@ -41,6 +41,12 @@ const createToolCaller = (toolPath) => (args) => · 40 unmodified lines | |||
| 41 | }); | 41 | }); |
| 42 | }); | 42 | }); |
| 43 | 43 | ||
| 44 | const toolsEnumerationError = (path) => | ||
| 45 | new Error( | ||
| 46 | (path.length === 0 ? "tools" : "tools." + path.join(".")) + | ||
| 47 | ' is a lazy proxy and cannot be enumerated. Use tools.search({ query: "..." }) to find tools, or tools.executor.coreTools.connections.list({}) to list saved connections.', | ||
| 48 | ); | ||
| 49 | |||
| 44 | const createToolsProxy = (path = []) => { | 50 | const createToolsProxy = (path = []) => { |
| 45 | const callable = () => undefined; | 51 | const callable = () => undefined; |
| 46 | 52 | ||
| @@ -50,6 +56,12 @@ const createToolsProxy = (path = []) => { · 3 unmodified lines | |||
| 50 | if (typeof prop !== "string") return undefined; | 56 | if (typeof prop !== "string") return undefined; |
| 51 | return createToolsProxy([...path, prop]); | 57 | return createToolsProxy([...path, prop]); |
| 52 | }, | 58 | }, |
| 59 | ownKeys() { | ||
| 60 | throw toolsEnumerationError(path); | ||
| 61 | }, | ||
| 62 | getOwnPropertyDescriptor() { | ||
| 63 | throw toolsEnumerationError(path); | ||
| 64 | }, | ||
| 53 | apply(_target, _thisArg, args) { | 65 | apply(_target, _thisArg, args) { |
| 54 | const toolPath = path.join("."); | 66 | const toolPath = path.join("."); |
| 55 | if (!toolPath) { | 67 | if (!toolPath) { |
| @@ -309,4 +309,55 @@ describe.skipIf(!isDenoAvailable())("runtime-deno-subprocess", () => { · 308 unmodified lines | |||
| 309 | expect(output.error).toBeUndefined(); | 309 | expect(output.error).toBeUndefined(); |
| 310 | }), | 310 | }), |
| 311 | ); | 311 | ); |
| 312 | |||
| 313 | it.effect("tools proxy throws a search hint on enumeration", () => | ||
| 314 | Effect.gen(function* () { | ||
| 315 | const executor = makeDenoSubprocessExecutor(); | ||
| 316 | const toolInvoker = makeTestInvoker({}); | ||
| 317 | |||
| 318 | const output = yield* executor.execute( | ||
| 319 | [ | ||
| 320 | "const outcomes = {};", | ||
| 321 | "try {", | ||
| 322 | " Object.keys(tools);", | ||
| 323 | ' outcomes.keys = "no error";', | ||
| 324 | "} catch (e) {", | ||
| 325 | " outcomes.keys = e instanceof Error ? e.message : String(e);", | ||
| 326 | "}", | ||
| 327 | "try {", | ||
| 328 | " ({ ...tools.github });", | ||
| 329 | ' outcomes.spread = "no error";', | ||
| 330 | "} catch (e) {", | ||
| 331 | " outcomes.spread = e instanceof Error ? e.message : String(e);", | ||
| 332 | "}", | ||
| 333 | "return outcomes;", | ||
| 334 | ].join("\n"), | ||
| 335 | toolInvoker, | ||
| 336 | ); | ||
| 337 | |||
| 338 | expect(output.error).toBeUndefined(); | ||
| 339 | expect(output.result).toEqual({ | ||
| 340 | keys: 'tools is a lazy proxy and cannot be enumerated. Use tools.search({ query: "..." }) to find tools, or tools.executor.coreTools.connections.list({}) to list saved connections.', | ||
| 341 | spread: | ||
| 342 | 'tools.github is a lazy proxy and cannot be enumerated. Use tools.search({ query: "..." }) to find tools, or tools.executor.coreTools.connections.list({}) to list saved connections.', | ||
| 343 | }); | ||
| 344 | }), | ||
| 345 | ); | ||
| 346 | |||
| 347 | it.effect("tools proxy still invokes after the enumeration traps", () => | ||
| 348 | Effect.gen(function* () { | ||
| 349 | const executor = makeDenoSubprocessExecutor(); | ||
| 350 | const toolInvoker = makeTestInvoker({ | ||
| 351 | "a.b.c": () => "a.b.c", | ||
| 352 | }); | ||
| 353 | |||
| 354 | const output = yield* executor.execute( | ||
| 355 | ["try { Object.keys(tools); } catch {}", "return tools.a.b.c({});"].join("\n"), | ||
| 356 | toolInvoker, | ||
| 357 | ); | ||
| 358 | |||
| 359 | expect(output.error).toBeUndefined(); | ||
| 360 | expect(output.result).toBe("a.b.c"); | ||
| 361 | }), | ||
| 362 | ); | ||
| 312 | }); | 363 | }); |