@smithers-orchestrator/agents 0.24.2 → 0.25.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.
Files changed (54) hide show
  1. package/package.json +15 -5
  2. package/src/AgentLike.ts +5 -0
  3. package/src/AmpAgent.js +15 -5
  4. package/src/AmpAgentOptions.ts +6 -0
  5. package/src/BaseCliAgent/BaseCliAgent.js +198 -10
  6. package/src/BaseCliAgent/createAgentStdoutTextEmitter.js +21 -3
  7. package/src/BaseCliAgent/index.d.ts +467 -0
  8. package/src/ClaudeCodeAgent.js +6 -2
  9. package/src/CodexAgent.js +4 -0
  10. package/src/GeminiAgent.js +34 -224
  11. package/src/GeminiAgentOptions.ts +4 -9
  12. package/src/OpenCodeAgent.js +2 -12
  13. package/src/OpenCodeAgentOptions.ts +19 -0
  14. package/src/cli-capabilities/CliAgentCapabilityAdapterId.ts +0 -1
  15. package/src/cli-capabilities/getCliAgentCapabilityDoctorReport.js +3 -2
  16. package/src/cli-capabilities/getCliAgentCapabilityReport.js +0 -6
  17. package/src/cli-surface/cliAgentSurfaceManifest.js +1 -40
  18. package/src/createElevenLabsTextToSpeechTool.js +128 -0
  19. package/src/createElevenLabsTextToSpeechTool.ts +33 -0
  20. package/src/diagnostics/getDiagnosticStrategy.js +13 -12
  21. package/src/document-parsing/DocumentParsingProvider.ts +13 -0
  22. package/src/document-parsing/DocumentParsingResult.ts +13 -0
  23. package/src/document-parsing/DocumentParsingToolset.ts +4 -0
  24. package/src/document-parsing/DocumentParsingToolsetOptions.ts +9 -0
  25. package/src/document-parsing/createDocumentParsingToolset.d.ts +9 -0
  26. package/src/document-parsing/createDocumentParsingToolset.js +416 -0
  27. package/src/http/CreateHttpToolOptions.ts +4 -0
  28. package/src/http/HttpToolAuth.ts +15 -0
  29. package/src/http/HttpToolInput.ts +11 -0
  30. package/src/http/HttpToolOutput.ts +7 -0
  31. package/src/http/createHttpTool.js +136 -0
  32. package/src/image-generation/ImageGenerationProvider.ts +7 -0
  33. package/src/image-generation/ImageGenerationRequest.ts +8 -0
  34. package/src/image-generation/ImageGenerationResult.ts +10 -0
  35. package/src/image-generation/ImageGenerationToolOptions.ts +10 -0
  36. package/src/image-generation/createImageGenerationTool.d.ts +18 -0
  37. package/src/image-generation/createImageGenerationTool.js +92 -0
  38. package/src/index.d.ts +490 -147
  39. package/src/index.js +23 -5
  40. package/src/streamResultToGenerateResult.js +55 -26
  41. package/src/transcription/createTranscriptionTool.js +182 -0
  42. package/src/transcription/createTranscriptionTool.ts +29 -0
  43. package/src/transcription/index.js +1 -0
  44. package/src/transcription/index.ts +6 -0
  45. package/src/web-search/GroundedWebSearchProvider.ts +21 -0
  46. package/src/web-search/GroundedWebSearchToolset.ts +6 -0
  47. package/src/web-search/createBraveSearchProvider.js +53 -0
  48. package/src/web-search/createExaSearchProvider.js +72 -0
  49. package/src/web-search/createGroundedWebSearchToolset.js +110 -0
  50. package/src/web-search/createSerperSearchProvider.js +63 -0
  51. package/src/web-search/createTavilySearchProvider.js +59 -0
  52. package/src/web-search/index.js +5 -0
  53. package/src/zodToOpenAISchema.js +4 -0
  54. package/src/OpenCodeAgent.ts +0 -43
