@aigne/core 1.0.3 → 1.0.4

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,18 +1,21 @@
1
- export * from "./utils";
1
+ export * from "./agent";
2
2
  export * from "./constants";
3
+ export * from "./context";
3
4
  export * from "./definitions/data-type";
4
5
  export * from "./definitions/data-type-schema";
5
- export * from "./definitions/open-api";
6
6
  export * from "./definitions/memory";
7
- export * from "./context";
8
- export * from "./runnable";
9
- export * from "./agent";
10
- export * from "./pipeline-agent";
11
- export * from "./llm-agent";
12
- export * from "./llm-model";
7
+ export * from "./definitions/open-api";
13
8
  export * from "./function-agent";
14
9
  export * from "./function-runner";
10
+ export * from "./llm-agent";
15
11
  export * from "./llm-decision-agent";
12
+ export * from "./llm-model";
13
+ export * from "./llm-models/gemini-llm-model";
14
+ export * from "./llm-models/openai-llm-model";
16
15
  export * from "./local-function-agent";
17
- export * from "./open-api-agent";
18
16
  export * from "./memorable";
17
+ export * from "./open-api-agent";
18
+ export * from "./pipeline-agent";
19
+ export * from "./runnable";
20
+ export * from "./runtime";
21
+ export * from "./utils";
@@ -0,0 +1,26 @@
1
+ import { LLMModel, type LLMModelInputs } from "../llm-model";
2
+ export declare class GeminiLLMModel extends LLMModel {
3
+ config: {
4
+ apiKey: string;
5
+ model: string;
6
+ };
7
+ constructor(config: {
8
+ apiKey: string;
9
+ model: string;
10
+ });
11
+ private client;
12
+ private model;
13
+ process(input: LLMModelInputs): AsyncGenerator<{
14
+ $text: string;
15
+ delta: {
16
+ toolCalls: {
17
+ id?: string;
18
+ type?: "function";
19
+ function?: {
20
+ name?: string;
21
+ arguments?: string;
22
+ };
23
+ }[];
24
+ };
25
+ }, void, unknown>;
26
+ }
@@ -0,0 +1,25 @@
1
+ import { LLMModel, type LLMModelInputs } from "../llm-model";
2
+ export declare class OpenaiLLMModel extends LLMModel {
3
+ config: {
4
+ apiKey: string;
5
+ model: string;
6
+ };
7
+ constructor(config: {
8
+ apiKey: string;
9
+ model: string;
10
+ });
11
+ private client;
12
+ process(input: LLMModelInputs): AsyncGenerator<{
13
+ $text: string | undefined;
14
+ delta: {
15
+ toolCalls: {
16
+ id?: string;
17
+ type?: "function";
18
+ function?: {
19
+ name?: string;
20
+ arguments?: string;
21
+ };
22
+ }[];
23
+ };
24
+ }, void, unknown>;
25
+ }
@@ -0,0 +1,55 @@
1
+ import { type DependencyContainer } from "tsyringe";
2
+ import type { constructor as Constructor } from "tsyringe/dist/typings/types";
3
+ import type { Context, ContextState } from "./context";
4
+ import type { FunctionRunner } from "./function-runner";
5
+ import type { LLMModel, LLMModelConfiguration } from "./llm-model";
6
+ import { Runnable, type RunnableDefinition } from "./runnable";
7
+ import { OrderedRecord } from "./utils/ordered-map";
8
+ import type { DeepPartial } from "./utils/partial";
9
+ export interface RuntimeConfiguration {
10
+ llmModel?: LLMModelConfiguration;
11
+ }
12
+ export interface RuntimeOptions<Agents extends {
13
+ [name: string]: Runnable;
14
+ }, State extends ContextState> {
15
+ id?: string;
16
+ name?: string;
17
+ config?: RuntimeConfiguration;
18
+ state?: State;
19
+ agents?: Agents;
20
+ llmModel?: LLMModel | Constructor<LLMModel>;
21
+ functionRunner?: FunctionRunner | Constructor<FunctionRunner>;
22
+ }
23
+ export declare class Runtime<Agents extends {
24
+ [name: string]: Runnable;
25
+ } = {}, State extends ContextState = ContextState> implements Context<State> {
26
+ constructor(options?: RuntimeOptions<Agents, State>);
27
+ protected inner: RuntimeInner<Agents, State>;
28
+ get options(): RuntimeOptions<Agents, State>;
29
+ get id(): string;
30
+ get name(): string | undefined;
31
+ config: RuntimeConfiguration;
32
+ state: State;
33
+ agents: Agents;
34
+ private container;
35
+ setup(config: DeepPartial<RuntimeConfiguration>): void;
36
+ register<R extends Array<RunnableDefinition | Runnable> = []>(...runnables: R): void;
37
+ private resolveSync;
38
+ resolve<T extends Runnable>(id: string | RunnableDefinition | T): Promise<T>;
39
+ resolveDependency<T>(token: string | symbol): T;
40
+ copy<State extends ContextState = ContextState>(options: Pick<RuntimeOptions<Agents, State>, "state" | "config">): Runtime<Agents, State>;
41
+ }
42
+ declare class RuntimeInner<Agents extends {
43
+ [name: string]: Runnable;
44
+ } = {}, State extends ContextState = ContextState> {
45
+ options: RuntimeOptions<Agents, State>;
46
+ constructor(options: RuntimeOptions<Agents, State>);
47
+ readonly id: string;
48
+ readonly name?: string;
49
+ config: RuntimeConfiguration;
50
+ state: State;
51
+ container: DependencyContainer;
52
+ runnableDefinitions: OrderedRecord<RunnableDefinition>;
53
+ registerDependency<T>(token: string | symbol, dependency: Constructor<T> | T): void;
54
+ }
55
+ export {};
@@ -6,5 +6,6 @@ export * from "./nullable";
6
6
  export * from "./omit";
