@theokit/sdk-tools 0.26.3 → 0.27.0

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.
package/dist/index.d.cts CHANGED
@@ -1173,6 +1173,60 @@ declare function truncateOutput(output: string, opts?: TruncationOptions): Trunc
1173
1173
 
1174
1174
  declare function createUpdatePlanTool(): CustomTool;
1175
1175
 
1176
+ /**
1177
+ * `view_image` — let the agent LOOK at an image in the project.
1178
+ *
1179
+ * ## Why this is a built-in
1180
+ *
1181
+ * It was the one tool a consumer had to write from scratch (89 LOC), and its shape — a `handler`
1182
+ * returning a structured result plus `toModelOutput` shaping it into an `ImageBlock` — is the
1183
+ * canonical multimodal shape the SDK already defines (SE17). Every product that wants an agent to look at a
1184
+ * screenshot rewrites the same base64 + media-type + confinement logic.
1185
+ *
1186
+ * The confinement is the part that is easy to get wrong, and the reason this belongs in a reviewed
1187
+ * built-in rather than in each product: **an image reader that honours any path is a file
1188
+ * exfiltration primitive with a friendly name.** `/etc/passwd` renamed to `.png` is not a
1189
+ * hypothetical — it is one prompt away.
1190
+ *
1191
+ * ## The two channels
1192
+ *
1193
+ * This built-in uses the SE17 split. The handler returns the envelope as a JSON **string** — which
1194
+ * is what `Tool.create` types it to return — and `toModelOutput` turns that string into an
1195
+ * `ImageBlock` for the model, while `defineTool` routes the full value to `onToolEnd` through a
1196
+ * resolver under `TOOL_SPLIT_RESOLVER`.
1197
+ *
1198
+ * So `tool.handler(...)` yields image blocks on success and the JSON string on failure: the factory
1199
+ * has already applied the shaping. There is no `tool.toModelOutput` left to call, and returning the
1200
+ * envelope unshaped would send the model a base64 blob as TEXT — something it cannot look at, which
1201
+ * is the failure this tool exists to avoid.
1202
+ *
1203
+ * ## Result shape (the APP channel)
1204
+ *
1205
+ * - `{ ok: true, path, media_type, bytes, data }`
1206
+ * - `{ ok: false, error: "path_traversal" | "not_found" | "unsupported_image_type" | "image_too_large", … }`
1207
+ */
1208
+
1209
+ /**
1210
+ * Default ceiling: 5 MB on disk.
1211
+ *
1212
+ * Base64 inflates by 4/3 and the result lands directly in the model's context. A 20 MB screenshot is
1213
+ * not a slow request — it is a failed turn, and an expensive one.
1214
+ */
1215
+ declare const DEFAULT_MAX_IMAGE_BYTES: number;
1216
+ interface CreateViewImageToolOptions {
1217
+ /** Root the tool reads from. Every path is resolved inside it. */
1218
+ projectRoot: string;
1219
+ /** Name exposed to the model. Omitted ⇒ `view_image`. The name is a contract: it is the approval
1220
+ * key, what the model sees, and what telemetry records. */
1221
+ name?: string;
1222
+ /** Description exposed to the model. Omitted ⇒ the literal below. */
1223
+ description?: string;
1224
+ /** Ceiling in bytes, measured on disk. Omitted ⇒ {@link DEFAULT_MAX_IMAGE_BYTES}. */
1225
+ maxBytes?: number;
1226
+ }
1227
+ /** Read an image from the project so the model can look at it. */
1228
+ declare function createViewImageTool(options: CreateViewImageToolOptions): CustomTool;
1229
+
1176
1230
  /**
1177
1231
  * `web_fetch` — built-in tool for coding agents.
1178
1232
  *
@@ -1351,4 +1405,4 @@ interface CreateWriteFileToolOptions {
1351
1405
  }
1352
1406
  declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
1353
1407
 
1354
- export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateCurrentTimeToolOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGitStatusToolOptions, type CreateGlobToolOptions, type CreateInteractiveShellToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationMode, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGitStatusTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
1408
+ export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateCurrentTimeToolOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGitStatusToolOptions, type CreateGlobToolOptions, type CreateInteractiveShellToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateViewImageToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_MAX_IMAGE_BYTES, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationMode, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGitStatusTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createViewImageTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
package/dist/index.d.ts CHANGED
@@ -1173,6 +1173,60 @@ declare function truncateOutput(output: string, opts?: TruncationOptions): Trunc
1173
1173
 
1174
1174
  declare function createUpdatePlanTool(): CustomTool;
1175
1175
 
1176
+ /**
1177
+ * `view_image` — let the agent LOOK at an image in the project.
1178
+ *
1179
+ * ## Why this is a built-in
1180
+ *
1181
+ * It was the one tool a consumer had to write from scratch (89 LOC), and its shape — a `handler`
1182
+ * returning a structured result plus `toModelOutput` shaping it into an `ImageBlock` — is the
1183
+ * canonical multimodal shape the SDK already defines (SE17). Every product that wants an agent to look at a
1184
+ * screenshot rewrites the same base64 + media-type + confinement logic.
1185
+ *
1186
+ * The confinement is the part that is easy to get wrong, and the reason this belongs in a reviewed
1187
+ * built-in rather than in each product: **an image reader that honours any path is a file
1188
+ * exfiltration primitive with a friendly name.** `/etc/passwd` renamed to `.png` is not a
1189
+ * hypothetical — it is one prompt away.
1190
+ *
1191
+ * ## The two channels
1192
+ *
1193
+ * This built-in uses the SE17 split. The handler returns the envelope as a JSON **string** — which
1194
+ * is what `Tool.create` types it to return — and `toModelOutput` turns that string into an
1195
+ * `ImageBlock` for the model, while `defineTool` routes the full value to `onToolEnd` through a
1196
+ * resolver under `TOOL_SPLIT_RESOLVER`.
1197
+ *
1198
+ * So `tool.handler(...)` yields image blocks on success and the JSON string on failure: the factory
1199
+ * has already applied the shaping. There is no `tool.toModelOutput` left to call, and returning the
1200
+ * envelope unshaped would send the model a base64 blob as TEXT — something it cannot look at, which
1201
+ * is the failure this tool exists to avoid.
1202
+ *
1203
+ * ## Result shape (the APP channel)
1204
+ *
1205
+ * - `{ ok: true, path, media_type, bytes, data }`
1206
+ * - `{ ok: false, error: "path_traversal" | "not_found" | "unsupported_image_type" | "image_too_large", … }`
1207
+ */
1208
+
1209
+ /**
1210
+ * Default ceiling: 5 MB on disk.
1211
+ *
1212
+ * Base64 inflates by 4/3 and the result lands directly in the model's context. A 20 MB screenshot is
1213
+ * not a slow request — it is a failed turn, and an expensive one.
1214
+ */
1215
+ declare const DEFAULT_MAX_IMAGE_BYTES: number;
1216
+ interface CreateViewImageToolOptions {
1217
+ /** Root the tool reads from. Every path is resolved inside it. */
1218
+ projectRoot: string;
1219
+ /** Name exposed to the model. Omitted ⇒ `view_image`. The name is a contract: it is the approval
1220
+ * key, what the model sees, and what telemetry records. */
1221
+ name?: string;
1222
+ /** Description exposed to the model. Omitted ⇒ the literal below. */
1223
+ description?: string;
1224
+ /** Ceiling in bytes, measured on disk. Omitted ⇒ {@link DEFAULT_MAX_IMAGE_BYTES}. */
1225
+ maxBytes?: number;
1226
+ }
1227
+ /** Read an image from the project so the model can look at it. */
1228
+ declare function createViewImageTool(options: CreateViewImageToolOptions): CustomTool;
1229
+
1176
1230
  /**
1177
1231
  * `web_fetch` — built-in tool for coding agents.
1178
1232
  *
@@ -1351,4 +1405,4 @@ interface CreateWriteFileToolOptions {
1351
1405
  }
1352
1406
  declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
1353
1407
 
1354
- export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateCurrentTimeToolOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGitStatusToolOptions, type CreateGlobToolOptions, type CreateInteractiveShellToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationMode, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGitStatusTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
1408
+ export { CatastrophicCommandError, type CommandPolicy, ContextMatchError, type ContextMatchReason, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateCurrentTimeToolOptions, type CreateEditFileToolOptions, type CreateGenericHttpSearchAdapterOptions, type CreateGitDiffToolOptions, type CreateGitStatusToolOptions, type CreateGlobToolOptions, type CreateInteractiveShellToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateViewImageToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_MAX_IMAGE_BYTES, DEFAULT_TOOL_GUIDANCE, type EnvContextOptions, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, ReadTracker, ReasoningTools, RedirectBlockedError, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationMode, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGitStatusTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createViewImageTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { rm, mkdir, writeFile, readFile, readdir, open, stat, copyFile } from 'fs/promises';
2
- import { dirname, relative, join, isAbsolute } from 'path';
2
+ import { dirname, relative, join, isAbsolute, extname } from 'path';
3
3
  import { Tool, ConfigurationError } from '@theokit/sdk';
4
4
  import { z } from 'zod';
5
5
  import { safePathJoin, assertNoSymlinkEscape, PathTraversalError, ForbiddenPathError, isForbiddenPath, safeFilenameForId } from '@theokit/sdk/path-safety';
@@ -2625,6 +2625,86 @@ function createUpdatePlanTool() {
2625
2625
  }
2626
2626
  });
2627
2627
  }
2628
+ var MEDIA_TYPES = /* @__PURE__ */ new Map([
2629
+ [".png", "image/png"],
2630
+ [".jpg", "image/jpeg"],
2631
+ [".jpeg", "image/jpeg"],
2632
+ [".gif", "image/gif"],
2633
+ [".webp", "image/webp"]
2634
+ ]);
2635
+ var DEFAULT_MAX_IMAGE_BYTES = 5 * 1024 * 1024;
2636
+ var json = (result) => JSON.stringify(result);
2637
+ function createViewImageTool(options) {
2638
+ const { projectRoot } = options;
2639
+ const maxBytes = options.maxBytes ?? DEFAULT_MAX_IMAGE_BYTES;
2640
+ return Tool.create({
2641
+ name: options.name ?? "view_image",
2642
+ description: options.description ?? "Read an image file from the project and show it to the model. Supports png, jpeg, gif and webp.",
2643
+ inputSchema: z.object({
2644
+ path: z.string().describe("Path to the image, relative to the project root.")
2645
+ }),
2646
+ handler: (input) => {
2647
+ const refused = checkPathScope(input.path, projectRoot);
2648
+ if (refused !== null) return refused;
2649
+ if (isForbiddenAtAnyDepth(input.path)) {
2650
+ return json({ ok: false, error: "path_traversal", path: input.path });
2651
+ }
2652
+ const mediaType = MEDIA_TYPES.get(extname(input.path).toLowerCase());
2653
+ if (mediaType === void 0) {
2654
+ return json({
2655
+ ok: false,
2656
+ error: "unsupported_image_type",
2657
+ path: input.path,
2658
+ supported: [...MEDIA_TYPES.keys()]
2659
+ });
2660
+ }
2661
+ const absolute = safePathJoin(projectRoot, input.path);
2662
+ let bytes;
2663
+ try {
2664
+ bytes = statSync(absolute).size;
2665
+ } catch {
2666
+ return json({ ok: false, error: "not_found", path: input.path });
2667
+ }
2668
+ if (bytes > maxBytes) {
2669
+ return json({
2670
+ ok: false,
2671
+ error: "image_too_large",
2672
+ path: input.path,
2673
+ bytes,
2674
+ limit_bytes: maxBytes
2675
+ });
2676
+ }
2677
+ return json({
2678
+ ok: true,
2679
+ path: input.path,
2680
+ media_type: mediaType,
2681
+ bytes,
2682
+ data: readFileSync(absolute).toString("base64")
2683
+ });
2684
+ },
2685
+ /**
2686
+ * Turn a successful read into an image block.
2687
+ *
2688
+ * A failed read stays TEXT on purpose: the model needs to read "not_found" and try another path,
2689
+ * and an error is not something to look at.
2690
+ */
2691
+ toModelOutput: (output) => {
2692
+ let result;
2693
+ try {
2694
+ result = JSON.parse(output);
2695
+ } catch {
2696
+ return output;
2697
+ }
2698
+ if (result.ok !== true) return output;
2699
+ return [
2700
+ {
2701
+ type: "image",
2702
+ source: { type: "base64", media_type: result.media_type, data: result.data }
2703
+ }
2704
+ ];
2705
+ }
2706
+ });
2707
+ }
2628
2708
  var DEFAULT_TIMEOUT_MS4 = 3e4;
