@aigne/core 1.5.1-1 → 1.6.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 (71) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/lib/cjs/agents/mcp-agent.d.ts +34 -7
  3. package/lib/cjs/agents/mcp-agent.js +55 -8
  4. package/lib/cjs/agents/user-agent.d.ts +1 -0
  5. package/lib/cjs/agents/user-agent.js +2 -1
  6. package/lib/cjs/execution-engine/execution-engine.d.ts +13 -2
  7. package/lib/cjs/execution-engine/execution-engine.js +20 -3
  8. package/lib/cjs/loader/agent-js.d.ts +17 -0
  9. package/lib/cjs/loader/agent-js.js +67 -0
  10. package/lib/cjs/loader/agent-yaml.d.ts +24 -0
  11. package/lib/cjs/loader/agent-yaml.js +58 -0
  12. package/lib/cjs/loader/index.d.ts +35 -0
  13. package/lib/cjs/loader/index.js +128 -0
  14. package/lib/cjs/loader/schema.d.ts +17 -0
  15. package/lib/cjs/loader/schema.js +10 -0
  16. package/lib/cjs/models/claude-chat-model.d.ts +1 -1
  17. package/lib/cjs/models/claude-chat-model.js +3 -2
  18. package/lib/cjs/models/openai-chat-model.d.ts +1 -1
  19. package/lib/cjs/models/openai-chat-model.js +4 -3
  20. package/lib/cjs/models/xai-chat-model.d.ts +2 -0
  21. package/lib/cjs/models/xai-chat-model.js +14 -0
  22. package/lib/cjs/utils/json-schema.js +1 -1
  23. package/lib/cjs/utils/logger.d.ts +3 -1
  24. package/lib/cjs/utils/logger.js +13 -10
  25. package/lib/cjs/utils/mcp-utils.d.ts +4 -5
  26. package/lib/cjs/utils/mcp-utils.js +6 -6
  27. package/lib/cjs/utils/run-chat-loop.js +3 -1
  28. package/lib/cjs/utils/type-utils.d.ts +2 -0
  29. package/lib/cjs/utils/type-utils.js +38 -1
  30. package/lib/dts/agents/mcp-agent.d.ts +34 -7
  31. package/lib/dts/agents/user-agent.d.ts +1 -0
  32. package/lib/dts/execution-engine/execution-engine.d.ts +13 -2
  33. package/lib/dts/loader/agent-js.d.ts +17 -0
  34. package/lib/dts/loader/agent-yaml.d.ts +24 -0
  35. package/lib/dts/loader/index.d.ts +35 -0
  36. package/lib/dts/loader/schema.d.ts +17 -0
  37. package/lib/dts/models/claude-chat-model.d.ts +1 -1
  38. package/lib/dts/models/openai-chat-model.d.ts +1 -1
  39. package/lib/dts/models/xai-chat-model.d.ts +2 -0
  40. package/lib/dts/utils/logger.d.ts +3 -1
  41. package/lib/dts/utils/mcp-utils.d.ts +4 -5
  42. package/lib/dts/utils/type-utils.d.ts +2 -0
  43. package/lib/esm/agents/mcp-agent.d.ts +34 -7
  44. package/lib/esm/agents/mcp-agent.js +52 -8
  45. package/lib/esm/agents/user-agent.d.ts +1 -0
  46. package/lib/esm/agents/user-agent.js +1 -0
  47. package/lib/esm/execution-engine/execution-engine.d.ts +13 -2
  48. package/lib/esm/execution-engine/execution-engine.js +21 -4
  49. package/lib/esm/loader/agent-js.d.ts +17 -0
  50. package/lib/esm/loader/agent-js.js +31 -0
  51. package/lib/esm/loader/agent-yaml.d.ts +24 -0
  52. package/lib/esm/loader/agent-yaml.js +55 -0
  53. package/lib/esm/loader/index.d.ts +35 -0
  54. package/lib/esm/loader/index.js +123 -0
  55. package/lib/esm/loader/schema.d.ts +17 -0
  56. package/lib/esm/loader/schema.js +7 -0
  57. package/lib/esm/models/claude-chat-model.d.ts +1 -1
  58. package/lib/esm/models/claude-chat-model.js +3 -2
  59. package/lib/esm/models/openai-chat-model.d.ts +1 -1
  60. package/lib/esm/models/openai-chat-model.js +4 -3
  61. package/lib/esm/models/xai-chat-model.d.ts +2 -0
  62. package/lib/esm/models/xai-chat-model.js +11 -0
  63. package/lib/esm/utils/json-schema.js +1 -1
  64. package/lib/esm/utils/logger.d.ts +3 -1
  65. package/lib/esm/utils/logger.js +13 -10
  66. package/lib/esm/utils/mcp-utils.d.ts +4 -5
  67. package/lib/esm/utils/mcp-utils.js +6 -6
  68. package/lib/esm/utils/run-chat-loop.js +3 -1
  69. package/lib/esm/utils/type-utils.d.ts +2 -0
  70. package/lib/esm/utils/type-utils.js +36 -1
  71. package/package.json +15 -9
