@webiny/api-core 6.6.0-alpha.1 → 6.6.0-alpha.3

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.
@@ -1,2 +1,3 @@
1
1
  export { TaskService } from "../../features/task/TaskService/index.js";
2
2
  export { TaskDefinition } from "../../features/task/TaskDefinition/index.js";
3
+ export { TaskHandler } from "../../features/task/TaskDefinition/index.js";
@@ -1,2 +1,2 @@
1
1
  export { TaskService } from "../../features/task/TaskService/index.js";
2
- export { TaskDefinition } from "../../features/task/TaskDefinition/index.js";
2
+ export { TaskDefinition, TaskHandler } from "../../features/task/TaskDefinition/index.js";
package/exports/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { AiSdk, AiSdkFactory, AiSdkTool, AiConnectionFactory, Ai } from "../features/ai/index.js";
1
+ export { AiSdk, AiSdkFactory, AiSdkToolDefinition, AiSdkToolHandler, AiConnectionFactory, Ai } from "../features/ai/index.js";
2
2
  export type { IAiConnection, IAiConnectionInline } from "../features/ai/index.js";
3
3
  export { Logger } from "../features/logger/index.js";
4
4
  export { Encryption } from "../features/encryption/index.js";
package/exports/api.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Ai, AiConnectionFactory, AiSdk, AiSdkFactory, AiSdkTool } from "../features/ai/index.js";
1
+ export { Ai, AiConnectionFactory, AiSdk, AiSdkFactory, AiSdkToolDefinition, AiSdkToolHandler } from "../features/ai/index.js";
2
2
  export { Logger } from "../features/logger/index.js";
3
3
  export { Encryption } from "../features/encryption/index.js";
4
4
  export { Hasher } from "../features/hashing/index.js";
@@ -0,0 +1,11 @@
1
+ import type { Container, Constructor } from "@webiny/di";
2
+ import { AiSdkToolHandler, AiSdkToolHandlerResolver as Abstraction } from "./abstractions.js";
3
+ declare class ContainerAiSdkToolHandlerResolver implements Abstraction.Interface {
4
+ private readonly container;
5
+ constructor(container: Container);
6
+ resolve<TInput>(handler: Constructor<AiSdkToolHandler.Interface<TInput>>): AiSdkToolHandler.Interface<TInput>;
7
+ }
8
+ export declare const AiSdkToolHandlerResolver: typeof ContainerAiSdkToolHandlerResolver & {
9
+ __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IAiSdkToolHandlerResolver>;
10
+ };
11
+ export {};
@@ -0,0 +1,19 @@
1
+ import { RequestContainer } from "@webiny/event-handler-core/features/events/RequestContainer.js";
2
+ import { AiSdkToolHandlerResolver } from "./abstractions.js";
3
+ class ContainerAiSdkToolHandlerResolver {
4
+ constructor(container){
5
+ this.container = container;
6
+ }
7
+ resolve(handler) {
8
+ return this.container.resolveImplementation(handler);
9
+ }
10
+ }
11
+ const AiSdkToolHandlerResolver_AiSdkToolHandlerResolver = AiSdkToolHandlerResolver.createImplementation({
12
+ implementation: ContainerAiSdkToolHandlerResolver,
13
+ dependencies: [
14
+ RequestContainer
15
+ ]
16
+ });
17
+ export { AiSdkToolHandlerResolver_AiSdkToolHandlerResolver as AiSdkToolHandlerResolver };
18
+
19
+ //# sourceMappingURL=AiSdkToolHandlerResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/ai/AiSdkToolHandlerResolver.js","sources":["../../../src/features/ai/AiSdkToolHandlerResolver.ts"],"sourcesContent":["import type { Container, Constructor } from \"@webiny/di\";\nimport { RequestContainer } from \"@webiny/event-handler-core/features/events/RequestContainer.js\";\nimport { AiSdkToolHandler, AiSdkToolHandlerResolver as Abstraction } from \"./abstractions.js\";\n\nclass ContainerAiSdkToolHandlerResolver implements Abstraction.Interface {\n constructor(private readonly container: Container) {}\n\n resolve<TInput>(\n handler: Constructor<AiSdkToolHandler.Interface<TInput>>\n ): AiSdkToolHandler.Interface<TInput> {\n /*\n * `resolveImplementation` builds the class from its own dependency metadata and runs it\n * through the normal resolution path, so decorators registered against the handler still\n * apply. It deliberately ignores registrations, which is what we want here: the tool names\n * the class directly and nothing registers handlers against an abstraction.\n */\n return this.container.resolveImplementation(handler);\n }\n}\n\nexport const AiSdkToolHandlerResolver = Abstraction.createImplementation({\n implementation: ContainerAiSdkToolHandlerResolver,\n dependencies: [RequestContainer]\n});\n"],"names":["ContainerAiSdkToolHandlerResolver","container","handler","AiSdkToolHandlerResolver","Abstraction","RequestContainer"],"mappings":";;AAIA,MAAMA;IACF,YAA6BC,SAAoB,CAAE;aAAtBA,SAAS,GAATA;IAAuB;IAEpD,QACIC,OAAwD,EACtB;QAOlC,OAAO,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAACA;IAChD;AACJ;AAEO,MAAMC,oDAA2BC,yBAAAA,oBAAgC,CAAC;IACrE,gBAAgBJ;IAChB,cAAc;QAACK;KAAiB;AACpC"}
@@ -1,8 +1,9 @@
1
- import { AiSdkTool, AiSdkTools as AiSdkToolsAbstraction } from "./abstractions.js";
1
+ import { AiSdkToolDefinition, AiSdkToolHandlerResolver, AiSdkTools as AiSdkToolsAbstraction } from "./abstractions.js";
2
2
  import type { ToolSet } from "ai";