@@ -0,0 +1,136 @@
1
+ import { dynamicTool } from "ai";
2
+ import { z } from "zod";
3
+
4
+ /** @typedef {import("ai").Tool} Tool */
5
+ /** @typedef {import("./CreateHttpToolOptions.ts").CreateHttpToolOptions} CreateHttpToolOptions */
6
+ /** @typedef {import("./HttpToolInput.ts").HttpToolInput} HttpToolInput */
7
+ /** @typedef {import("./HttpToolOutput.ts").HttpToolOutput} HttpToolOutput */
8
+
9
+ const httpToolInputSchema = z.object({
10
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]).optional().default("GET"),
11
+ url: z.string().url(),
12
+ headers: z.record(z.string(), z.string()).optional(),
13
+ query: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.null(), z.undefined()])).optional(),
14
+ body: z.unknown().optional(),
15
+ auth: z
16
+ .discriminatedUnion("type", [
17
+ z.object({ type: z.literal("bearer"), token: z.string() }),
18
+ z.object({ type: z.literal("basic"), username: z.string(), password: z.string() }),
19
+ z.object({ type: z.literal("header"), name: z.string(), value: z.string() }),
20
+ ])
21
+ .optional(),
22
+ timeoutMs: z.number().int().positive().optional(),
23
+ });
24
+
25
+ /**
26
+ * Create an AI SDK tool that can call any REST API without an OpenAPI spec.
27
+ *
28
+ * @param {CreateHttpToolOptions} [options]
29
+ * @returns {Tool}
30
+ */
31
+ export function createHttpTool(options = {}) {
32
+ return dynamicTool({
33
+ description:
34
+ options.description ??
35
+ "Call any REST API by providing method, url, headers, query params, body, and optional auth.",
36
+ inputSchema: httpToolInputSchema,
37
+ execute: async (input) => executeHttpRequest(/** @type {HttpToolInput} */ (input), options),
38
+ });
39
+ }
40
+
41
+ /**
42
+ * @param {HttpToolInput} input
43
+ * @param {CreateHttpToolOptions} options
44
+ * @returns {Promise<HttpToolOutput>}
45
+ */
46
+ async function executeHttpRequest(input, options) {
47
+ const url = new URL(input.url);
48
+ for (const [key, value] of Object.entries(input.query ?? {})) {
49
+ if (value !== null && value !== undefined) {
50
+ url.searchParams.set(key, String(value));
51
+ }
52
+ }
53
+
54
+ const headers = new Headers(options.defaultHeaders ?? {});
55
+ for (const [key, value] of Object.entries(input.headers ?? {})) {
56
+ headers.set(key, value);
57
+ }
58
+ applyAuth(headers, input.auth);
59
+
60
+ const init = /** @type {RequestInit} */ ({
61
+ method: input.method ?? "GET",
62
+ headers,
63
+ });
64
+ if (input.body !== undefined && init.method !== "GET" && init.method !== "HEAD") {
65
+ init.body = serializeBody(input.body, headers);
66
+ }
67
+
68
+ const controller = input.timeoutMs ? new AbortController() : null;
69
+ const timeout = controller ? setTimeout(() => controller.abort(), input.timeoutMs) : null;
70
+ if (controller) {
71
+ init.signal = controller.signal;
72
+ }
73
+ try {
74
+ const response = await fetch(url, init);
75
+ return {
76
+ ok: response.ok,
77
+ status: response.status,
78
+ statusText: response.statusText,
79
+ headers: Object.fromEntries(response.headers.entries()),
80
+ body: await parseResponseBody(response),
81
+ };
82
+ } finally {
83
+ if (timeout) {
84
+ clearTimeout(timeout);
85
+ }
86
+ }
87
+ }
88
+
89
+ /**
90
+ * @param {Headers} headers
91
+ * @param {HttpToolInput["auth"]} auth
92
+ */
93
+ function applyAuth(headers, auth) {
94
+ if (!auth) return;
95
+ if (auth.type === "bearer") {
96
+ headers.set("authorization", `Bearer ${auth.token}`);
97
+ } else if (auth.type === "basic") {
98
+ headers.set("authorization", `Basic ${btoa(`${auth.username}:${auth.password}`)}`);
99
+ } else {
100
+ headers.set(auth.name, auth.value);
101
+ }
102
+ }
103
+
104
+ /**
105
+ * @param {unknown} body
106
+ * @param {Headers} headers
107
+ * @returns {BodyInit}
108
+ */
109
+ function serializeBody(body, headers) {
110
+ if (typeof body === "string" || body instanceof Blob || body instanceof FormData || body instanceof URLSearchParams) {
111
+ return body;
112
+ }
113
+ if (!headers.has("content-type")) {
114
+ headers.set("content-type", "application/json");
115
+ }
116
+ return JSON.stringify(body);
117
+ }
118
+
119
+ /**
120
+ * @param {Response} response
121
+ * @returns {Promise<unknown>}
122
+ */
123
+ async function parseResponseBody(response) {
124
+ if (response.status === 204 || response.status === 205) {
125
+ return null;
126
+ }
127
+ const text = await response.text();
128
+ if (!text) {
129
+ return null;
130
+ }
131
+ const contentType = response.headers.get("content-type") ?? "";
132
+ if (contentType.includes("application/json")) {
133
+ return JSON.parse(text);
134
+ }
135
+ return text;
136
+ }
@@ -0,0 +1,7 @@
1
+ import type { ImageGenerationRequest } from "./ImageGenerationRequest.js";
2
+ import type { ImageGenerationResult } from "./ImageGenerationResult.js";
3
+
4
+ export type ImageGenerationProvider = {
5
+ name?: string;
6
+ generateImage(request: ImageGenerationRequest): Promise<ImageGenerationResult> | ImageGenerationResult;
7
+ };
@@ -0,0 +1,8 @@
1
+ export type ImageGenerationRequest = {
2
+ prompt: string;
3
+ model?: string;
4
+ size?: string;
5
+ count?: number;
6
+ seed?: number;
7
+ style?: string;
8
+ };
@@ -0,0 +1,10 @@
1
+ export type ImageGenerationResult = {
2
+ provider?: string;
3
+ model?: string;
4
+ images: Array<{
5
+ url?: string;
6
+ base64?: string;
7
+ mimeType?: string;
8
+ revisedPrompt?: string;
9
+ }>;
10
+ };
@@ -0,0 +1,10 @@
1
+ export type ImageGenerationToolOptions = {
2
+ /** Tool name used when returning a toolset. */
3
+ name?: string;
4
+ /** Description shown to the model. */
5
+ description?: string;
6
+ /** Provider model to use when the agent does not specify one. */
7
+ model?: string;
8
+ /** Return `{ [name]: tool }` for direct mounting on an agent. */
9
+ asToolset?: boolean;
10
+ };
@@ -0,0 +1,18 @@
1
+ import type { Tool } from "ai";
2
+ import type { ImageGenerationProvider } from "./ImageGenerationProvider.js";
3
+ import type { ImageGenerationToolOptions } from "./ImageGenerationToolOptions.js";
4
+
5
+ export type { ImageGenerationProvider } from "./ImageGenerationProvider.js";
6
+ export type { ImageGenerationRequest } from "./ImageGenerationRequest.js";
7
+ export type { ImageGenerationResult } from "./ImageGenerationResult.js";
8
+ export type { ImageGenerationToolOptions } from "./ImageGenerationToolOptions.js";
9
+
10
+ export declare function createImageGenerationTool(
11
+ provider: ImageGenerationProvider,
12
+ options: ImageGenerationToolOptions & { asToolset: true },
13
+ ): Record<string, Tool>;
14
+
15
+ export declare function createImageGenerationTool(
16
+ provider: ImageGenerationProvider,
17
+ options?: ImageGenerationToolOptions,
18
+ ): Tool;
@@ -0,0 +1,92 @@
1
+ import { dynamicTool, jsonSchema } from "ai";
2
+
3
+ /** @typedef {import("ai").Tool} Tool */
4
+ /** @typedef {import("./ImageGenerationProvider.ts").ImageGenerationProvider} ImageGenerationProvider */
5
+ /** @typedef {import("./ImageGenerationToolOptions.ts").ImageGenerationToolOptions} ImageGenerationToolOptions */
6
+ /** @typedef {import("./ImageGenerationRequest.ts").ImageGenerationRequest} ImageGenerationRequest */
7
+
8
+ const DEFAULT_TOOL_NAME = "generate_image";
9
+
10
+ const imageGenerationInputSchema = {
11
+ type: "object",
12
+ additionalProperties: false,
13
+ required: ["prompt"],
14
+ properties: {
15
+ prompt: {
16
+ type: "string",
17
+ description: "A detailed description of the image to generate.",
18
+ minLength: 1,
19
+ },
20
+ model: {
21
+ type: "string",
22
+ description: "Optional provider model override.",
23
+ },
24
+ size: {
25
+ type: "string",
26
+ description: "Requested output size, such as 1024x1024.",
27
+ },
28
+ count: {
29
+ type: "integer",
30
+ description: "Number of images to generate.",
31
+ minimum: 1,
32
+ maximum: 10,
33
+ },
34
+ seed: {
35
+ type: "integer",
36
+ description: "Optional deterministic seed when supported by the provider.",
37
+ },
38
+ style: {
39
+ type: "string",
40
+ description: "Optional provider-specific style hint.",
41
+ },
42
+ },
43
+ };
44
+
45
+ /**
46
+ * Create an agent-callable image generation primitive backed by a provider.
47
+ *
48
+ * The provider boundary keeps Smithers independent of any single image model
49
+ * vendor while still exposing a stable tool surface to AI SDK agents.
50
+ *
51
+ * @param {ImageGenerationProvider} provider
52
+ * @param {ImageGenerationToolOptions} [options]
53
+ * @returns {Tool | Record<string, Tool>}
54
+ */
55
+ export function createImageGenerationTool(provider, options = {}) {
56
+ if (!provider || typeof provider.generateImage !== "function") {
57
+ throw new TypeError("createImageGenerationTool requires a provider with generateImage(request)");
58
+ }
59
+
60
+ const tool = dynamicTool({
61
+ description:
62
+ options.description ??
63
+ "Generate images from a prompt. Returns image URLs or base64 image payloads from the configured provider.",
64
+ inputSchema: jsonSchema(imageGenerationInputSchema),
65
+ execute: async (input) => provider.generateImage(normalizeImageGenerationInput(input, options)),
66
+ });
67
+
68
+ if (options.asToolset) {
69
+ return { [options.name ?? DEFAULT_TOOL_NAME]: tool };
70
+ }
71
+ return tool;
72
+ }
73
+
74
+ /**
75
+ * @param {unknown} input
76
+ * @param {ImageGenerationToolOptions} options
77
+ * @returns {ImageGenerationRequest}
78
+ */
79
+ function normalizeImageGenerationInput(input, options) {
80
+ const value = /** @type {Partial<ImageGenerationRequest>} */ (input ?? {});
81
+ if (typeof value.prompt !== "string" || value.prompt.trim() === "") {
82
+ throw new TypeError("generate_image requires a non-empty prompt");
83
+ }
84
+ return {
85
+ prompt: value.prompt,
86
+ ...(typeof value.size === "string" ? { size: value.size } : {}),
87
+ ...(typeof value.count === "number" ? { count: value.count } : {}),
88
+ ...(typeof value.seed === "number" ? { seed: value.seed } : {}),
89
+ ...(typeof value.style === "string" ? { style: value.style } : {}),
90
+ ...(typeof value.model === "string" ? { model: value.model } : options.model ? { model: options.model } : {}),
91
+ };
92
+ }