2629
2709
  var MAX_BODY_BYTES = 1 * 1024 * 1024;
2630
2710
  function createWebFetchTool(opts) {
@@ -2766,8 +2846,8 @@ function createBraveWebSearchAdapter(opts = {}) {
2766
2846
  headers: { "X-Subscription-Token": apiKey, Accept: "application/json" }
2767
2847
  });
2768
2848
  if (!res.ok) throw new Error(`brave_search_failed: HTTP ${res.status}`);
2769
- const json = await res.json();
2770
- const results = json?.web?.results ?? [];
2849
+ const json2 = await res.json();
2850
+ const results = json2?.web?.results ?? [];
2771
2851
  return results.map((r) => ({
2772
2852
  title: String(r?.title ?? ""),
2773
2853
  url: String(r?.url ?? ""),
@@ -2927,6 +3007,6 @@ async function isBinaryFile(absolutePath) {
2927
3007
  }
2928
3008
  }
2929
3009
 
2930
- export { CatastrophicCommandError, ContextMatchError, DEFAULT_TOOL_GUIDANCE, ReadTracker, ReasoningTools, RedirectBlockedError, SsrfBlockedError, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGitStatusTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
3010
+ export { CatastrophicCommandError, ContextMatchError, DEFAULT_MAX_IMAGE_BYTES, DEFAULT_TOOL_GUIDANCE, ReadTracker, ReasoningTools, RedirectBlockedError, SsrfBlockedError, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createCurrentTimeTool, createEditFileTool, createGenericHttpSearchAdapter, createGitDiffTool, createGitStatusTool, createGlobTool, createInteractiveShellTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createUpdatePlanTool, createViewImageTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, createWriteStdinTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, replaceUnique, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withName, withShellExitGuidance, withToolResultGuidance };
2931
3011
  //# sourceMappingURL=index.js.map
2932
3012
  //# sourceMappingURL=index.js.map