7
7
  export * from "./open-api-parameter";
8
8
  export * from "./ordered-map";
9
+ export * from "./partial";
9
10
  export * from "./stream-utils";
10
11
  export * from "./union";
@@ -0,0 +1,3 @@
1
+ export type DeepPartial<T> = T extends object ? {
2
+ [P in keyof T]?: DeepPartial<T[P]>;
3
+ } : T;
@@ -1,18 +1,21 @@
1
- export * from "./utils";
1
+ export * from "./agent";
2
2
  export * from "./constants";
3
+ export * from "./context";
3
4
  export * from "./definitions/data-type";
4
5
  export * from "./definitions/data-type-schema";
5
- export * from "./definitions/open-api";
6
6
  export * from "./definitions/memory";
7
- export * from "./context";
8
- export * from "./runnable";
9
- export * from "./agent";
10
- export * from "./pipeline-agent";
11
- export * from "./llm-agent";
12
- export * from "./llm-model";
7
+ export * from "./definitions/open-api";
13
8
  export * from "./function-agent";
14
9
  export * from "./function-runner";
10
+ export * from "./llm-agent";
15
11
  export * from "./llm-decision-agent";
12
+ export * from "./llm-model";
13
+ export * from "./llm-models/gemini-llm-model";
14
+ export * from "./llm-models/openai-llm-model";
16
15
  export * from "./local-function-agent";
17
- export * from "./open-api-agent";
18
16
  export * from "./memorable";
17
+ export * from "./open-api-agent";
18
+ export * from "./pipeline-agent";
19
+ export * from "./runnable";
20
+ export * from "./runtime";
21
+ export * from "./utils";
package/lib/esm/index.js CHANGED
@@ -1,18 +1,21 @@
1
- export * from "./utils";
1
+ export * from "./agent";
2
2
  export * from "./constants";
3
+ export * from "./context";
3
4
  export * from "./definitions/data-type";
4
5
  export * from "./definitions/data-type-schema";
5
- export * from "./definitions/open-api";
6
6
  export * from "./definitions/memory";
7
- export * from "./context";
8
- export * from "./runnable";
9
- export * from "./agent";
10
- export * from "./pipeline-agent";
11
- export * from "./llm-agent";
12
- export * from "./llm-model";
7
+ export * from "./definitions/open-api";
13
8
  export * from "./function-agent";
14
9
  export * from "./function-runner";
