(
address: ToolAddress,
args: unknown,
options?: InvokeOptions,
)
| 3371 | }); |
| 3372 | |
| 3373 | const execute = ( |
| 3374 | address: ToolAddress, |
| 3375 | args: unknown, |
| 3376 | options?: InvokeOptions, |
| 3377 | ): Effect.Effect<unknown, ExecuteError> => { |
| 3378 | const handler = pickHandler(options); |
| 3379 | return Effect.gen(function* () { |
| 3380 | // oxlint-disable executor/no-instanceof-error, executor/no-unknown-error-message, executor/no-manual-tag-check -- boundary: normalize arbitrary unknown plugin failures into a human-readable message for ToolInvocationError/telemetry |
| 3381 | const formatInvocationCauseMessage = (cause: unknown): string => { |
| 3382 | if (cause instanceof Error && cause.message.length > 0) return cause.message; |
| 3383 | // Non-Error / empty-message causes: `String(plainObject)` renders |
| 3384 | // "[object Object]", which is what telemetry then shows as the only |
| 3385 | // label for the failure. Prefer the tag, else stringify structurally. |
| 3386 | if (typeof cause === "object" && cause !== null) { |
| 3387 | const tag = (cause as { readonly _tag?: unknown })._tag; |
| 3388 | if (typeof tag === "string") return tag; |
| 3389 | return Inspectable.toStringUnknown(cause, 0); |
| 3390 | } |
| 3391 | return String(cause); |
| 3392 | }; |
| 3393 | // oxlint-enable executor/no-instanceof-error, executor/no-unknown-error-message, executor/no-manual-tag-check |
| 3394 | const wrapInvocationError = <A, E>( |
| 3395 | effect: Effect.Effect<A, E>, |
| 3396 | ): Effect.Effect<A, ToolInvocationError> => |
| 3397 | effect.pipe( |
| 3398 | Effect.mapError( |
| 3399 | (cause) => |
| 3400 | new ToolInvocationError({ |
| 3401 | address, |
| 3402 | message: formatInvocationCauseMessage(cause), |
| 3403 | cause, |
| 3404 | }), |
| 3405 | ), |
| 3406 | ); |
| 3407 | |
| 3408 | // Static path — O(1) map lookup for plugin-contributed static tools |
| 3409 | // (core-tools, plugin executor namespaces). Addressed by their fqid, |
| 3410 | // not the 5-segment dynamic form. |
| 3411 | const staticEntry = staticTools.get(String(address)); |
| 3412 | if (staticEntry) { |
| 3413 | const policyRules = yield* listActivePolicyRuleSet(); |
| 3414 | const policy = yield* resolvePolicyFromRuleSet( |
| 3415 | String(address), |
| 3416 | policyRules, |
| 3417 | staticEntry.tool.annotations?.requiresApproval, |
| 3418 | ); |
| 3419 | if (policy.action === "block") { |
| 3420 | return yield* new ToolBlockedError({ |
| 3421 | address, |
| 3422 | pattern: policy.pattern ?? "*", |
| 3423 | }); |
| 3424 | } |
| 3425 | yield* enforceApproval(staticEntry.tool.annotations, address, args, policy, handler); |
| 3426 | return yield* wrapInvocationError( |
| 3427 | staticEntry.tool.handler({ |
| 3428 | ctx: staticEntry.ctx, |
| 3429 | args, |
| 3430 | elicit: buildElicit(address, args, handler), |
no test coverage detected