3
3
  declare class AiSdkToolsImpl implements AiSdkToolsAbstraction.Interface {
4
- private tools;
5
- constructor(tools: AiSdkTool.Interface[]);
4
+ private definitions;
5
+ private resolver;
6
+ constructor(definitions: AiSdkToolDefinition.Interface[], resolver: AiSdkToolHandlerResolver.Interface);
6
7
  getToolSet(): ToolSet;
7
8
  }
8
9
  export declare const AiSdkTools: typeof AiSdkToolsImpl & {
@@ -1,14 +1,15 @@
1
- import { AiSdkTool, AiSdkTools } from "./abstractions.js";
1
+ import { AiSdkToolDefinition, AiSdkToolHandlerResolver, AiSdkTools } from "./abstractions.js";
2
2
  class AiSdkToolsImpl {
3
- constructor(tools){
4
- this.tools = tools;
3
+ constructor(definitions, resolver){
4
+ this.definitions = definitions;
5
+ this.resolver = resolver;
5
6
  }
6
7
  getToolSet() {
7
8
  const map = {};
8
- for (const t of this.tools)map[t.name] = {
9
- description: t.description,
10
- inputSchema: t.inputSchema,
11
- execute: (input)=>t.execute(input)
9
+ for (const definition of this.definitions)map[definition.name] = {
10
+ description: definition.description,
11
+ inputSchema: definition.inputSchema,
12
+ execute: (input)=>this.resolver.resolve(definition.handler).execute(input)
12
13
  };
13
14
  return map;
14
15
  }
@@ -17,11 +18,12 @@ const AiSdkTools_AiSdkTools = AiSdkTools.createImplementation({
17
18
  implementation: AiSdkToolsImpl,
18
19
  dependencies: [
19
20
  [
20
- AiSdkTool,
21
+ AiSdkToolDefinition,
21
22
  {
22
23
  multiple: true
23
24
  }
24
- ]
25
+ ],
26
+ AiSdkToolHandlerResolver
25
27
  ]
26
28
  });
27
29
  export { AiSdkTools_AiSdkTools as AiSdkTools };
@@ -1 +1 @@
1
- {"version":3,"file":"features/ai/AiSdkTools.js","sources":["../../../src/features/ai/AiSdkTools.ts"],"sourcesContent":["import { AiSdkTool, AiSdkTools as AiSdkToolsAbstraction } from \"./abstractions.js\";\nimport type { ToolSet } from \"ai\";\n\nclass AiSdkToolsImpl implements AiSdkToolsAbstraction.Interface {\n constructor(private tools: AiSdkTool.Interface[]) {}\n\n getToolSet(): ToolSet {\n const map: ToolSet = {};\n for (const t of this.tools) {\n map[t.name] = {\n description: t.description,\n inputSchema: t.inputSchema,\n execute: (input: unknown) => t.execute(input)\n };\n }\n return map;\n }\n}\n\nexport const AiSdkTools = AiSdkToolsAbstraction.createImplementation({\n implementation: AiSdkToolsImpl,\n dependencies: [[AiSdkTool, { multiple: true }]]\n});\n"],"names":["AiSdkToolsImpl","tools","map","t","input","AiSdkTools","AiSdkToolsAbstraction","AiSdkTool"],"mappings":";AAGA,MAAMA;IACF,YAAoBC,KAA4B,CAAE;aAA9BA,KAAK,GAALA;IAA+B;IAEnD,aAAsB;QAClB,MAAMC,MAAe,CAAC;QACtB,KAAK,MAAMC,KAAK,IAAI,CAAC,KAAK,CACtBD,GAAG,CAACC,EAAE,IAAI,CAAC,GAAG;YACV,aAAaA,EAAE,WAAW;YAC1B,aAAaA,EAAE,WAAW;YAC1B,SAAS,CAACC,QAAmBD,EAAE,OAAO,CAACC;QAC3C;QAEJ,OAAOF;IACX;AACJ;AAEO,MAAMG,wBAAaC,WAAAA,oBAA0C,CAAC;IACjE,gBAAgBN;IAChB,cAAc;QAAC;YAACO;YAAW;gBAAE,UAAU;YAAK;SAAE;KAAC;AACnD"}
1
+ {"version":3,"file":"features/ai/AiSdkTools.js","sources":["../../../src/features/ai/AiSdkTools.ts"],"sourcesContent":["import {\n AiSdkToolDefinition,\n AiSdkToolHandlerResolver,\n AiSdkTools as AiSdkToolsAbstraction\n} from \"./abstractions.js\";\nimport type { ToolSet } from \"ai\";\n\nclass AiSdkToolsImpl implements AiSdkToolsAbstraction.Interface {\n constructor(\n private definitions: AiSdkToolDefinition.Interface[],\n private resolver: AiSdkToolHandlerResolver.Interface\n ) {}\n\n getToolSet(): ToolSet {\n const map: ToolSet = {};\n for (const definition of this.definitions) {\n map[definition.name] = {\n description: definition.description,\n inputSchema: definition.inputSchema,\n /*\n * Deliberately resolved inside the call, not here. The model is offered every\n * tool and calls a few, which is what keeps the rest of their use cases unbuilt.\n *\n * `resolve` IS `container.resolveImplementation`, one layer down. It lives behind\n * an abstraction so this class does not inject a container. Note it builds the\n * class the definition names; resolving the `AiSdkToolHandler` abstraction would\n * find nothing, since handlers are declared through it but never registered.\n */\n execute: (input: unknown) =>\n this.resolver.resolve(definition.handler).execute(input)\n };\n }\n return map;\n }\n}\n\nexport const AiSdkTools = AiSdkToolsAbstraction.createImplementation({\n implementation: AiSdkToolsImpl,\n dependencies: [[AiSdkToolDefinition, { multiple: true }], AiSdkToolHandlerResolver]\n});\n"],"names":["AiSdkToolsImpl","definitions","resolver","map","definition","input","AiSdkTools","AiSdkToolsAbstraction","AiSdkToolDefinition","AiSdkToolHandlerResolver"],"mappings":";AAOA,MAAMA;IACF,YACYC,WAA4C,EAC5CC,QAA4C,CACtD;aAFUD,WAAW,GAAXA;aACAC,QAAQ,GAARA;IACT;IAEH,aAAsB;QAClB,MAAMC,MAAe,CAAC;QACtB,KAAK,MAAMC,cAAc,IAAI,CAAC,WAAW,CACrCD,GAAG,CAACC,WAAW,IAAI,CAAC,GAAG;YACnB,aAAaA,WAAW,WAAW;YACnC,aAAaA,WAAW,WAAW;YAUnC,SAAS,CAACC,QACN,IAAI,CAAC,QAAQ,CAAC,OAAO,CAACD,WAAW,OAAO,EAAE,OAAO,CAACC;QAC1D;QAEJ,OAAOF;IACX;AACJ;AAEO,MAAMG,wBAAaC,WAAAA,oBAA0C,CAAC;IACjE,gBAAgBP;IAChB,cAAc;QAAC;YAACQ;YAAqB;gBAAE,UAAU;YAAK;SAAE;QAAEC;KAAyB;AACvF"}
@@ -1,3 +1,4 @@
1
+ import type { Constructor } from "@webiny/di";
1
2
  import type { generateText } from "ai";
2
3
  import type { streamText } from "ai";
3
4
  import type { LanguageModel } from "ai";
@@ -85,21 +86,59 @@ export interface IAiSdkToolAnnotations {
85
86
  /** Tool interacts with entities outside its own closed world. */
86
87
  openWorldHint?: boolean;
87
88
  }
88
- export interface IAiSdkTool<TInput = any> {
89
+ /**
90
+ * What a tool DOES. This is the half that injects use cases, so it is built only for a tool the
91
+ * model actually calls, and only at the moment it calls it.
92
+ */
93
+ export interface IAiSdkToolHandler<TInput = any> {
94
+ execute(input: TInput): Promise<unknown>;
95
+ }
96
+ /**
97
+ * What a tool IS: everything the model is told about it, plus the class that runs it.
98
+ *
99
+ * Carries no behaviour and no dependencies, which is what makes the registry cheap to read.
100
+ * `AiSdkTools` builds every definition to assemble the tool set, and builds a handler only for a
101
+ * tool the model actually calls.
102
+ */
103
+ export interface IAiSdkToolDefinition<TInput = any> {
89
104
  readonly name: string;
90
105
  readonly description: string;
91
106
  readonly inputSchema: FlexibleSchema<TInput>;
92
107
  /** Human-friendly display name. Falls back to `name` when omitted. */
93
108
  readonly title?: string;
94
109
  readonly annotations?: IAiSdkToolAnnotations;
95
- execute(input: TInput): Promise<unknown>;
110
+ readonly handler: Constructor<IAiSdkToolHandler<TInput>>;
96
111
  }
97
- /** A single tool that can be provided to AI generateText/streamText calls. */
98
- export declare const AiSdkTool: import("@webiny/di").Abstraction<IAiSdkTool<any>>;
99
- export declare namespace AiSdkTool {
100
- type Interface = IAiSdkTool;
112
+ export declare const AiSdkToolDefinition: import("@webiny/di").Abstraction<IAiSdkToolDefinition<any>>;
113
+ /**
114
+ * The behaviour half of a tool, built on demand through {@link AiSdkToolHandlerResolver}.
115
+ *
116
+ * Implementations are NOT registered against this abstraction. The definition points at the class
117
+ * directly, exactly as `HttpRouteDefinition` points at its `HttpRouteHandler`. Declaring them
118
+ * through it is what attaches their dependency metadata.
119
+ */
120
+ export declare const AiSdkToolHandler: import("@webiny/di").Abstraction<IAiSdkToolHandler<any>>;
121
+ export declare namespace AiSdkToolDefinition {
122
+ type Interface<TInput = any> = IAiSdkToolDefinition<TInput>;
101
123
  type Annotations = IAiSdkToolAnnotations;
102
124
  }
125
+ export declare namespace AiSdkToolHandler {
126
+ type Interface<TInput = any> = IAiSdkToolHandler<TInput>;
127
+ }
128
+ export interface IAiSdkToolHandlerResolver {
129
+ resolve<TInput>(handler: Constructor<IAiSdkToolHandler<TInput>>): IAiSdkToolHandler<TInput>;
130
+ }
131
+ /**
132
+ * Builds the behaviour half of a tool on demand.
133
+ *
134
+ * Something has to turn `tool.handler` (a class) into an instance, and that needs the container.
135
+ * Rather than injecting the container into the tool registry, it lives behind this one narrow
136
+ * abstraction, so everything else depends on `resolve(handler)` and stays testable with a stub.
137
+ */
138
+ export declare const AiSdkToolHandlerResolver: import("@webiny/di").Abstraction<IAiSdkToolHandlerResolver>;
139
+ export declare namespace AiSdkToolHandlerResolver {
140
+ type Interface = IAiSdkToolHandlerResolver;
141
+ }
103
142
  export interface IAiSdkTools {
104
143
  getToolSet(): ToolSet;
105
144
  }
@@ -3,8 +3,10 @@ const AiSdk = createAbstraction("AiSdk");
3
3
  const AiSdkFactory = createAbstraction("AiSdkFactory");
4
4
  const AiConnectionFactory = createAbstraction("AiConnectionFactory");
5
5
  const Ai = createAbstraction("Ai");
6
- const AiSdkTool = createAbstraction("AiSdkTool");
6
+ const AiSdkToolDefinition = createAbstraction("AiSdkToolDefinition");
7
+ const AiSdkToolHandler = createAbstraction("AiSdkToolHandler");
8
+ const AiSdkToolHandlerResolver = createAbstraction("AiSdkToolHandlerResolver");
7
9
  const AiSdkTools = createAbstraction("AiSdkTools");
8
- export { Ai, AiConnectionFactory, AiSdk, AiSdkFactory, AiSdkTool, AiSdkTools };
10
+ export { Ai, AiConnectionFactory, AiSdk, AiSdkFactory, AiSdkToolDefinition, AiSdkToolHandler, AiSdkToolHandlerResolver, AiSdkTools };
9
11
 
10
12
  //# sourceMappingURL=abstractions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"features/ai/abstractions.js","sources":["../../../src/features/ai/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { generateText } from \"ai\";\nimport type { streamText } from \"ai\";\nimport type { LanguageModel } from \"ai\";\nimport type { FlexibleSchema, ToolSet } from \"ai\";\n\n// AiSdk\n\nexport interface IAiSdkModel {\n id: string; // raw model id, e.g. \"claude-sonnet-4-5\"\n name: string; // human-friendly name, e.g. \"Claude Sonnet 4.5\"\n}\n\nexport interface IAiSdk {\n languageModel(modelId: string): LanguageModel;\n}\n\n/** A single AI SDK instance (e.g. OpenAI, Anthropic) that resolves model instances. */\nexport const AiSdk = createAbstraction<IAiSdk>(\"AiSdk\");\n\nexport namespace AiSdk {\n export type Interface = IAiSdk;\n}\n\n// AiSdkFactory\n\nexport interface IAiSdkFactory {\n readonly id: string; // machine id, e.g. \"anthropic\"\n readonly name: string; // human-friendly name, e.g. \"Anthropic\"\n readonly models: readonly IAiSdkModel[]; // static model list, no API call needed\n execute(apiKey?: string): Promise<IAiSdk>;\n}\n\n/** Factory that asynchronously initialises an AI SDK. Register one per provider namespace. */\nexport const AiSdkFactory = createAbstraction<IAiSdkFactory>(\"AiSdkFactory\");\n\nexport namespace AiSdkFactory {\n export type Interface = IAiSdkFactory;\n}\n\n// AiConnection\n\nexport interface IAiConnectionInline {\n readonly sdkName: string;\n readonly apiKey?: string;\n}\n\nexport interface IAiConnection extends IAiConnectionInline {\n readonly id: string;\n}\n\n// AiConnectionFactory\n\nexport interface IAiConnectionFactory {\n execute(): Promise<IAiConnection>;\n}\n\n/** Factory that asynchronously produces an AiConnection. */\nexport const AiConnectionFactory = createAbstraction<IAiConnectionFactory>(\"AiConnectionFactory\");\n\nexport namespace AiConnectionFactory {\n export type Interface = IAiConnectionFactory;\n}\n\n// Ai\n\ntype SDKGenerateTextParams = Parameters<typeof generateText>[0];\ntype SDKStreamTextParams = Parameters<typeof streamText>[0];\n\nexport type AiGenerateTextParams = Omit<SDKGenerateTextParams, \"model\"> & {\n model: string;\n connection?: string | IAiConnectionInline;\n};\nexport type AiStreamTextParams = Omit<SDKStreamTextParams, \"model\"> & {\n model: string;\n connection?: string | IAiConnectionInline;\n};\n\nexport interface AiModel {\n providerId: string; // e.g. \"anthropic\"\n providerName: string; // e.g. \"Anthropic\"\n modelId: string; // e.g. \"claude-sonnet-4-5\"\n modelName: string; // e.g. \"Claude Sonnet 4.5\"\n}\n\nexport interface IAi {\n generateText(params: AiGenerateTextParams): ReturnType<typeof generateText>;\n streamText(params: AiStreamTextParams): Promise<ReturnType<typeof streamText>>;\n listModels(): Promise<AiModel[]>;\n listModelsByConnections(): Promise<AiModel[]>;\n listModelsByConnection(connection: string | IAiConnectionInline): Promise<AiModel[]>;\n}\n\n/** Interact with AI language models using registered providers. */\nexport const Ai = createAbstraction<IAi>(\"Ai\");\n\nexport namespace Ai {\n export type Interface = IAi;\n export type GenerateTextParams = AiGenerateTextParams;\n export type StreamTextParams = AiStreamTextParams;\n}\n\n// AiSdkTool\n\n/**\n * Behavioural hints about a tool. Purely advisory — they never replace a permission check.\n * Names mirror the MCP tool annotations so they can be forwarded verbatim to MCP clients,\n * which use them to decide what to auto-approve and what to confirm with the user.\n */\nexport interface IAiSdkToolAnnotations {\n /** Tool does not modify state. */\n readOnlyHint?: boolean;\n /** Tool may perform destructive updates (only meaningful when not read-only). */\n destructiveHint?: boolean;\n /** Repeated calls with the same arguments have no additional effect. */\n idempotentHint?: boolean;\n /** Tool interacts with entities outside its own closed world. */\n openWorldHint?: boolean;\n}\n\nexport interface IAiSdkTool<TInput = any> {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: FlexibleSchema<TInput>;\n /** Human-friendly display name. Falls back to `name` when omitted. */\n readonly title?: string;\n readonly annotations?: IAiSdkToolAnnotations;\n execute(input: TInput): Promise<unknown>;\n}\n\n/** A single tool that can be provided to AI generateText/streamText calls. */\nexport const AiSdkTool = createAbstraction<IAiSdkTool>(\"AiSdkTool\");\n\nexport namespace AiSdkTool {\n export type Interface = IAiSdkTool;\n export type Annotations = IAiSdkToolAnnotations;\n}\n\n// AiSdkTools\n\nexport interface IAiSdkTools {\n getToolSet(): ToolSet;\n}\n\n/** Collection of AI SDK tools. Returns a ready-to-use ToolSet for generateText/streamText. */\nexport const AiSdkTools = createAbstraction<IAiSdkTools>(\"AiSdkTools\");\n\nexport namespace AiSdkTools {\n export type Interface = IAiSdkTools;\n}\n"],"names":["AiSdk","createAbstraction","AiSdkFactory","AiConnectionFactory","Ai","AiSdkTool","AiSdkTools"],"mappings":";AAkBO,MAAMA,QAAQC,kBAA0B;AAgBxC,MAAMC,eAAeD,kBAAiC;AAwBtD,MAAME,sBAAsBF,kBAAwC;AAoCpE,MAAMG,KAAKH,kBAAuB;AAqClC,MAAMI,YAAYJ,kBAA8B;AAchD,MAAMK,aAAaL,kBAA+B"}
1
+ {"version":3,"file":"features/ai/abstractions.js","sources":["../../../src/features/ai/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { Constructor } from \"@webiny/di\";\nimport type { generateText } from \"ai\";\nimport type { streamText } from \"ai\";\nimport type { LanguageModel } from \"ai\";\nimport type { FlexibleSchema, ToolSet } from \"ai\";\n\n// AiSdk\n\nexport interface IAiSdkModel {\n id: string; // raw model id, e.g. \"claude-sonnet-4-5\"\n name: string; // human-friendly name, e.g. \"Claude Sonnet 4.5\"\n}\n\nexport interface IAiSdk {\n languageModel(modelId: string): LanguageModel;\n}\n\n/** A single AI SDK instance (e.g. OpenAI, Anthropic) that resolves model instances. */\nexport const AiSdk = createAbstraction<IAiSdk>(\"AiSdk\");\n\nexport namespace AiSdk {\n export type Interface = IAiSdk;\n}\n\n// AiSdkFactory\n\nexport interface IAiSdkFactory {\n readonly id: string; // machine id, e.g. \"anthropic\"\n readonly name: string; // human-friendly name, e.g. \"Anthropic\"\n readonly models: readonly IAiSdkModel[]; // static model list, no API call needed\n execute(apiKey?: string): Promise<IAiSdk>;\n}\n\n/** Factory that asynchronously initialises an AI SDK. Register one per provider namespace. */\nexport const AiSdkFactory = createAbstraction<IAiSdkFactory>(\"AiSdkFactory\");\n\nexport namespace AiSdkFactory {\n export type Interface = IAiSdkFactory;\n}\n\n// AiConnection\n\nexport interface IAiConnectionInline {\n readonly sdkName: string;\n readonly apiKey?: string;\n}\n\nexport interface IAiConnection extends IAiConnectionInline {\n readonly id: string;\n}\n\n// AiConnectionFactory\n\nexport interface IAiConnectionFactory {\n execute(): Promise<IAiConnection>;\n}\n\n/** Factory that asynchronously produces an AiConnection. */\nexport const AiConnectionFactory = createAbstraction<IAiConnectionFactory>(\"AiConnectionFactory\");\n\nexport namespace AiConnectionFactory {\n export type Interface = IAiConnectionFactory;\n}\n\n// Ai\n\ntype SDKGenerateTextParams = Parameters<typeof generateText>[0];\ntype SDKStreamTextParams = Parameters<typeof streamText>[0];\n\nexport type AiGenerateTextParams = Omit<SDKGenerateTextParams, \"model\"> & {\n model: string;\n connection?: string | IAiConnectionInline;\n};\nexport type AiStreamTextParams = Omit<SDKStreamTextParams, \"model\"> & {\n model: string;\n connection?: string | IAiConnectionInline;\n};\n\nexport interface AiModel {\n providerId: string; // e.g. \"anthropic\"\n providerName: string; // e.g. \"Anthropic\"\n modelId: string; // e.g. \"claude-sonnet-4-5\"\n modelName: string; // e.g. \"Claude Sonnet 4.5\"\n}\n\nexport interface IAi {\n generateText(params: AiGenerateTextParams): ReturnType<typeof generateText>;\n streamText(params: AiStreamTextParams): Promise<ReturnType<typeof streamText>>;\n listModels(): Promise<AiModel[]>;\n listModelsByConnections(): Promise<AiModel[]>;\n listModelsByConnection(connection: string | IAiConnectionInline): Promise<AiModel[]>;\n}\n\n/** Interact with AI language models using registered providers. */\nexport const Ai = createAbstraction<IAi>(\"Ai\");\n\nexport namespace Ai {\n export type Interface = IAi;\n export type GenerateTextParams = AiGenerateTextParams;\n export type StreamTextParams = AiStreamTextParams;\n}\n\n// AiSdkToolDefinition\n\n/**\n * Behavioural hints about a tool. Purely advisory — they never replace a permission check.\n * Names mirror the MCP tool annotations so they can be forwarded verbatim to MCP clients,\n * which use them to decide what to auto-approve and what to confirm with the user.\n */\nexport interface IAiSdkToolAnnotations {\n /** Tool does not modify state. */\n readOnlyHint?: boolean;\n /** Tool may perform destructive updates (only meaningful when not read-only). */\n destructiveHint?: boolean;\n /** Repeated calls with the same arguments have no additional effect. */\n idempotentHint?: boolean;\n /** Tool interacts with entities outside its own closed world. */\n openWorldHint?: boolean;\n}\n\n/**\n * What a tool DOES. This is the half that injects use cases, so it is built only for a tool the\n * model actually calls, and only at the moment it calls it.\n */\nexport interface IAiSdkToolHandler<TInput = any> {\n execute(input: TInput): Promise<unknown>;\n}\n\n/**\n * What a tool IS: everything the model is told about it, plus the class that runs it.\n *\n * Carries no behaviour and no dependencies, which is what makes the registry cheap to read.\n * `AiSdkTools` builds every definition to assemble the tool set, and builds a handler only for a\n * tool the model actually calls.\n */\nexport interface IAiSdkToolDefinition<TInput = any> {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: FlexibleSchema<TInput>;\n /** Human-friendly display name. Falls back to `name` when omitted. */\n readonly title?: string;\n readonly annotations?: IAiSdkToolAnnotations;\n readonly handler: Constructor<IAiSdkToolHandler<TInput>>;\n}\n\nexport const AiSdkToolDefinition = createAbstraction<IAiSdkToolDefinition>(\"AiSdkToolDefinition\");\n\n/**\n * The behaviour half of a tool, built on demand through {@link AiSdkToolHandlerResolver}.\n *\n * Implementations are NOT registered against this abstraction. The definition points at the class\n * directly, exactly as `HttpRouteDefinition` points at its `HttpRouteHandler`. Declaring them\n * through it is what attaches their dependency metadata.\n */\nexport const AiSdkToolHandler = createAbstraction<IAiSdkToolHandler>(\"AiSdkToolHandler\");\n\nexport namespace AiSdkToolDefinition {\n export type Interface<TInput = any> = IAiSdkToolDefinition<TInput>;\n export type Annotations = IAiSdkToolAnnotations;\n}\n\nexport namespace AiSdkToolHandler {\n export type Interface<TInput = any> = IAiSdkToolHandler<TInput>;\n}\n\n// AiSdkToolHandlerResolver\n\nexport interface IAiSdkToolHandlerResolver {\n resolve<TInput>(handler: Constructor<IAiSdkToolHandler<TInput>>): IAiSdkToolHandler<TInput>;\n}\n\n/**\n * Builds the behaviour half of a tool on demand.\n *\n * Something has to turn `tool.handler` (a class) into an instance, and that needs the container.\n * Rather than injecting the container into the tool registry, it lives behind this one narrow\n * abstraction, so everything else depends on `resolve(handler)` and stays testable with a stub.\n */\nexport const AiSdkToolHandlerResolver = createAbstraction<IAiSdkToolHandlerResolver>(\n \"AiSdkToolHandlerResolver\"\n);\n\nexport namespace AiSdkToolHandlerResolver {\n export type Interface = IAiSdkToolHandlerResolver;\n}\n\n// AiSdkTools\n\nexport interface IAiSdkTools {\n getToolSet(): ToolSet;\n}\n\n/** Collection of AI SDK tools. Returns a ready-to-use ToolSet for generateText/streamText. */\nexport const AiSdkTools = createAbstraction<IAiSdkTools>(\"AiSdkTools\");\n\nexport namespace AiSdkTools {\n export type Interface = IAiSdkTools;\n}\n"],"names":["AiSdk","createAbstraction","AiSdkFactory","AiConnectionFactory","Ai","AiSdkToolDefinition","AiSdkToolHandler","AiSdkToolHandlerResolver","AiSdkTools"],"mappings":";AAmBO,MAAMA,QAAQC,kBAA0B;AAgBxC,MAAMC,eAAeD,kBAAiC;AAwBtD,MAAME,sBAAsBF,kBAAwC;AAoCpE,MAAMG,KAAKH,kBAAuB;AAmDlC,MAAMI,sBAAsBJ,kBAAwC;AASpE,MAAMK,mBAAmBL,kBAAqC;AAwB9D,MAAMM,2BAA2BN,kBACpC;AAcG,MAAMO,aAAaP,kBAA+B"}
@@ -3,6 +3,7 @@ import { OpenAiSdkFactory } from "./OpenAiSdkFactory.js";
3
3
  import { AnthropicSdkFactory } from "./AnthropicSdkFactory.js";
4
4
  import { Ai } from "./Ai.js";
5
5
  import { AiSdkTools } from "./AiSdkTools.js";
6
+ import { AiSdkToolHandlerResolver } from "./AiSdkToolHandlerResolver.js";
6
7
  import { AiOutputToolRegistry } from "./toolPipeline/AiOutputToolRegistry.js";
7
8
  import { AiToolPipelineRunner } from "./toolPipeline/AiToolPipelineRunner.js";
8
9
  import { DefaultTextExtractor } from "./TextExtractor/DefaultTextExtractor.js";
@@ -13,6 +14,7 @@ const AiFeature = createFeature({
13
14
  container.register(AnthropicSdkFactory);
14
15
  container.register(Ai);
15
16
  container.register(AiSdkTools);
17
+ container.register(AiSdkToolHandlerResolver);
16
18
  container.register(AiOutputToolRegistry);
17
19
  container.register(AiToolPipelineRunner);
18
20
  container.register(DefaultTextExtractor);
@@ -1 +1 @@
1
- {"version":3,"file":"features/ai/feature.js","sources":["../../../src/features/ai/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { OpenAiSdkFactory } from \"./OpenAiSdkFactory.js\";\nimport { AnthropicSdkFactory } from \"./AnthropicSdkFactory.js\";\nimport { Ai } from \"./Ai.js\";\nimport { AiSdkTools } from \"./AiSdkTools.js\";\nimport { AiOutputToolRegistry } from \"./toolPipeline/AiOutputToolRegistry.js\";\nimport { AiToolPipelineRunner } from \"./toolPipeline/AiToolPipelineRunner.js\";\nimport { DefaultTextExtractor } from \"./TextExtractor/DefaultTextExtractor.js\";\n\nexport const AiFeature = createFeature({\n name: \"AiFeature\",\n register(container) {\n container.register(OpenAiSdkFactory);\n container.register(AnthropicSdkFactory);\n container.register(Ai);\n container.register(AiSdkTools);\n container.register(AiOutputToolRegistry);\n container.register(AiToolPipelineRunner);\n container.register(DefaultTextExtractor);\n }\n});\n"],"names":["AiFeature","createFeature","container","OpenAiSdkFactory","AnthropicSdkFactory","Ai","AiSdkTools","AiOutputToolRegistry","AiToolPipelineRunner","DefaultTextExtractor"],"mappings":";;;;;;;;AASO,MAAMA,YAAYC,cAAc;IACnC,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;QACnBF,UAAU,QAAQ,CAACG;QACnBH,UAAU,QAAQ,CAACI;QACnBJ,UAAU,QAAQ,CAACK;QACnBL,UAAU,QAAQ,CAACM;QACnBN,UAAU,QAAQ,CAACO;IACvB;AACJ"}
1
+ {"version":3,"file":"features/ai/feature.js","sources":["../../../src/features/ai/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { OpenAiSdkFactory } from \"./OpenAiSdkFactory.js\";\nimport { AnthropicSdkFactory } from \"./AnthropicSdkFactory.js\";\nimport { Ai } from \"./Ai.js\";\nimport { AiSdkTools } from \"./AiSdkTools.js\";\nimport { AiSdkToolHandlerResolver } from \"./AiSdkToolHandlerResolver.js\";\nimport { AiOutputToolRegistry } from \"./toolPipeline/AiOutputToolRegistry.js\";\nimport { AiToolPipelineRunner } from \"./toolPipeline/AiToolPipelineRunner.js\";\nimport { DefaultTextExtractor } from \"./TextExtractor/DefaultTextExtractor.js\";\n\nexport const AiFeature = createFeature({\n name: \"AiFeature\",\n register(container) {\n container.register(OpenAiSdkFactory);\n container.register(AnthropicSdkFactory);\n container.register(Ai);\n container.register(AiSdkTools);\n container.register(AiSdkToolHandlerResolver);\n container.register(AiOutputToolRegistry);\n container.register(AiToolPipelineRunner);\n container.register(DefaultTextExtractor);\n }\n});\n"],"names":["AiFeature","createFeature","container","OpenAiSdkFactory","AnthropicSdkFactory","Ai","AiSdkTools","AiSdkToolHandlerResolver","AiOutputToolRegistry","AiToolPipelineRunner","DefaultTextExtractor"],"mappings":";;;;;;;;;AAUO,MAAMA,YAAYC,cAAc;IACnC,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;QACnBF,UAAU,QAAQ,CAACG;QACnBH,UAAU,QAAQ,CAACI;QACnBJ,UAAU,QAAQ,CAACK;QACnBL,UAAU,QAAQ,CAACM;QACnBN,UAAU,QAAQ,CAACO;QACnBP,UAAU,QAAQ,CAACQ;IACvB;AACJ"}
@@ -1,5 +1,5 @@
1
- export { AiSdk, AiSdkFactory, AiConnectionFactory, Ai, AiSdkTool, AiSdkTools } from "./abstractions.js";
2
- export type { IAiConnection, IAiConnectionInline, AiModel, IAiSdkModel, IAiSdkTool, IAiSdkToolAnnotations, IAiSdkTools } from "./abstractions.js";
1
+ export { AiSdk, AiSdkFactory, AiConnectionFactory, Ai, AiSdkToolDefinition, AiSdkToolHandler, AiSdkToolHandlerResolver, AiSdkTools } from "./abstractions.js";
2
+ export type { IAiConnection, IAiConnectionInline, AiModel, IAiSdkModel } from "./abstractions.js";
3
3
  export { AiOutputTool, AiOutputToolRegistry, AiToolPipelineRunner } from "./toolPipeline/index.js";
4
4
  export type { IAiOutputTool, IAiOutputToolRegistry, IAiToolPipelineRunner } from "./toolPipeline/index.js";
5
5
  export { TextExtractor, DefaultTextExtractor } from "./TextExtractor/index.js";
@@ -1,4 +1,4 @@
1
- export { Ai, AiConnectionFactory, AiSdk, AiSdkFactory, AiSdkTool, AiSdkTools } from "./abstractions.js";
1
+ export { Ai, AiConnectionFactory, AiSdk, AiSdkFactory, AiSdkToolDefinition, AiSdkToolHandler, AiSdkToolHandlerResolver, AiSdkTools } from "./abstractions.js";
2
2
  export { AiOutputTool, AiOutputToolRegistry, AiToolPipelineRunner } from "./toolPipeline/index.js";
3
3
  export { DefaultTextExtractor, TextExtractor } from "./TextExtractor/index.js";
4
4
  export { AiAfterGenerateTextEvent, AiAfterGenerateTextEventHandler, AiBeforeGenerateTextEvent, AiBeforeGenerateTextEventHandler, AiBeforeStreamTextEvent, AiBeforeStreamTextEventHandler, AiGenerateTextErrorEvent, AiGenerateTextErrorEventHandler } from "./events.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/api-core",
3
- "version": "6.6.0-alpha.1",
3
+ "version": "6.6.0-alpha.3",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,15 +16,16 @@
16
16
  "dependencies": {
17
17
  "@ai-sdk/anthropic": "4.0.40",
18
18
  "@ai-sdk/openai": "4.0.45",
19
- "@webiny/api": "6.6.0-alpha.1",
20
- "@webiny/api-graphql": "6.6.0-alpha.1",
19
+ "@webiny/api": "6.6.0-alpha.3",
20
+ "@webiny/api-graphql": "6.6.0-alpha.3",
21
21
  "@webiny/di": "1.1.0",
22
- "@webiny/error": "6.6.0-alpha.1",
23
- "@webiny/feature": "6.6.0-alpha.1",
24
- "@webiny/feature-flags": "6.6.0-alpha.1",
25
- "@webiny/handler": "6.6.0-alpha.1",
26
- "@webiny/utils": "6.6.0-alpha.1",
27
- "@webiny/wcp": "6.6.0-alpha.1",
22
+ "@webiny/error": "6.6.0-alpha.3",
23
+ "@webiny/event-handler-core": "6.6.0-alpha.3",
24
+ "@webiny/feature": "6.6.0-alpha.3",
25
+ "@webiny/feature-flags": "6.6.0-alpha.3",
26
+ "@webiny/handler": "6.6.0-alpha.3",
27
+ "@webiny/utils": "6.6.0-alpha.3",
28
+ "@webiny/wcp": "6.6.0-alpha.3",
28
29
  "ai": "7.0.73",
29
30
  "dataloader": "2.2.3",
30
31
  "graphql": "16.14.2",
@@ -39,8 +40,7 @@
39
40
  },
40
41
  "devDependencies": {
41
42
  "@types/jsonwebtoken": "9.0.10",
42
- "@webiny/build-tools": "6.6.0-alpha.1",
43
- "@webiny/event-handler-core": "6.6.0-alpha.1",
43
+ "@webiny/build-tools": "6.6.0-alpha.3",
44
44
  "rimraf": "6.1.3",
45
45
  "typescript": "7.0.2",
46
46
  "vitest": "4.1.11"