@@ -1,3 +1,4 @@
1
+ import OpenAI from "openai";
1
2
  import { OpenAIChatModel } from "./openai-chat-model.js";
2
3
  const XAI_DEFAULT_CHAT_MODEL = "grok-2-latest";
3
4
  const XAI_BASE_URL = "https://api.x.ai/v1";
@@ -9,4 +10,14 @@ export class XAIChatModel extends OpenAIChatModel {
9
10
  baseURL: options?.baseURL || XAI_BASE_URL,
10
11
  });
11
12
  }
13
+ get client() {
14
+ const apiKey = this.options?.apiKey || process.env.XAI_API_KEY;
15
+ if (!apiKey)
16
+ throw new Error("Api Key is required for XAIChatModel");
17
+ this._client ??= new OpenAI({
18
+ baseURL: this.options?.baseURL,
19
+ apiKey,
20
+ });
21
+ return this._client;
22
+ }
12
23
  }
@@ -7,7 +7,7 @@ function setAdditionPropertiesDeep(schema, additionalProperties) {
7
7
  if (Array.isArray(schema)) {
8
8
  return schema.map((s) => setAdditionPropertiesDeep(s, additionalProperties));
9
9
  }
10
- if (schema && typeof schema === "object" && !Array.isArray(schema)) {
10
+ if (schema !== null && typeof schema === "object" && !Array.isArray(schema)) {
11
11
  return Object.entries(schema).reduce((acc, [key, value]) => {
12
12
  acc[key] = setAdditionPropertiesDeep(value, additionalProperties);
13
13
  if (acc.type === "object") {
@@ -1,4 +1,5 @@
1
1
  import debug, { type Debugger } from "debug";
2
+ import type { Ora } from "ora";
2
3
  interface DebugWithSpinner extends Debugger {
3
4
  spinner<T>(promise: Promise<T>, message?: string, callback?: (result: T) => void, options?: {
4
5
  disabled?: boolean;
@@ -10,9 +11,10 @@ export declare const logger: debug.Debug & {
10
11
  debug: debug.Debug;
11
12
  default: debug.Debug;
12
13
  } & {
13
- globalSpinner: import("@aigne/ora").Ora;
14
+ globalSpinner: Ora | undefined;
14
15
  base: DebugWithSpinner;
15
16
  debug: DebugWithSpinner;
16
17
  spinner: typeof spinner;
18
+ setSpinner: (spinner: Ora) => void;
17
19
  };
18
20
  export {};
@@ -1,12 +1,11 @@
1
- import ora from "@aigne/ora";
2
1
  import debug from "debug";
3
2
  debug.log = (...args) => {
4
- const { isSpinning } = globalSpinner;
3
+ const { isSpinning } = globalSpinner ?? {};
5
4
  if (isSpinning)
6
- globalSpinner.stop();
5
+ globalSpinner?.stop();
7
6
  console.log(...args);
8
7
  if (isSpinning)
9
- globalSpinner.start();
8
+ globalSpinner?.start();
10
9
  };
11
10
  function createDebugger(namespace) {
12
11
  const i = debug(namespace);
@@ -26,12 +25,12 @@ function createDebugger(namespace) {
26
25
  overrideExtend(i);
27
26
  return i;
28
27
  }
29
- const globalSpinner = ora();
28
+ let globalSpinner;
30
29
  const globalSpinnerTasks = [];
31
30
  async function spinner(promise, message, callback) {
32
31
  const task = { promise, message, callback };
33
32
  globalSpinnerTasks.push(task);
34
- globalSpinner.start(message || " ");
33
+ globalSpinner?.start(message || " ");
35
34
  await promise
36
35
  .then((result) => {
37
36
  task.result = result;
@@ -48,18 +47,18 @@ async function spinner(promise, message, callback) {
48
47
  break;
49
48
  // Recover spinner state for last running task
50
49
  if (!task.status) {
51
- globalSpinner.start(task.message || " ");
50
+ globalSpinner?.start(task.message || " ");
52
51
  break;
53
52
  }
54
53
  globalSpinnerTasks.pop();
55
54
  if (task.message) {
56
55
  if (task.status === "fail")
57
- globalSpinner.fail(task.message);
56
+ globalSpinner?.fail(task.message);
58
57
  else
59
- globalSpinner.succeed(task.message);
58
+ globalSpinner?.succeed(task.message);
60
59
  }
61
60
  else {
62
- globalSpinner.stop();
61
+ globalSpinner?.stop();
63
62
  }
64
63
  // NOTE: This is a workaround to make sure the spinner stops spinning before the next tick
65
64
  await new Promise((resolve) => setTimeout(resolve, 10));
@@ -74,4 +73,8 @@ export const logger = Object.assign(debug, {
74
73
  base,
75
74
  debug: base.extend("core"),
76
75
  spinner,
76
+ setSpinner: (spinner) => {
77
+ globalSpinner = spinner;
78
+ logger.globalSpinner = spinner;
79
+ },
77
80
  });
@@ -1,6 +1,5 @@
1
- import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
1
  import { type ListPromptsResult, type ListResourceTemplatesResult, type ListResourcesResult, type ListToolsResult } from "@modelcontextprotocol/sdk/types.js";
3
- import { MCPPrompt, MCPResource, MCPTool } from "../agents/mcp-agent.js";
4
- export declare function toolFromMCPTool(client: Client, tool: ListToolsResult["tools"][number]): MCPTool;
5
- export declare function promptFromMCPPrompt(client: Client, prompt: ListPromptsResult["prompts"][number]): MCPPrompt;
6
- export declare function resourceFromMCPResource(client: Client, resource: ListResourcesResult["resources"][number] | ListResourceTemplatesResult["resourceTemplates"][number]): MCPResource;
2
+ import { type MCPBaseOptions, MCPPrompt, MCPResource, MCPTool } from "../agents/mcp-agent.js";
3
+ export declare function toolFromMCPTool(tool: ListToolsResult["tools"][number], options: MCPBaseOptions): MCPTool;
4
+ export declare function promptFromMCPPrompt(prompt: ListPromptsResult["prompts"][number], options: MCPBaseOptions): MCPPrompt;
5
+ export declare function resourceFromMCPResource(resource: ListResourcesResult["resources"][number] | ListResourceTemplatesResult["resourceTemplates"][number], options: MCPBaseOptions): MCPResource;
@@ -3,18 +3,18 @@ import { UriTemplate } from "@modelcontextprotocol/sdk/shared/uriTemplate.js";
3
3
  import { CallToolResultSchema, GetPromptResultSchema, ReadResourceResultSchema, } from "@modelcontextprotocol/sdk/types.js";
4
4
  import { z } from "zod";
5
5
  import { MCPPrompt, MCPResource, MCPTool } from "../agents/mcp-agent.js";
6
- export function toolFromMCPTool(client, tool) {
6
+ export function toolFromMCPTool(tool, options) {
7
7
  return new MCPTool({
8
- client,
8
+ ...options,
9
9
  name: tool.name,
10
10
  description: tool.description,
11
11
  inputSchema: jsonSchemaToZod(tool.inputSchema),
12
12
  outputSchema: CallToolResultSchema,
13
13
  });
14
14
  }
15
- export function promptFromMCPPrompt(client, prompt) {
15
+ export function promptFromMCPPrompt(prompt, options) {
16
16
  return new MCPPrompt({
17
- client,
17
+ ...options,
18
18
  name: prompt.name,
19
19
  description: prompt.description,
20
20
  inputSchema: jsonSchemaToZod({
@@ -26,7 +26,7 @@ export function promptFromMCPPrompt(client, prompt) {
26
26
  outputSchema: GetPromptResultSchema,
27
27
  });
28
28
  }
29
- export function resourceFromMCPResource(client, resource) {
29
+ export function resourceFromMCPResource(resource, options) {
30
30
  const [uri, variables] = isResourceTemplate(resource)
31
31
  ? [
32
32
  resource.uriTemplate,
@@ -35,7 +35,7 @@ export function resourceFromMCPResource(client, resource) {
35
35
  ]
36
36
  : [resource.uri, []];
37
37
  return new MCPResource({
38
- client,
38
+ ...options,
39
39
  name: resource.name,
40
40
  uri,
41
41
  description: resource.description,
@@ -1,6 +1,8 @@
1
1
  import inquirer from "inquirer";
2
+ import ora from "ora";
2
3
  import { logger } from "./logger.js";
3
4
  export async function runChatLoopInTerminal(userAgent, { log = console.log.bind(console), ...options } = {}) {
5
+ logger.setSpinner(ora());
4
6
  let isLoopExited = false;
5
7
  let prompt;
6
8
  if (options?.welcome)
@@ -13,7 +15,7 @@ export async function runChatLoopInTerminal(userAgent, { log = console.log.bind(
13
15
  if (isLoopExited)
14
16
  return;
15
17
  if (options?.onResponse)
16
- options.onResponse(output);
18
+ options.onResponse(output.message);
17
19
  else
18
20
  log(output);
19
21
  prompt?.ui.close();
@@ -5,8 +5,10 @@ export declare function isNil(value: unknown): value is null | undefined;
5
5
  export declare function isEmpty(obj: unknown): boolean;
6
6
  export declare function isNonNullable<T>(value: T): value is NonNullable<T>;
7
7
  export declare function isNotEmpty<T>(arr: T[]): arr is [T, ...T[]];
8
+ export declare function duplicates<T>(arr: T[], key?: (item: T) => unknown): T[];
8
9
  export declare function orArrayToArray<T>(value?: T | T[]): T[];
9
10
  export declare function createAccessorArray<T>(array: T[], accessor: (array: T[], name: string) => T | undefined): T[] & {
10
11
  [key: string]: T;
11
12
  };
12
13
  export declare function checkArguments<T>(prefix: string, schema: ZodType<T>, args: T): void;
14
+ export declare function tryOrThrow<P extends PromiseOrValue<unknown>>(fn: () => P, error: string | Error | ((error: Error) => Error)): P;
@@ -8,7 +8,7 @@ export function isEmpty(obj) {
8
8
  if (typeof obj === "string" || Array.isArray(obj))
9
9
  return obj.length === 0;
10
10
  if (typeof obj === "object")
11
- Object.keys(obj).length === 0;
11
+ return Object.keys(obj).length === 0;
12
12
  return false;
13
13
  }
14
14
  export function isNonNullable(value) {
@@ -17,6 +17,20 @@ export function isNonNullable(value) {
17
17
  export function isNotEmpty(arr) {
18
18
  return arr.length > 0;
19
19
  }
20
+ export function duplicates(arr, key = (item) => item) {
21
+ const seen = new Set();
22
+ const duplicates = new Set();
23
+ for (const item of arr) {
24
+ const k = key(item);
25
+ if (seen.has(k)) {
26
+ duplicates.add(item);
27
+ }
28
+ else {
29
+ seen.add(k);
30
+ }
31
+ }
32
+ return Array.from(duplicates);
33
+ }
20
34
  export function orArrayToArray(value) {
21
35
  if (isNil(value))
22
36
  return [];
@@ -69,3 +83,24 @@ export function checkArguments(prefix, schema, args) {
69
83
  throw error;
70
84
  }
71
85
  }
86
+ export function tryOrThrow(fn, error) {
87
+ const createError = (e) => {
88
+ return typeof error === "function"
89
+ ? error(e)
90
+ : typeof error === "string"
91
+ ? new Error(error)
92
+ : error;
93
+ };
94
+ try {
95
+ const result = fn();
96
+ if (result instanceof Promise) {
97
+ return result.catch((e) => {
98
+ throw createError(e);
99
+ });
100
+ }
101
+ return result;
102
+ }
103
+ catch (e) {
104
+ throw createError(e);
105
+ }
106
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.5.1-1",
3
+ "version": "1.6.0",
4
4
  "description": "AIGNE core library for building AI-powered applications",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -60,13 +60,15 @@
60
60
  },
61
61
  "dependencies": {
62
62
  "@aigne/json-schema-to-zod": "^1.3.3",
63
- "@aigne/ora": "^8.2.0",
64
63
  "@modelcontextprotocol/sdk": "^1.8.0",
65
64
  "@types/debug": "^4.1.12",
66
65
  "debug": "^4.4.0",
67
66
  "inquirer": "^12.5.0",
68
67
  "mustache": "^4.2.0",
69
68
  "nanoid": "^5.1.5",
69
+ "ora": "^8.2.0",
70
+ "p-retry": "^6.2.1",
71
+ "yaml": "^2.7.1",
70
72
  "zod": "^3.24.2",
71
73
  "zod-to-json-schema": "^3.24.5"
72
74
  },
@@ -78,20 +80,24 @@
78
80
  "devDependencies": {
79
81
  "@anthropic-ai/sdk": "^0.39.0",
80
82
  "@google/generative-ai": "^0.24.0",
81
- "@types/bun": "^1.2.6",
83
+ "@types/bun": "^1.2.8",
84
+ "@types/express": "^5.0.1",
82
85
  "@types/mustache": "^4.2.5",
83
- "@types/node": "^22.13.14",
86
+ "@types/node": "^22.14.0",
87
+ "detect-port": "^2.1.0",
88
+ "express": "^5.1.0",
84
89
  "npm-run-all": "^4.1.5",
85
- "openai": "^4.89.1",
90
+ "openai": "^4.91.1",
86
91
  "rimraf": "^6.0.1",
87
- "typescript": "^5.8.2"
92
+ "typescript": "^5.8.2",
93
+ "@aigne/test-utils": "^1.0.0"
88
94
  },
89
95
  "scripts": {
90
96
  "lint": "tsc --noEmit",
91
97
  "build": "tsc --build scripts/tsconfig.build.json",
92
- "clean": "rimraf lib coverage",
93
- "test": "bun test",
94
- "test:coverage": "bun test --coverage --coverage-reporter=lcov --coverage-reporter=text",
98
+ "clean": "rimraf lib test/coverage",
99
+ "test": "bun --cwd test test",
100
+ "test:coverage": "bun --cwd test test --coverage --coverage-reporter=lcov --coverage-reporter=text",
95
101
  "postbuild": "echo '{\"type\": \"module\"}' > lib/esm/package.json && echo '{\"type\": \"commonjs\"}' > lib/cjs/package.json"
96
102
  }
97
103
  }