tekimax-ts 0.2.0 → 0.2.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.
package/dist/index.js CHANGED
@@ -1025,7 +1025,7 @@ var OpenAIProvider = class {
1025
1025
  this.name = "openai";
1026
1026
  this.client = new OpenAI({
1027
1027
  apiKey: options.apiKey,
1028
- dangerouslyAllowBrowser: options.dangerouslyAllowBrowser
1028
+ baseURL: options.baseURL
1029
1029
  });
1030
1030
  }
1031
1031
  async generateSpeech(options) {
@@ -1926,22 +1926,41 @@ function tool(def) {
1926
1926
  // src/core/generate.ts
1927
1927
  async function generateText({
1928
1928
  adapter,
1929
+ plugins = [],
1929
1930
  ...options
1930
1931
  }) {
1931
1932
  const { model, tools, maxSteps = 1, temperature, maxTokens, signal } = options;
1932
- const currentMessages = [...options.messages];
1933
+ let currentMessages = [...options.messages];
1934
+ let currentModel = model;
1933
1935
  let steps = 0;
1934
1936
  const toolDefinitions = tools ? Object.values(tools) : void 0;
1935
1937
  while (steps < maxSteps) {
1936
1938
  steps++;
1939
+ let context = {
1940
+ model: currentModel,
1941
+ messages: [...currentMessages],
1942
+ timestamp: Date.now(),
1943
+ requestOptions: { ...options }
1944
+ };
1945
+ for (const plugin of plugins) {
1946
+ if (plugin.beforeRequest) {
1947
+ const updated = await plugin.beforeRequest(context);
1948
+ if (updated) context = updated;
1949
+ }
1950
+ }
1951
+ currentMessages = context.messages;
1952
+ currentModel = context.model;
1937
1953
  const result = await adapter.chat({
1938
- model,
1954
+ model: currentModel,
1939
1955
  messages: currentMessages,
1940
1956
  tools: toolDefinitions,
1941
1957
  temperature,
1942
1958
  maxTokens,
1943
1959
  signal
1944
1960
  });
1961
+ for (const plugin of plugins) {
1962
+ if (plugin.afterResponse) await plugin.afterResponse(context, result);
1963
+ }
1945
1964
  const { message } = result;
1946
1965
  currentMessages.push(message);
1947
1966
  if (!message.toolCalls || message.toolCalls.length === 0) {
@@ -1955,25 +1974,23 @@ async function generateText({
1955
1974
  }
1956
1975
  const toolResults = await Promise.all(
1957
1976
  message.toolCalls.map(async (call) => {
1958
- const tool2 = tools?.[call.function.name];
1977
+ const toolName = call.function.name;
1978
+ const tool2 = tools?.[toolName];
1959
1979
  if (!tool2) {
1960
- return {
1961
- id: call.id,
1962
- result: `Error: Tool ${call.function.name} not found`
1963
- };
1980
+ return { id: call.id, result: `Error: Tool ${toolName} not found` };
1964
1981
  }
1965
1982
  try {
1966
- const args = JSON.parse(call.function.arguments);
1983
+ let args = JSON.parse(call.function.arguments);
1984
+ for (const plugin of plugins) {
1985
+ if (plugin.beforeToolExecute) await plugin.beforeToolExecute(toolName, args);
1986
+ }
1967
1987
  const output = await tool2.execute(args);
1968
- return {
1969
- id: call.id,
1970
- result: output
1971
- };
1988
+ for (const plugin of plugins) {
1989
+ if (plugin.afterToolExecute) await plugin.afterToolExecute(toolName, output);
1990
+ }
1991
+ return { id: call.id, result: output };
1972
1992
  } catch (error) {
1973
- return {
1974
- id: call.id,
1975
- result: `Error executing tool: ${error.message}`
1976
- };
1993
+ return { id: call.id, result: `Error executing tool: ${error.message}` };
1977
1994
  }
1978
1995
  })
1979
1996
  );
@@ -1991,7 +2008,6 @@ async function generateText({
1991
2008
  toolCalls: [],
1992
2009
  toolResults: [],
1993
2010
  finishReason: "length",
1994
- // or 'tool_calls' if strictly ending on tools
1995
2011
  usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
1996
2012
  warnings: ["Max steps reached"]
1997
2013
  };
@@ -2247,69 +2263,80 @@ async function withRetry(fn, options = {}) {
2247
2263
  throw lastError || new Error("withRetry: unexpected exit");
2248
2264
  }
2249
2265
  function createRetryProvider(provider, options = {}) {
2250
- return {
2251
- ...provider,
2252
- name: provider.name,
2253
- chat: (chatOptions) => {
2254
- return withRetry(
2255
- () => provider.chat(chatOptions),
2256
- { ...options, signal: chatOptions.signal || options.signal }
2257
- );
2258
- },
2259
- chatStream: (chatOptions) => {
2260
- const iterable = {
2261
- [Symbol.asyncIterator]() {
2262
- let innerIterator = null;
2263
- return {
2264
- async next() {
2265
- if (!innerIterator) {
2266
- const stream = await withRetry(
2267
- async () => provider.chatStream(chatOptions),
2268
- { ...options, signal: chatOptions.signal || options.signal }
2269
- );
2270
- innerIterator = stream[Symbol.asyncIterator]();
2271
- }
2272
- return innerIterator.next();
2273
- },
2274
- async return() {
2275
- if (innerIterator?.return) {
2276
- return innerIterator.return();
2266
+ return new Proxy(provider, {
2267
+ get(target, prop, receiver) {
2268
+ const value = Reflect.get(target, prop, receiver);
2269
+ if (typeof value === "function" && typeof prop === "string") {
2270
+ if (prop === "chatStream") {
2271
+ return function(chatOptions) {
2272
+ const iterable = {
2273
+ [Symbol.asyncIterator]() {
2274
+ let innerIterator = null;
2275
+ return {
2276
+ async next() {
2277
+ if (!innerIterator) {
2278
+ const stream = await withRetry(
2279
+ async () => value.call(target, chatOptions),
2280
+ { ...options, signal: chatOptions.signal || options.signal }
2281
+ );
2282
+ innerIterator = stream[Symbol.asyncIterator]();
2283
+ }
2284
+ return innerIterator.next();
2285
+ },
2286
+ async return() {
2287
+ if (innerIterator?.return) {
2288
+ return innerIterator.return();
2289
+ }
2290
+ return { value: void 0, done: true };
2291
+ }
2292
+ };
2277
2293
  }
2278
- return { value: void 0, done: true };
2279
- }
2294
+ };
2295
+ return iterable;
2280
2296
  };
2281
2297
  }
2282
- };
2283
- return iterable;
2284
- },
2285
- // Pass through multi-modal methods with retry
2286
- generateImage: provider.generateImage ? (opts) => withRetry(() => provider.generateImage(opts), options) : void 0,
2287
- editImage: provider.editImage ? (opts) => withRetry(() => provider.editImage(opts), options) : void 0,
2288
- analyzeImage: provider.analyzeImage ? (opts) => withRetry(() => provider.analyzeImage(opts), options) : void 0,
2289
- generateSpeech: provider.generateSpeech ? (opts) => withRetry(() => provider.generateSpeech(opts), options) : void 0,
2290
- transcribeAudio: provider.transcribeAudio ? (opts) => withRetry(() => provider.transcribeAudio(opts), options) : void 0,
2291
- generateVideo: provider.generateVideo ? (opts) => withRetry(() => provider.generateVideo(opts), options) : void 0,
2292
- analyzeVideo: provider.analyzeVideo ? (opts) => withRetry(() => provider.analyzeVideo(opts), options) : void 0
2293
- };
2298
+ const promiseMethods = [
2299
+ "chat",
2300
+ "generateImage",
2301
+ "editImage",
2302
+ "analyzeImage",
2303
+ "generateSpeech",
2304
+ "transcribeAudio",
2305
+ "generateVideo",
2306
+ "analyzeVideo",
2307
+ "embed"
2308
+ ];
2309
+ if (promiseMethods.includes(prop)) {
2310
+ return function(...args) {
2311
+ const callOpts = args[0] || {};
2312
+ const sig = callOpts.signal || options.signal;
2313
+ return withRetry(() => value.apply(target, args), { ...options, signal: sig });
2314
+ };
2315
+ }
2316
+ }
2317
+ if (typeof value === "function") {
2318
+ return value.bind(target);
2319
+ }
2320
+ return value;
2321
+ }
2322
+ });
2294
2323
  }
2295
2324
 
2296
2325
  // src/core/middleware.ts
2297
2326
  function wrapProvider(provider, middlewares) {
2298
- return {
2299
- ...provider,
2300
- name: provider.name,
2301
- chat: createWrappedChat(provider, middlewares),
2302
- chatStream: createWrappedChatStream(provider, middlewares),
2303
- // Multi-modal methods pass through unmodified.
2304
- // Middleware only applies to chat/chatStream for now.
2305
- generateImage: provider.generateImage?.bind(provider),
2306
- editImage: provider.editImage?.bind(provider),
2307
- analyzeImage: provider.analyzeImage?.bind(provider),
2308
- generateSpeech: provider.generateSpeech?.bind(provider),
2309
- transcribeAudio: provider.transcribeAudio?.bind(provider),
2310
- generateVideo: provider.generateVideo?.bind(provider),
2311
- analyzeVideo: provider.analyzeVideo?.bind(provider)
2312
- };
2327
+ const wrappedChat = createWrappedChat(provider, middlewares);
2328
+ const wrappedChatStream = createWrappedChatStream(provider, middlewares);
2329
+ return new Proxy(provider, {
2330
+ get(target, prop, receiver) {
2331
+ if (prop === "chat") return wrappedChat;
2332
+ if (prop === "chatStream") return wrappedChatStream;
2333
+ const value = Reflect.get(target, prop, receiver);
2334
+ if (typeof value === "function") {
2335
+ return value.bind(target);
2336
+ }
2337
+ return value;
2338
+ }
2339
+ });
2313
2340
  }
2314
2341
  function createWrappedChat(provider, middlewares) {
2315
2342
  return async (options) => {
@@ -2458,35 +2485,35 @@ var FallbackProvider = class {
2458
2485
  }
2459
2486
  // --- Multi-modal: delegate to first provider that supports the capability ---
2460
2487
  get generateImage() {
2461
- const provider = this.providers.find((p) => p.generateImage);
2488
+ const provider = this.providers.find((p) => typeof p.generateImage === "function");
2462
2489
  return provider?.generateImage?.bind(provider);
2463
2490
  }
2464
2491
  get editImage() {
2465
- const provider = this.providers.find((p) => p.editImage);
2492
+ const provider = this.providers.find((p) => typeof p.editImage === "function");
2466
2493
  return provider?.editImage?.bind(provider);
2467
2494
  }
2468
2495
  get analyzeImage() {
2469
- const provider = this.providers.find((p) => p.analyzeImage);
2496
+ const provider = this.providers.find((p) => typeof p.analyzeImage === "function");
2470
2497
  return provider?.analyzeImage?.bind(provider);
2471
2498
  }
2472
2499
  get generateSpeech() {
2473
- const provider = this.providers.find((p) => p.generateSpeech);
2500
+ const provider = this.providers.find((p) => typeof p.generateSpeech === "function");
2474
2501
  return provider?.generateSpeech?.bind(provider);
2475
2502
  }
2476
2503
  get transcribeAudio() {
2477
- const provider = this.providers.find((p) => p.transcribeAudio);
2504
+ const provider = this.providers.find((p) => typeof p.transcribeAudio === "function");
2478
2505
  return provider?.transcribeAudio?.bind(provider);
2479
2506
  }
2480
2507
  get generateVideo() {
2481
- const provider = this.providers.find((p) => p.generateVideo);
2508
+ const provider = this.providers.find((p) => typeof p.generateVideo === "function");
2482
2509
  return provider?.generateVideo?.bind(provider);
2483
2510
  }
2484
2511
  get analyzeVideo() {
2485
- const provider = this.providers.find((p) => p.analyzeVideo);
2512
+ const provider = this.providers.find((p) => typeof p.analyzeVideo === "function");
2486
2513
  return provider?.analyzeVideo?.bind(provider);
2487
2514
  }
2488
2515
  get embed() {
2489
- const provider = this.providers.find((p) => p.embed);
2516
+ const provider = this.providers.find((p) => typeof p.embed === "function");
2490
2517
  return provider?.embed?.bind(provider);
2491
2518
  }
2492
2519
  /**
@@ -2513,174 +2540,7 @@ var FallbackProvider = class {
2513
2540
  }
2514
2541
  };
2515
2542
 
2516
- // src/core/convex.ts
2517
- import { execSync } from "child_process";
2518
- var MANAGEMENT_API = "https://api.convex.dev/v1";
2519
- var ConvexManager = class {
2520
- constructor(options = {}) {
2521
- this.accessToken = options.accessToken || process.env.CONVEX_ACCESS_TOKEN || "";
2522
- this.teamId = options.teamId || process.env.CONVEX_TEAM_ID;
2523
- if (!this.accessToken) {
2524
- throw new Error(
2525
- "ConvexManager requires an access token. Pass accessToken in options or set CONVEX_ACCESS_TOKEN env var."
2526
- );
2527
- }
2528
- }
2529
- // ─── Project Lifecycle ──────────────────────────────────────────────
2530
- /**
2531
- * Create a new Convex project (includes an initial deployment).
2532
- */
2533
- async createProject(name, options = {}) {
2534
- const teamId = await this.resolveTeamId();
2535
- const body = {
2536
- projectName: name,
2537
- deploymentType: options.deploymentType || "prod"
2538
- };
2539
- if (options.region) {
2540
- body.deploymentRegion = options.region;
2541
- }
2542
- return this.request(
2543
- `${MANAGEMENT_API}/teams/${teamId}/create_project`,
2544
- { method: "POST", body }
2545
- );
2546
- }
2547
- /**
2548
- * List all projects for the team.
2549
- */
2550
- async listProjects() {
2551
- const teamId = await this.resolveTeamId();
2552
- return this.request(
2553
- `${MANAGEMENT_API}/teams/${teamId}/list_projects`
2554
- );
2555
- }
2556
- /**
2557
- * Delete a project by ID.
2558
- */
2559
- async deleteProject(projectId) {
2560
- await this.request(
2561
- `${MANAGEMENT_API}/projects/${projectId}`,
2562
- { method: "DELETE" }
2563
- );
2564
- }
2565
- // ─── Deployment Management ──────────────────────────────────────────
2566
- /**
2567
- * Generate a deploy key for a deployment (needed for schema push / deploy).
2568
- */
2569
- async createDeployKey(deploymentName) {
2570
- const result = await this.request(
2571
- `${MANAGEMENT_API}/deployments/${deploymentName}/create_deploy_key`,
2572
- { method: "POST", body: { name: "sdk-provisioned" } }
2573
- );
2574
- return result.deployKey;
2575
- }
2576
- /**
2577
- * Set environment variables on a deployment (bulk upsert).
2578
- */
2579
- async setEnvVars(deploymentName, vars) {
2580
- await this.request(
2581
- `https://${deploymentName}.convex.cloud/api/v1/update_environment_variables`,
2582
- {
2583
- method: "POST",
2584
- body: { changes: vars },
2585
- authStyle: "deploy"
2586
- }
2587
- );
2588
- }
2589
- /**
2590
- * List environment variables on a deployment.
2591
- */
2592
- async getEnvVars(deploymentName) {
2593
- return this.request(
2594
- `https://${deploymentName}.convex.cloud/api/v1/list_environment_variables`,
2595
- { authStyle: "deploy" }
2596
- );
2597
- }
2598
- /**
2599
- * Push Convex functions and schema to a deployment.
2600
- * Shells out to `npx convex deploy` with the given deploy key.
2601
- */
2602
- deploy(deployKey, options = {}) {
2603
- const cwd = options.projectDir || process.cwd();
2604
- const flags = options.flags?.join(" ") || "";
2605
- const cmd = `npx convex deploy --cmd-url-env-var-name CONVEX_URL ${flags}`.trim();
2606
- execSync(cmd, {
2607
- cwd,
2608
- stdio: "inherit",
2609
- env: {
2610
- ...process.env,
2611
- CONVEX_DEPLOY_KEY: deployKey
2612
- }
2613
- });
2614
- }
2615
- // ─── Discovery ──────────────────────────────────────────────────────
2616
- /**
2617
- * Resolve token details (type, teamId, name) from the access token.
2618
- */
2619
- async getTokenDetails() {
2620
- return this.request(
2621
- `${MANAGEMENT_API}/token_details`
2622
- );
2623
- }
2624
- /**
2625
- * List available deployment regions.
2626
- */
2627
- async getRegions() {
2628
- const result = await this.request(
2629
- `${MANAGEMENT_API}/deployment_regions`
2630
- );
2631
- return result.items;
2632
- }
2633
- /**
2634
- * Generate an OpenAPI specification from a Convex deployment.
2635
- *
2636
- * Uses `npx convex-helpers open-api-spec` to introspect the deployment
2637
- * and produce a `convex-spec.yaml` file. You can then use tools like
2638
- * openapi-generator-cli to create type-safe clients in Go, Java, etc.
2639
- *
2640
- * @see https://docs.convex.dev/client/open-api
2641
- */
2642
- generateOpenAPISpec(options = {}) {
2643
- const cwd = options.projectDir || process.cwd();
2644
- const output = options.output || "convex-spec.yaml";
2645
- const extraFlags = options.flags?.join(" ") || "";
2646
- const cmd = `npx convex-helpers open-api-spec --output ${output} ${extraFlags}`.trim();
2647
- execSync(cmd, {
2648
- cwd,
2649
- stdio: "inherit"
2650
- });
2651
- }
2652
- // ─── Internal Helpers ───────────────────────────────────────────────
2653
- async resolveTeamId() {
2654
- if (this.teamId) return this.teamId;
2655
- const details = await this.getTokenDetails();
2656
- this.teamId = details.teamId;
2657
- return this.teamId;
2658
- }
2659
- async request(url, options = {}) {
2660
- const { method = "GET", body, authStyle = "bearer" } = options;
2661
- const headers = {
2662
- "Content-Type": "application/json",
2663
- Authorization: authStyle === "deploy" ? `Convex ${this.accessToken}` : `Bearer ${this.accessToken}`
2664
- };
2665
- const res = await fetch(url, {
2666
- method,
2667
- headers,
2668
- body: body ? JSON.stringify(body) : void 0
2669
- });
2670
- if (!res.ok) {
2671
- const text2 = await res.text().catch(() => "");
2672
- throw new Error(
2673
- `Convex API error (${res.status} ${res.statusText}): ${text2}`
2674
- );
2675
- }
2676
- const text = await res.text();
2677
- if (!text) return void 0;
2678
- return JSON.parse(text);
2679
- }
2680
- };
2681
-
2682
2543
  // src/core/cache.ts
2683
- import { createHash } from "crypto";
2684
2544
  var ResponseCache = class {
2685
2545
  constructor(redis, options = {}) {
2686
2546
  this.redis = redis;
@@ -2703,7 +2563,11 @@ var ResponseCache = class {
2703
2563
  }
2704
2564
  defaultKeyFn(model, messages) {
2705
2565
  const payload = JSON.stringify({ model, messages });
2706
- return createHash("sha256").update(payload).digest("hex");
2566
+ let hash = 5381;
2567
+ for (let i = 0; i < payload.length; i++) {
2568
+ hash = (hash << 5) + hash + payload.charCodeAt(i);
2569
+ }
2570
+ return (hash >>> 0).toString(16);
2707
2571
  }
2708
2572
  };
2709
2573
  var RateLimiter = class {
@@ -2800,28 +2664,55 @@ var SessionStore = class {
2800
2664
 
2801
2665
  // src/namespaces/text.ts
2802
2666
  var TextNamespace = class {
2803
- constructor(provider) {
2667
+ constructor(provider, plugins = []) {
2804
2668
  this.provider = provider;
2669
+ this.plugins = plugins;
2670
+ }
2671
+ async runBeforeRequest(options) {
2672
+ let context = {
2673
+ model: options.model,
2674
+ messages: [...options.messages],
2675
+ timestamp: Date.now(),
2676
+ requestOptions: { ...options }
2677
+ };
2678
+ for (const plugin of this.plugins) {
2679
+ if (plugin.beforeRequest) {
2680
+ const updated = await plugin.beforeRequest(context);
2681
+ if (updated) context = updated;
2682
+ }
2683
+ }
2684
+ return context;
2805
2685
  }
2806
2686
  /**
2807
2687
  * Generate text from a prompt (Chat Completion).
2808
2688
  */
2809
2689
  async generate(options) {
2810
- return this.provider.chat(options);
2690
+ const context = await this.runBeforeRequest(options);
2691
+ const activeOptions = { ...options, messages: context.messages, model: context.model };
2692
+ const result = await this.provider.chat(activeOptions);
2693
+ for (const plugin of this.plugins) {
2694
+ if (plugin.afterResponse) await plugin.afterResponse(context, result);
2695
+ }
2696
+ return result;
2811
2697
  }
2812
2698
  /**
2813
2699
  * Stream text generation.
2814
2700
  */
2815
2701
  async *generateStream(options) {
2816
- for await (const chunk of this.provider.chatStream(options)) {
2702
+ const context = await this.runBeforeRequest(options);
2703
+ const activeOptions = { ...options, messages: context.messages, model: context.model };
2704
+ for await (const chunk of this.provider.chatStream(activeOptions)) {
2705
+ for (const plugin of this.plugins) {
2706
+ if (plugin.onStreamChunk) plugin.onStreamChunk(context, chunk);
2707
+ }
2817
2708
  yield chunk;
2818
2709
  }
2819
2710
  }
2820
2711
  /**
2821
- * Generate embeddings for text input(s).
2712
+ * Generate embeddings for text input(s). Only available if the provider supports embeddings.
2822
2713
  */
2823
2714
  async embed(options) {
2824
- if (!this.provider.embed) {
2715
+ if (!("embed" in this.provider)) {
2825
2716
  throw new Error(`Provider '${this.provider.name}' does not support embeddings`);
2826
2717
  }
2827
2718
  return this.provider.embed(options);
@@ -2843,28 +2734,28 @@ var ImagesNamespace = class {
2843
2734
  this.provider = provider;
2844
2735
  }
2845
2736
  /**
2846
- * Generate images from a prompt.
2737
+ * Generate images from a prompt. Only available if the provider supports image generation.
2847
2738
  */
2848
2739
  async generate(options) {
2849
- if (!this.provider.generateImage) {
2740
+ if (!("generateImage" in this.provider)) {
2850
2741
  throw new Error(`Provider '${this.provider.name}' does not support image generation`);
2851
2742
  }
2852
2743
  return this.provider.generateImage(options);
2853
2744
  }
2854
2745
  /**
2855
- * Edit an image with a prompt.
2746
+ * Edit an image with a prompt. Only available if the provider supports image editing.
2856
2747
  */
2857
2748
  async edit(options) {
2858
- if (!this.provider.editImage) {
2749
+ if (!("editImage" in this.provider)) {
2859
2750
  throw new Error(`Provider '${this.provider.name}' does not support image editing`);
2860
2751
  }
2861
2752
  return this.provider.editImage(options);
2862
2753
  }
2863
2754
  /**
2864
- * Analyze an image (Vision).
2755
+ * Analyze an image (Vision). Only available if the provider supports vision analytics.
2865
2756
  */
2866
2757
  async analyze(options) {
2867
- if (!this.provider.analyzeImage) {
2758
+ if (!("analyzeImage" in this.provider)) {
2868
2759
  throw new Error(`Provider '${this.provider.name}' does not support image analysis`);
2869
2760
  }
2870
2761
  return this.provider.analyzeImage(options);
@@ -2877,19 +2768,19 @@ var AudioNamespace = class {
2877
2768
  this.provider = provider;
2878
2769
  }
2879
2770
  /**
2880
- * Convert text to speech.
2771
+ * Convert text to speech. Only available if the provider supports TTS.
2881
2772
  */
2882
2773
  async speak(options) {
2883
- if (!this.provider.generateSpeech) {
2774
+ if (!("generateSpeech" in this.provider)) {
2884
2775
  throw new Error(`Provider '${this.provider.name}' does not support speech generation`);
2885
2776
  }
2886
2777
  return this.provider.generateSpeech(options);
2887
2778
  }
2888
2779
  /**
2889
- * Transcribe audio to text.
2780
+ * Transcribe audio to text. Only available if the provider supports STT.
2890
2781
  */
2891
2782
  async transcribe(options) {
2892
- if (!this.provider.transcribeAudio) {
2783
+ if (!("transcribeAudio" in this.provider)) {
2893
2784
  throw new Error(`Provider '${this.provider.name}' does not support audio transcription`);
2894
2785
  }
2895
2786
  return this.provider.transcribeAudio(options);
@@ -2902,19 +2793,19 @@ var VideosNamespace = class {
2902
2793
  this.provider = provider;
2903
2794
  }
2904
2795
  /**
2905
- * Generate a video from a prompt.
2796
+ * Generate a video from a prompt. Only available if the provider supports video generation.
2906
2797
  */
2907
2798
  async generate(options) {
2908
- if (!this.provider.generateVideo) {
2799
+ if (!("generateVideo" in this.provider)) {
2909
2800
  throw new Error(`Provider '${this.provider.name}' does not support video generation`);
2910
2801
  }
2911
2802
  return this.provider.generateVideo(options);
2912
2803
  }
2913
2804
  /**
2914
- * Analyze a video (Video-to-Text).
2805
+ * Analyze a video (Video-to-Text). Only available if the provider supports video analysis.
2915
2806
  */
2916
2807
  async analyze(options) {
2917
- if (!this.provider.analyzeVideo) {
2808
+ if (!("analyzeVideo" in this.provider)) {
2918
2809
  throw new Error(`Provider '${this.provider.name}' does not support video analysis`);
2919
2810
  }
2920
2811
  return this.provider.analyzeVideo(options);
@@ -2925,7 +2816,11 @@ var VideosNamespace = class {
2925
2816
  var Tekimax = class {
2926
2817
  constructor(options) {
2927
2818
  this.provider = options.provider;
2928
- this.text = new TextNamespace(this.provider);
2819
+ this.plugins = options.plugins || [];
2820
+ for (const plugin of this.plugins) {
2821
+ if (plugin.onInit) plugin.onInit(this);
2822
+ }
2823
+ this.text = new TextNamespace(this.provider, this.plugins);
2929
2824
  this.images = new ImagesNamespace(this.provider);
2930
2825
  this.audio = new AudioNamespace(this.provider);
2931
2826
  this.videos = new VideosNamespace(this.provider);
@@ -2937,16 +2832,86 @@ var Tekimax = class {
2937
2832
  return this.text.chat;
2938
2833
  }
2939
2834
  };
2835
+
2836
+ // src/plugins/logger.ts
2837
+ var LoggerPlugin = class {
2838
+ constructor() {
2839
+ this.name = "LoggerPlugin";
2840
+ }
2841
+ onInit() {
2842
+ console.log("[LoggerPlugin] Tekimax SDK initialized with Logger Plugin active.");
2843
+ }
2844
+ async beforeRequest(context) {
2845
+ console.log(`[LoggerPlugin] Sending request to model: ${context.model} (${context.messages.length} messages)`);
2846
+ }
2847
+ async afterResponse(context, result) {
2848
+ console.log(`[LoggerPlugin] Received completion from ${context.model}. Usage:`, result.usage);
2849
+ }
2850
+ onStreamChunk(context, chunk) {
2851
+ if (chunk.usage) {
2852
+ console.log(`[LoggerPlugin] Stream completed. Final usage:`, chunk.usage);
2853
+ }
2854
+ }
2855
+ async beforeToolExecute(toolName, args) {
2856
+ console.log(`[LoggerPlugin] Executing tool '${toolName}' with args:`, args);
2857
+ }
2858
+ async afterToolExecute(toolName, result) {
2859
+ console.log(`[LoggerPlugin] Tool '${toolName}' returned successfully.`);
2860
+ }
2861
+ };
2862
+
2863
+ // src/plugins/pii.ts
2864
+ var PIIFilterPlugin = class {
2865
+ constructor() {
2866
+ this.name = "PIIFilterPlugin";
2867
+ this.patterns = {
2868
+ email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
2869
+ ssn: /\b\d{3}-\d{2}-\d{4}\b/g
2870
+ };
2871
+ }
2872
+ async beforeRequest(context) {
2873
+ context.messages = context.messages.map((msg) => {
2874
+ if (typeof msg.content === "string") {
2875
+ let safeContent = msg.content;
2876
+ safeContent = safeContent.replace(this.patterns.email, "[REDACTED EMAIL]");
2877
+ safeContent = safeContent.replace(this.patterns.ssn, "[REDACTED SSN]");
2878
+ return { ...msg, content: safeContent };
2879
+ }
2880
+ return msg;
2881
+ });
2882
+ return context;
2883
+ }
2884
+ };
2885
+
2886
+ // src/plugins/context.ts
2887
+ var MaxContextOverflowPlugin = class {
2888
+ constructor(maxMessages = 20) {
2889
+ this.maxMessages = maxMessages;
2890
+ this.name = "MaxContextOverflowPlugin";
2891
+ }
2892
+ async beforeRequest(context) {
2893
+ if (context.messages.length > this.maxMessages) {
2894
+ const hasSystem = context.messages[0]?.role === "system";
2895
+ const systemMsg = hasSystem ? context.messages[0] : null;
2896
+ const recentMsgs = context.messages.slice(-(this.maxMessages - (hasSystem ? 1 : 0)));
2897
+ context.messages = hasSystem && systemMsg ? [systemMsg, ...recentMsgs] : recentMsgs;
2898
+ console.warn(`[MaxContextOverflowPlugin] Truncated chat history to ${this.maxMessages} messages to preserve context limits.`);
2899
+ }
2900
+ return context;
2901
+ }
2902
+ };
2940
2903
  export {
2941
2904
  AnthropicProvider,
2942
2905
  types_exports as ApiTypes,
2943
- ConvexManager,
2944
2906
  FallbackProvider,
2945
2907
  GeminiProvider,
2946
2908
  GrokProvider,
2909
+ LoggerPlugin,
2910
+ MaxContextOverflowPlugin,
2947
2911
  OllamaProvider,
2948
2912
  OpenAIProvider,
2949
2913
  OpenRouterProvider,
2914
+ PIIFilterPlugin,
2950
2915
  RateLimiter,
2951
2916
  ResponseCache,
2952
2917
  SessionStore,