10
+ export * from "./llm-agent";
15
11
  export * from "./llm-decision-agent";
12
+ export * from "./llm-model";
13
+ export * from "./llm-models/gemini-llm-model";
14
+ export * from "./llm-models/openai-llm-model";
16
15
  export * from "./local-function-agent";
17
- export * from "./open-api-agent";
18
16
  export * from "./memorable";
17
+ export * from "./open-api-agent";
18
+ export * from "./pipeline-agent";
19
+ export * from "./runnable";
20
+ export * from "./runtime";
21
+ export * from "./utils";
@@ -0,0 +1,26 @@
1
+ import { LLMModel, type LLMModelInputs } from "../llm-model";
2
+ export declare class GeminiLLMModel extends LLMModel {
3
+ config: {
4
+ apiKey: string;
5
+ model: string;
6
+ };
7
+ constructor(config: {
8
+ apiKey: string;
9
+ model: string;
10
+ });
11
+ private client;
12
+ private model;
13
+ process(input: LLMModelInputs): AsyncGenerator<{
14
+ $text: string;
15
+ delta: {
16
+ toolCalls: {
17
+ id?: string;
18
+ type?: "function";
19
+ function?: {
20
+ name?: string;
21
+ arguments?: string;
22
+ };
23
+ }[];
24
+ };
25
+ }, void, unknown>;
26
+ }
@@ -0,0 +1,191 @@
1
+ import { FunctionCallingMode, GoogleGenerativeAI, SchemaType, } from "@google/generative-ai";
2
+ import { nanoid } from "nanoid";
3
+ import { LLMModel, } from "../llm-model";
4
+ import { isNonNullable } from "../utils/is-non-nullable";
5
+ export class GeminiLLMModel extends LLMModel {
6
+ config;
7
+ constructor(config) {
8
+ super();
9
+ this.config = config;
10
+ this.client = new GoogleGenerativeAI(this.config.apiKey);
11
+ this.model = this.client.getGenerativeModel({ model: this.config.model });
12
+ }
13
+ client;
14
+ model;
15
+ async *process(input) {
16
+ const res = await this.model.generateContentStream({
17
+ contents: await contentsFromInputMessages(input.messages),
18
+ tools: toolsFromInputTools(input.tools),
19
+ toolConfig: toolConfigFromInputToolChoice(input.toolChoice),
20
+ generationConfig: generationConfigFromInput(input),
21
+ });
22
+ const toolCalls = [];
23
+ for await (const chunk of res.stream) {
24
+ const choice = chunk.candidates?.[0];
25
+ if (choice?.content.parts) {
26
+ const calls = choice.content.parts
27
+ .filter((i) => typeof i.functionCall === "object")
28
+ .map((i) => ({
29
+ id: nanoid(),
30
+ type: "function",
31
+ function: {
32
+ name: i.functionCall.name,
33
+ arguments: JSON.stringify(i.functionCall.args),
34
+ },
35
+ }));
36
+ if (calls.length) {
37
+ toolCalls.push(...calls);
38
+ }
39
+ yield {
40
+ $text: choice.content.parts
41
+ .map((i) => i.text)
42
+ .filter(Boolean)
43
+ .join(""),
44
+ delta: { toolCalls },
45
+ };
46
+ }
47
+ else if (chunk.promptFeedback?.blockReason) {
48
+ const { blockReason, blockReasonMessage } = chunk.promptFeedback;
49
+ throw new Error(["PROMPT_BLOCKED", blockReason, blockReasonMessage]
50
+ .filter(Boolean)
51
+ .join(" "));
52
+ }
53
+ }
54
+ }
55
+ }
56
+ async function contentsFromInputMessages(messages) {
57
+ const contents = [];
58
+ let prevMsg;
59
+ while (messages.length) {
60
+ const message = messages.shift();
61
+ if (!prevMsg || message.role !== prevMsg.role) {
62
+ prevMsg = {
63
+ role: message.role === "assistant" ? "model" : "user",
64
+ parts: [],
65
+ };
66
+ contents.push(prevMsg);
67
+ }
68
+ if (typeof message.content === "string") {
69
+ prevMsg.parts.push({ text: message.content });
70
+ }
71
+ else if (Array.isArray(message.content)) {
72
+ const res = await Promise.all(message.content.map(resolveContent));
73
+ prevMsg.parts.push(...res.filter(isNonNullable));
74
+ }
75
+ }
76
+ return contents;
77
+ }
78
+ async function resolveContent(content) {
79
+ if (typeof content === "string")
80
+ return { text: content };
81
+ if (content.type === "text" && content.text) {
82
+ return { text: content.text };
83
+ }
84
+ if (content.type === "image_url") {
85
+ const url = content.imageUrl.url;
86
+ return { fileData: { mimeType: "image/jpeg", fileUri: url } };
87
+ }
88
+ return undefined;
89
+ }
90
+ function parameterSchemaToFunctionDeclarationSchema(schema) {
91
+ if (schema.type === "object") {
92
+ return {
93
+ type: SchemaType.OBJECT,
94
+ description: schema.description,
95
+ properties: Object.fromEntries(Object.entries(schema.properties).map(([key, s]) => [
96
+ key,
97
+ openAISchemaToGeminiSchema(s),
98
+ ])),
99
+ required: schema.required,
100
+ };
101
+ }
102
+ throw new Error(`Unsupported schema type ${schema.type}`);
103
+ }
104
+ function generationConfigFromInput(input) {
105
+ const jsonSchema = input.responseFormat?.type === "json_schema"
106
+ ? input.responseFormat.jsonSchema
107
+ : undefined;
108
+ return {
109
+ temperature: input.modelOptions?.temperature,
110
+ topP: input.modelOptions?.topP,
111
+ frequencyPenalty: input.modelOptions?.frequencyPenalty,
112
+ presencePenalty: input.modelOptions?.presencePenalty,
113
+ responseMimeType: jsonSchema ? "application/json" : undefined,
114
+ responseSchema: jsonSchema
115
+ ? openAISchemaToGeminiSchema(jsonSchema)
116
+ : undefined,
117
+ };
118
+ }
119
+ function toolConfigFromInputToolChoice(toolChoice) {
120
+ if (!toolChoice)
121
+ return undefined;
122
+ const selectedToolFunctionName = typeof toolChoice === "object" ? toolChoice.function.name : undefined;
123
+ return !toolChoice
124
+ ? undefined
125
+ : {
126
+ functionCallingConfig: {
127
+ mode: toolChoice === "required" || selectedToolFunctionName
128
+ ? FunctionCallingMode.ANY
129
+ : toolChoice === "none"
130
+ ? FunctionCallingMode.NONE
131
+ : FunctionCallingMode.AUTO,
132
+ allowedFunctionNames: selectedToolFunctionName
133
+ ? [selectedToolFunctionName]
134
+ : undefined,
135
+ },
136
+ };
137
+ }
138
+ function toolsFromInputTools(tools) {
139
+ return tools?.length
140
+ ? [
141
+ {
142
+ functionDeclarations: tools.map((i) => ({
143
+ name: i.function.name,
144
+ description: i.function.description,
145
+ parameters: !i.function.parameters ||
146
+ Object.keys(i.function.parameters).length === 0
147
+ ? undefined
148
+ : parameterSchemaToFunctionDeclarationSchema(i.function.parameters),
149
+ })),
150
+ },
151
+ ]
152
+ : undefined;
153
+ }
154
+ function openAISchemaToGeminiSchema(schema) {
155
+ if (schema.type === "string") {
156
+ return {
157
+ type: SchemaType.STRING,
158
+ description: schema.description,
159
+ };
160
+ }
161
+ if (schema.type === "number") {
162
+ return {
163
+ type: SchemaType.NUMBER,
164
+ description: schema.description,
165
+ };
166
+ }
167
+ if (schema.type === "boolean") {
168
+ return {
169
+ type: SchemaType.BOOLEAN,
170
+ description: schema.description,
171
+ };
172
+ }
173
+ if (schema.type === "object") {
174
+ return {
175
+ type: SchemaType.OBJECT,
176
+ description: schema.description,
177
+ properties: Object.fromEntries(Object.entries(schema.properties).map(([key, s]) => [
178
+ key,
179
+ openAISchemaToGeminiSchema(s),
180
+ ])),
181
+ required: schema.required,
182
+ };
183
+ }
184
+ if (schema.type === "array") {
185
+ return {
186
+ type: SchemaType.ARRAY,
187
+ items: openAISchemaToGeminiSchema(schema.items),
188
+ };
189
+ }
190
+ throw new Error(`Unsupported schema type ${schema.type}`);
191
+ }
@@ -0,0 +1,25 @@
1
+ import { LLMModel, type LLMModelInputs } from "../llm-model";
2
+ export declare class OpenaiLLMModel extends LLMModel {
3
+ config: {
4
+ apiKey: string;
5
+ model: string;
6
+ };
7
+ constructor(config: {
8
+ apiKey: string;
9
+ model: string;
10
+ });
11
+ private client;
12
+ process(input: LLMModelInputs): AsyncGenerator<{
13
+ $text: string | undefined;
14
+ delta: {
15
+ toolCalls: {
16
+ id?: string;
17
+ type?: "function";
18
+ function?: {
19
+ name?: string;
20
+ arguments?: string;
21
+ };
22
+ }[];
23
+ };
24
+ }, void, unknown>;
25
+ }
@@ -0,0 +1,113 @@
1
+ import { nanoid } from "nanoid";
2
+ import OpenAI from "openai";
3
+ import { LLMModel, } from "../llm-model";
4
+ import { isNonNullable } from "../utils/is-non-nullable";
5
+ export class OpenaiLLMModel extends LLMModel {
6
+ config;
7
+ constructor(config) {
8
+ super();
9
+ this.config = config;
10
+ this.client = new OpenAI({ apiKey: this.config.apiKey });
11
+ }
12
+ client;
13
+ async *process(input) {
14
+ const res = await this.client.chat.completions.create({
15
+ model: this.config.model,
16
+ temperature: input.modelOptions?.temperature,
17
+ top_p: input.modelOptions?.topP,
18
+ frequency_penalty: input.modelOptions?.frequencyPenalty,
19
+ presence_penalty: input.modelOptions?.presencePenalty,
20
+ messages: await contentsFromInputMessages(input.messages),
21
+ tools: toolsFromInputTools(input.tools),
22
+ tool_choice: input.toolChoice,
23
+ response_format: input.responseFormat?.type === "json_schema"
24
+ ? {
25
+ type: "json_schema",
26
+ json_schema: {
27
+ ...input.responseFormat.jsonSchema,
28
+ schema: jsonSchemaToOpenAIJsonSchema(input.responseFormat.jsonSchema.schema),
29
+ },
30
+ }
31
+ : undefined,
32
+ stream: true,
33
+ });
34
+ const toolCalls = [];
35
+ for await (const chunk of res) {
36
+ const choice = chunk.choices?.[0];
37
+ const calls = choice?.delta.tool_calls?.map((i) => ({
38
+ id: i.id || nanoid(),
39
+ type: "function",
40
+ function: {
41
+ name: i.function?.name,
42
+ arguments: i.function?.arguments,
43
+ },
44
+ }));
45
+ if (calls?.length) {
46
+ toolCalls.push(...calls);
47
+ }
48
+ yield {
49
+ $text: choice?.delta.content || undefined,
50
+ delta: { toolCalls },
51
+ };
52
+ }
53
+ }
54
+ }
55
+ async function contentsFromInputMessages(messages) {
56
+ return messages.map((i) => ({
57
+ role: i.role,
58
+ content: typeof i.content === "string"
59
+ ? i.content
60
+ : i.content
61
+ .map((c) => {
62
+ if (c.type === "text") {
63
+ return { type: "text", text: c.text };
64
+ }
65
+ if (c.type === "image_url") {
66
+ return {
67
+ type: "image_url",
68
+ image_url: { url: c.imageUrl.url },
69
+ };
70
+ }
71
+ })
72
+ .filter(isNonNullable),
73
+ tool_call_id: i.toolCallId,
74
+ }));
75
+ }
76
+ function toolsFromInputTools(tools) {
77
+ return tools?.length
78
+ ? tools.map((i) => ({
79
+ type: "function",
80
+ function: {
81
+ name: i.function.name,
82
+ description: i.function.description,
83
+ parameters: i.function.parameters,
84
+ },
85
+ }))
86
+ : undefined;
87
+ }
88
+ function jsonSchemaToOpenAIJsonSchema(schema) {
89
+ if (schema?.type === "object") {
90
+ const { required, properties } = schema;
91
+ return {
92
+ ...schema,
93
+ properties: Object.fromEntries(Object.entries(properties).map(([key, value]) => {
94
+ const valueSchema = jsonSchemaToOpenAIJsonSchema(value);
95
+ // NOTE: All fields must be required https://platform.openai.com/docs/guides/structured-outputs/all-fields-must-be-required
96
+ return [
97
+ key,
98
+ required?.includes(key)
99
+ ? valueSchema
100
+ : { anyOf: [valueSchema, { type: ["null"] }] },
101
+ ];
102
+ })),
103
+ required: Object.keys(properties),
104
+ };
105
+ }
106
+ if (schema?.type === "array") {
107
+ return {
108
+ ...schema,
109
+ items: jsonSchemaToOpenAIJsonSchema(schema.items),
110
+ };
111
+ }
112
+ return schema;
113
+ }
@@ -0,0 +1,55 @@
1
+ import { type DependencyContainer } from "tsyringe";
2
+ import type { constructor as Constructor } from "tsyringe/dist/typings/types";
3
+ import type { Context, ContextState } from "./context";
4
+ import type { FunctionRunner } from "./function-runner";
5
+ import type { LLMModel, LLMModelConfiguration } from "./llm-model";
6
+ import { Runnable, type RunnableDefinition } from "./runnable";
7
+ import { OrderedRecord } from "./utils/ordered-map";
8
+ import type { DeepPartial } from "./utils/partial";
9
+ export interface RuntimeConfiguration {
10
+ llmModel?: LLMModelConfiguration;
11
+ }
12
+ export interface RuntimeOptions<Agents extends {
13
+ [name: string]: Runnable;
14
+ }, State extends ContextState> {
15
+ id?: string;
16
+ name?: string;
17
+ config?: RuntimeConfiguration;
18
+ state?: State;
19
+ agents?: Agents;
20
+ llmModel?: LLMModel | Constructor<LLMModel>;
21
+ functionRunner?: FunctionRunner | Constructor<FunctionRunner>;
22
+ }
23
+ export declare class Runtime<Agents extends {
24
+ [name: string]: Runnable;
25
+ } = {}, State extends ContextState = ContextState> implements Context<State> {
26
+ constructor(options?: RuntimeOptions<Agents, State>);
27
+ protected inner: RuntimeInner<Agents, State>;
28
+ get options(): RuntimeOptions<Agents, State>;
29
+ get id(): string;
30
+ get name(): string | undefined;
31
+ config: RuntimeConfiguration;
32
+ state: State;
33
+ agents: Agents;
34
+ private container;
35
+ setup(config: DeepPartial<RuntimeConfiguration>): void;
36
+ register<R extends Array<RunnableDefinition | Runnable> = []>(...runnables: R): void;
37
+ private resolveSync;
38
+ resolve<T extends Runnable>(id: string | RunnableDefinition | T): Promise<T>;
39
+ resolveDependency<T>(token: string | symbol): T;
40
+ copy<State extends ContextState = ContextState>(options: Pick<RuntimeOptions<Agents, State>, "state" | "config">): Runtime<Agents, State>;
41
+ }
42
+ declare class RuntimeInner<Agents extends {
43
+ [name: string]: Runnable;
44
+ } = {}, State extends ContextState = ContextState> {
45
+ options: RuntimeOptions<Agents, State>;
46
+ constructor(options: RuntimeOptions<Agents, State>);
47
+ readonly id: string;
48
+ readonly name?: string;
49
+ config: RuntimeConfiguration;
50
+ state: State;
51
+ container: DependencyContainer;
52
+ runnableDefinitions: OrderedRecord<RunnableDefinition>;
53
+ registerDependency<T>(token: string | symbol, dependency: Constructor<T> | T): void;
54
+ }
55
+ export {};