@crewai-ts/core 0.1.3 → 0.1.5

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.cjs CHANGED
@@ -46193,6 +46193,7 @@ function readStringNumberBooleanRecord(value) {
46193
46193
 
46194
46194
  // src/provider-completions.ts
46195
46195
  init_cjs_shims();
46196
+ init_string_utils();
46196
46197
  var TOOL_SEARCH_TOOL_TYPES = Object.freeze([
46197
46198
  "tool_search_tool_regex_20251119",
46198
46199
  "tool_search_tool_bm25_20251119"
@@ -47347,33 +47348,37 @@ var GeminiCompletion = class _GeminiCompletion extends ConfiguredLLM {
47347
47348
  delete generationConfigBody.safety_settings;
47348
47349
  const model = this.model.replace(/^(?:gemini|google)\//, "");
47349
47350
  const baseUrl = this.baseUrl ?? "https://generativelanguage.googleapis.com/v1beta";
47350
- const requestInit = {
47351
+ const buildRequestInit = (currentContents) => ({
47351
47352
  method: "POST",
47352
47353
  headers: { "Content-Type": "application/json" },
47353
47354
  body: JSON.stringify({
47354
- contents,
47355
+ contents: currentContents,
47355
47356
  ...Object.keys(generationConfigBody).length > 0 ? { generationConfig: generationConfigBody } : {},
47356
47357
  ..."system_instruction" in requestBody ? { system_instruction: requestBody.system_instruction } : {},
47357
47358
  ..."tools" in requestBody ? { tools: requestBody.tools } : {},
47358
47359
  ..."safety_settings" in requestBody ? { safety_settings: requestBody.safety_settings } : {}
47359
- })
47360
- };
47361
- if (options?.signal) {
47362
- requestInit.signal = options.signal;
47363
- }
47364
- return fetch(
47365
- `${baseUrl.replace(/\/$/, "")}/models/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`,
47366
- requestInit
47367
- ).then(async (response) => {
47360
+ }),
47361
+ ...options?.signal ? { signal: options.signal } : {}
47362
+ });
47363
+ const generateContent = async (currentContents) => {
47364
+ const response = await fetch(
47365
+ `${baseUrl.replace(/\/$/, "")}/models/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`,
47366
+ buildRequestInit(currentContents)
47367
+ );
47368
47368
  const body = await response.json();
47369
47369
  if (!response.ok) {
47370
47370
  const error = readObject2(readObject2(body).error);
47371
47371
  throw new Error(scalarToString(error.message) ?? `Gemini request failed with HTTP ${response.status.toString()}.`);
47372
47372
  }
47373
+ return body;
47374
+ };
47375
+ return generateContent(contents).then(async (body) => {
47373
47376
  return await this.processResponseWithTools(
47374
47377
  body,
47375
47378
  contents,
47376
- options?.availableFunctions ?? options?.available_functions ?? null
47379
+ options?.availableFunctions ?? options?.available_functions ?? null,
47380
+ generateContent,
47381
+ geminiMaxToolRounds(options)
47377
47382
  );
47378
47383
  });
47379
47384
  }
@@ -47673,42 +47678,69 @@ ${textContent}` : textContent;
47673
47678
  static extract_structured_output_from_response(response) {
47674
47679
  return _GeminiCompletion.extractStructuredOutputFromResponse(response);
47675
47680
  }
47676
- async processResponseWithTools(response, contents = [], availableFunctions = null) {
47677
- void contents;
47678
- const candidates = readObject2(response).candidates;
47679
- if (!Array.isArray(candidates)) {
47680
- return _GeminiCompletion.extractTextFromResponse(response);
47681
- }
47682
- const first = readObject2(candidates[0]);
47683
- const rawParts = Array.isArray(readObject2(first.content).parts) ? readObject2(first.content).parts : [];
47684
- const functionCallParts = rawParts.filter((part) => Object.keys(readObject2(readObject2(part).functionCall ?? readObject2(part).function_call)).length > 0);
47685
- const nonStructuredParts = functionCallParts.filter((part) => {
47686
- const partRecord = readObject2(part);
47687
- const functionCall = readObject2(partRecord.functionCall ?? partRecord.function_call);
47688
- return (scalarToString(functionCall.name) ?? "") !== STRUCTURED_OUTPUT_TOOL_NAME;
47689
- });
47690
- if (nonStructuredParts.length > 0 && !availableFunctions) {
47691
- return nonStructuredParts;
47692
- }
47693
- if (nonStructuredParts.length > 0 && availableFunctions) {
47681
+ async processResponseWithTools(response, contents = [], availableFunctions = null, generateContent = null, maxToolRounds = DEFAULT_GEMINI_MAX_TOOL_ROUNDS) {
47682
+ let currentResponse = response;
47683
+ let currentContents = [...contents];
47684
+ for (let round = 0; round <= maxToolRounds; round += 1) {
47685
+ const candidates = readObject2(currentResponse).candidates;
47686
+ if (!Array.isArray(candidates)) {
47687
+ return _GeminiCompletion.extractTextFromResponse(currentResponse);
47688
+ }
47689
+ const first = readObject2(candidates[0]);
47690
+ const rawParts = Array.isArray(readObject2(first.content).parts) ? readObject2(first.content).parts : [];
47691
+ const functionCallParts = rawParts.filter((part) => Object.keys(readObject2(readObject2(part).functionCall ?? readObject2(part).function_call)).length > 0);
47692
+ const structuredOutput = _GeminiCompletion.extractStructuredOutputFromResponse(currentResponse);
47693
+ const nonStructuredParts = functionCallParts.filter((part) => {
47694
+ const partRecord = readObject2(part);
47695
+ const functionCall = readObject2(partRecord.functionCall ?? partRecord.function_call);
47696
+ return (scalarToString(functionCall.name) ?? "") !== STRUCTURED_OUTPUT_TOOL_NAME;
47697
+ });
47698
+ if (nonStructuredParts.length === 0) {
47699
+ return structuredOutput ?? _GeminiCompletion.extractTextFromResponse(currentResponse);
47700
+ }
47701
+ if (!availableFunctions) {
47702
+ return nonStructuredParts;
47703
+ }
47704
+ if (round >= maxToolRounds) {
47705
+ throw new Error(`Gemini tool loop exceeded max tool rounds (${String(maxToolRounds)}).`);
47706
+ }
47707
+ const functionResponseParts = [];
47708
+ let firstToolResult = null;
47694
47709
  for (const part of nonStructuredParts) {
47695
47710
  const partRecord = readObject2(part);
47696
47711
  const functionCall = readObject2(partRecord.functionCall ?? partRecord.function_call);
47697
- const functionName = scalarToString(functionCall.name);
47712
+ const rawFunctionName = scalarToString(functionCall.name) ?? "";
47713
+ const functionName = resolveGeminiFunctionName(rawFunctionName, availableFunctions);
47698
47714
  if (!functionName) {
47699
- continue;
47715
+ throw new Error(`Gemini requested unknown function '${rawFunctionName}'.`);
47700
47716
  }
47701
47717
  const result = await this.handleToolExecution({
47702
47718
  functionName,
47703
47719
  functionArgs: readObject2(functionCall.args),
47704
47720
  availableFunctions
47705
47721
  });
47706
- if (result !== null) {
47707
- return result;
47722
+ if (result === null) {
47723
+ throw new Error(`Gemini failed to execute function '${rawFunctionName}'.`);
47708
47724
  }
47725
+ firstToolResult ??= result;
47726
+ functionResponseParts.push({
47727
+ functionResponse: {
47728
+ name: rawFunctionName,
47729
+ response: { result }
47730
+ }
47731
+ });
47709
47732
  }
47733
+ if (!generateContent) {
47734
+ return firstToolResult;
47735
+ }
47736
+ currentContents = [
47737
+ ...currentContents,
47738
+ { role: "model", parts: rawParts },
47739
+ { role: "user", parts: functionResponseParts }
47740
+ ];
47741
+ currentResponse = await generateContent(currentContents);
47710
47742
  }
47711
- return _GeminiCompletion.extractTextFromResponse(response);
47743
+ throw new Error(`Gemini tool loop exceeded max tool rounds (${String(maxToolRounds)}).`);
47712
47744
  }
47713
47745
  async _process_response_with_tools(response, contents = [], availableFunctions = null) {
47714
47746
  return await this.processResponseWithTools(response, contents, availableFunctions);
@@ -48797,6 +48829,19 @@ function geminiVersion(model) {
48797
48829
  const match = /gemini-(\d+(?:\.\d+)?)/iu.exec(model.toLowerCase());
48798
48830
  return match ? Number.parseFloat(match[1] ?? "0") : 0;
48799
48831
  }
48832
+ var DEFAULT_GEMINI_MAX_TOOL_ROUNDS = 8;
48833
+ function geminiMaxToolRounds(options) {
48834
+ const record = readObject2(options);
48835
+ const configured = record.maxToolRounds ?? record.max_tool_rounds;
48836
+ return typeof configured === "number" && Number.isInteger(configured) && configured > 0 ? configured : DEFAULT_GEMINI_MAX_TOOL_ROUNDS;
48837
+ }
48838
+ function resolveGeminiFunctionName(functionName, availableFunctions) {
48839
+ if (functionName in availableFunctions) {
48840
+ return functionName;
48841
+ }
48842
+ const sanitizedName = sanitizeToolName(functionName);
48843
+ return sanitizedName in availableFunctions ? sanitizedName : null;
48844
+ }
48800
48845
  function geminiTextParts(content) {
48801
48846
  if (Array.isArray(content)) {
48802
48847
  return content.map((item) => {
@@ -52088,9 +52133,11 @@ ${todo.description}`);
52088
52133
  if (this.tools.length === 0) {
52089
52134
  return Object.keys(options).length > 0 ? options : void 0;
52090
52135
  }
52091
- const [tools] = setupNativeTools(this.tools);
52136
+ const [tools, availableFunctions] = setupNativeTools(this.tools);
52092
52137
  if (tools.length > 0) {
52093
52138
  options.tools = tools;
52139
+ options.availableFunctions = availableFunctions;
52140
+ options.available_functions = availableFunctions;
52094
52141
  }
52095
52142
  return Object.keys(options).length > 0 ? options : void 0;
52096
52143
  }
package/dist/index.js CHANGED
@@ -31009,33 +31009,37 @@ var GeminiCompletion = class _GeminiCompletion extends ConfiguredLLM {
31009
31009
  delete generationConfigBody.safety_settings;
31010
31010
  const model = this.model.replace(/^(?:gemini|google)\//, "");
31011
31011
  const baseUrl = this.baseUrl ?? "https://generativelanguage.googleapis.com/v1beta";
31012
- const requestInit = {
31012
+ const buildRequestInit = (currentContents) => ({
31013
31013
  method: "POST",
31014
31014
  headers: { "Content-Type": "application/json" },
31015
31015
  body: JSON.stringify({
31016
- contents,
31016
+ contents: currentContents,
31017
31017
  ...Object.keys(generationConfigBody).length > 0 ? { generationConfig: generationConfigBody } : {},
31018
31018
  ..."system_instruction" in requestBody ? { system_instruction: requestBody.system_instruction } : {},
31019
31019
  ..."tools" in requestBody ? { tools: requestBody.tools } : {},
31020
31020
  ..."safety_settings" in requestBody ? { safety_settings: requestBody.safety_settings } : {}
31021
- })
31022
- };
31023
- if (options?.signal) {
31024
- requestInit.signal = options.signal;
31025
- }
31026
- return fetch(
31027
- `${baseUrl.replace(/\/$/, "")}/models/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`,
31028
- requestInit
31029
- ).then(async (response) => {
31021
+ }),
31022
+ ...options?.signal ? { signal: options.signal } : {}
31023
+ });
31024
+ const generateContent = async (currentContents) => {
31025
+ const response = await fetch(
31026
+ `${baseUrl.replace(/\/$/, "")}/models/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`,
31027
+ buildRequestInit(currentContents)
31028
+ );
31030
31029
  const body = await response.json();
31031
31030
  if (!response.ok) {
31032
31031
  const error = readObject2(readObject2(body).error);
31033
31032
  throw new Error(scalarToString(error.message) ?? `Gemini request failed with HTTP ${response.status.toString()}.`);
31034
31033
  }
31034
+ return body;
31035
+ };
31036
+ return generateContent(contents).then(async (body) => {
31035
31037
  return await this.processResponseWithTools(
31036
31038
  body,
31037
31039
  contents,
31038
- options?.availableFunctions ?? options?.available_functions ?? null
31040
+ options?.availableFunctions ?? options?.available_functions ?? null,
31041
+ generateContent,
31042
+ geminiMaxToolRounds(options)
31039
31043
  );
31040
31044
  });
31041
31045
  }
@@ -31335,42 +31339,69 @@ ${textContent}` : textContent;
31335
31339
  static extract_structured_output_from_response(response) {
31336
31340
  return _GeminiCompletion.extractStructuredOutputFromResponse(response);
31337
31341
  }
31338
- async processResponseWithTools(response, contents = [], availableFunctions = null) {
31339
- void contents;
31340
- const candidates = readObject2(response).candidates;
31341
- if (!Array.isArray(candidates)) {
31342
- return _GeminiCompletion.extractTextFromResponse(response);
31343
- }
31344
- const first = readObject2(candidates[0]);
31345
- const rawParts = Array.isArray(readObject2(first.content).parts) ? readObject2(first.content).parts : [];
31346
- const functionCallParts = rawParts.filter((part) => Object.keys(readObject2(readObject2(part).functionCall ?? readObject2(part).function_call)).length > 0);
31347
- const nonStructuredParts = functionCallParts.filter((part) => {
31348
- const partRecord = readObject2(part);
31349
- const functionCall = readObject2(partRecord.functionCall ?? partRecord.function_call);
31350
- return (scalarToString(functionCall.name) ?? "") !== STRUCTURED_OUTPUT_TOOL_NAME;
31351
- });
31352
- if (nonStructuredParts.length > 0 && !availableFunctions) {
31353
- return nonStructuredParts;
31354
- }
31355
- if (nonStructuredParts.length > 0 && availableFunctions) {
31342
+ async processResponseWithTools(response, contents = [], availableFunctions = null, generateContent = null, maxToolRounds = DEFAULT_GEMINI_MAX_TOOL_ROUNDS) {
31343
+ let currentResponse = response;
31344
+ let currentContents = [...contents];
31345
+ for (let round = 0; round <= maxToolRounds; round += 1) {
31346
+ const candidates = readObject2(currentResponse).candidates;
31347
+ if (!Array.isArray(candidates)) {
31348
+ return _GeminiCompletion.extractTextFromResponse(currentResponse);
31349
+ }
31350
+ const first = readObject2(candidates[0]);
31351
+ const rawParts = Array.isArray(readObject2(first.content).parts) ? readObject2(first.content).parts : [];
31352
+ const functionCallParts = rawParts.filter((part) => Object.keys(readObject2(readObject2(part).functionCall ?? readObject2(part).function_call)).length > 0);
31353
+ const structuredOutput = _GeminiCompletion.extractStructuredOutputFromResponse(currentResponse);
31354
+ const nonStructuredParts = functionCallParts.filter((part) => {
31355
+ const partRecord = readObject2(part);
31356
+ const functionCall = readObject2(partRecord.functionCall ?? partRecord.function_call);
31357
+ return (scalarToString(functionCall.name) ?? "") !== STRUCTURED_OUTPUT_TOOL_NAME;
31358
+ });
31359
+ if (nonStructuredParts.length === 0) {
31360
+ return structuredOutput ?? _GeminiCompletion.extractTextFromResponse(currentResponse);
31361
+ }
31362
+ if (!availableFunctions) {
31363
+ return nonStructuredParts;
31364
+ }
31365
+ if (round >= maxToolRounds) {
31366
+ throw new Error(`Gemini tool loop exceeded max tool rounds (${String(maxToolRounds)}).`);
31367
+ }
31368
+ const functionResponseParts = [];
31369
+ let firstToolResult = null;
31356
31370
  for (const part of nonStructuredParts) {
31357
31371
  const partRecord = readObject2(part);
31358
31372
  const functionCall = readObject2(partRecord.functionCall ?? partRecord.function_call);
31359
- const functionName = scalarToString(functionCall.name);
31373
+ const rawFunctionName = scalarToString(functionCall.name) ?? "";
31374
+ const functionName = resolveGeminiFunctionName(rawFunctionName, availableFunctions);
31360
31375
  if (!functionName) {
31361
- continue;
31376
+ throw new Error(`Gemini requested unknown function '${rawFunctionName}'.`);
31362
31377
  }
31363
31378
  const result = await this.handleToolExecution({
31364
31379
  functionName,
31365
31380
  functionArgs: readObject2(functionCall.args),
31366
31381
  availableFunctions
31367
31382
  });
31368
- if (result !== null) {
31369
- return result;
31383
+ if (result === null) {
31384
+ throw new Error(`Gemini failed to execute function '${rawFunctionName}'.`);
31370
31385
  }
31386
+ firstToolResult ??= result;
31387
+ functionResponseParts.push({
31388
+ functionResponse: {
31389
+ name: rawFunctionName,
31390
+ response: { result }
31391
+ }
31392
+ });
31371
31393
  }
31394
+ if (!generateContent) {
31395
+ return firstToolResult;
31396
+ }
31397
+ currentContents = [
31398
+ ...currentContents,
31399
+ { role: "model", parts: rawParts },
31400
+ { role: "user", parts: functionResponseParts }
31401
+ ];
31402
+ currentResponse = await generateContent(currentContents);
31372
31403
  }
31373
- return _GeminiCompletion.extractTextFromResponse(response);
31404
+ throw new Error(`Gemini tool loop exceeded max tool rounds (${String(maxToolRounds)}).`);
31374
31405
  }
31375
31406
  async _process_response_with_tools(response, contents = [], availableFunctions = null) {
31376
31407
  return await this.processResponseWithTools(response, contents, availableFunctions);
@@ -32459,6 +32490,19 @@ function geminiVersion(model) {
32459
32490
  const match = /gemini-(\d+(?:\.\d+)?)/iu.exec(model.toLowerCase());
32460
32491
  return match ? Number.parseFloat(match[1] ?? "0") : 0;
32461
32492
  }
32493
+ var DEFAULT_GEMINI_MAX_TOOL_ROUNDS = 8;
32494
+ function geminiMaxToolRounds(options) {
32495
+ const record = readObject2(options);
32496
+ const configured = record.maxToolRounds ?? record.max_tool_rounds;
32497
+ return typeof configured === "number" && Number.isInteger(configured) && configured > 0 ? configured : DEFAULT_GEMINI_MAX_TOOL_ROUNDS;
32498
+ }
32499
+ function resolveGeminiFunctionName(functionName, availableFunctions) {
32500
+ if (functionName in availableFunctions) {
32501
+ return functionName;
32502
+ }
32503
+ const sanitizedName = sanitizeToolName(functionName);
32504
+ return sanitizedName in availableFunctions ? sanitizedName : null;
32505
+ }
32462
32506
  function geminiTextParts(content) {
32463
32507
  if (Array.isArray(content)) {
32464
32508
  return content.map((item) => {
@@ -35736,9 +35780,11 @@ ${todo.description}`);
35736
35780
  if (this.tools.length === 0) {
35737
35781
  return Object.keys(options).length > 0 ? options : void 0;
35738
35782
  }
35739
- const [tools] = setupNativeTools(this.tools);
35783
+ const [tools, availableFunctions] = setupNativeTools(this.tools);
35740
35784
  if (tools.length > 0) {
35741
35785
  options.tools = tools;
35786
+ options.availableFunctions = availableFunctions;
35787
+ options.available_functions = availableFunctions;
35742
35788
  }
35743
35789
  return Object.keys(options).length > 0 ? options : void 0;
35744
35790
  }
@@ -358,7 +358,7 @@ export declare class GeminiCompletion extends ConfiguredLLM {
358
358
  static extract_function_calls_from_response(response: unknown): Record<string, unknown>[];
359
359
  static extractStructuredOutputFromResponse(response: unknown): Record<string, unknown> | null;
360
360
  static extract_structured_output_from_response(response: unknown): Record<string, unknown> | null;
361
- processResponseWithTools(response: unknown, contents?: readonly unknown[], availableFunctions?: Record<string, LLMAvailableFunction> | null): Promise<unknown>;
361
+ processResponseWithTools(response: unknown, contents?: readonly unknown[], availableFunctions?: Record<string, LLMAvailableFunction> | null, generateContent?: ((contents: readonly unknown[]) => Promise<unknown>) | null, maxToolRounds?: number): Promise<unknown>;
362
362
  _process_response_with_tools(response: unknown, contents?: readonly unknown[], availableFunctions?: Record<string, LLMAvailableFunction> | null): Promise<unknown>;
363
363
  static addPropertyOrdering<T extends Record<string, unknown>>(schema: T): T;
364
364
  static add_property_ordering<T extends Record<string, unknown>>(schema: T): T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewai-ts/core",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Unofficial TypeScript port of CrewAI (not affiliated with crewAI, Inc.).",
5
5
  "keywords": [
6
6
  "crewai",