When introducing identifiers that represent external/domain data (e.g., tool calls, event payloads) and shared utilities, keep naming and placement semantically aligned and avoid redundant typing.
Apply: 1) Use domain-consistent suffixes for schema-derived types
event.input, prefer *Input (e.g., BashToolInput) over *Params/*Parameters unless the rest of the codebase uses a different established convention.2) Prefer inference over duplicated/hand-written boundary types
execute/handler boundary if the type is already inferred.3) Put shared utilities in accurately named modules and reuse them
shell.ts rather than shell-config.ts if it’s not config-only).Example (adapted):
const bashSchema = Type.Object({
command: Type.String(),
timeout: Type.Optional(Type.Number()),
});
// Domain-aligned: matches event.input
export type BashToolInput = Static<typeof bashSchema>;
// Inference-first: avoid re-specifying the same structure if already inferred
export const createBashTool = () =>
({
execute: async (
_toolCallId: string,
{ command, timeout }, // type inferred from bashSchema
signal?: AbortSignal,
) => {
// ...
},
});
Rule of thumb: if the identifier communicates “input/payload”, name it accordingly; if the logic is shared, name the module for what it provides and reuse it rather than duplicating/relocating ad-hoc helpers.
Enter the URL of a public GitHub repository