@aigne/core 1.72.0-beta.5 → 1.72.0-beta.7

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.
@@ -9,7 +9,7 @@ import type { Memory, MemoryAgent } from "../memory/memory.js";
9
9
  import type { MemoryRecorderInput } from "../memory/recorder.js";
10
10
  import type { MemoryRetrieverInput } from "../memory/retriever.js";
11
11
  import { type Nullish, type PromiseOrValue, type XOr } from "../utils/type-utils.js";
12
- import type { ChatModel } from "./chat-model.js";
12
+ import type { ChatModel, ChatModelInputMessage } from "./chat-model.js";
13
13
  import type { GuideRailAgent, GuideRailAgentOutput } from "./guide-rail-agent.js";
14
14
  import type { ImageModel } from "./image-model.js";
15
15
  import { type GetterSchema, type TransferAgentOutput } from "./types.js";
@@ -350,7 +350,20 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
350
350
  */
351
351
  private disableEvents?;
352
352
  historyConfig?: {
353
- disabled?: boolean;
353
+ /**
354
+ * Whether to enable history recording and injection
355
+ * @default false
356
+ */
357
+ enabled?: boolean;
358
+ /**
359
+ * Whether to record history entries, default to enabled when history is enabled
360
+ */
361
+ record?: boolean;
362
+ /**
363
+ * Whether to inject history entries into the context, default to enabled when history is enabled
364
+ */
365
+ inject?: boolean;
366
+ useOldMemory?: boolean;
354
367
  maxTokens?: number;
355
368
  maxItems?: number;
356
369
  };
@@ -455,7 +468,9 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
455
468
  * @param options Invocation options
456
469
  * @returns Final processed output
457
470
  */
458
- protected processAgentOutput(input: I, output: Exclude<AgentResponse<O>, AgentResponseStream<O>>, options: AgentInvokeOptions): Promise<O>;
471
+ protected processAgentOutput(input: I, output: Exclude<AgentResponse<O>, AgentResponseStream<O>>, { messages, ...options }: AgentInvokeOptions & {
472
+ messages?: ChatModelInputMessage[];
473
+ }): Promise<O>;
459
474
  /**
460
475
  * Process errors that occur during agent execution
461
476
  *
@@ -785,29 +800,29 @@ export interface AgentResponseProgress {
785
800
  error: Error;
786
801
  } | {
787
802
  event: "message";
788
- role: "user" | "agent";
789
- message: ({
790
- type: "text";
791
- content: string;
792
- } | {
793
- type: "thinking";
794
- thoughts: string;
795
- } | {
796
- type: "tool_use";
797
- toolUseId: string;
798
- name: string;
799
- input: unknown;
800
- } | {
801
- type: "tool_result";
802
- toolUseId: string;
803
- content: unknown;
804
- })[];
803
+ message: ChatModelInputMessage;
805
804
  }) & Omit<AgentEvent, "agent"> & {
806
805
  agent: {
807
806
  name: string;
808
807
  };
809
808
  };
810
809
  }
810
+ export type AgentResponseProgressMessageItem = {
811
+ type: "text";
812
+ content: string;
813
+ } | {
814
+ type: "thinking";
815
+ thoughts: string;
816
+ } | {
817
+ type: "tool_use";
818
+ toolUseId: string;
819
+ name: string;
820
+ input: unknown;
821
+ } | {
822
+ type: "tool_result";
823
+ toolUseId: string;
824
+ content: unknown;
825
+ };
811
826
  export declare function isAgentResponseProgress<T>(chunk: AgentResponseChunk<T>): chunk is AgentResponseProgress;
812
827
  /**
813
828
  * Creates a text delta for streaming responses
@@ -225,6 +225,7 @@ export type ChatModelInputMessageContent = string | UnionContent[];
225
225
  export type TextContent = {
226
226
  type: "text";
227
227
  text: string;
228
+ isThinking?: boolean;
228
229
  /**
229
230
  * Cache control marker (only supported by Claude)
230
231
  *
@@ -1,6 +1,6 @@
1
1
  import type { AFSOptions } from "@aigne/afs";
2
2
  import { type ZodType, z } from "zod";
3
- import type { AgentHooks, TaskRenderMode } from "../agents/agent.js";
3
+ import type { Agent, AgentHooks, TaskRenderMode } from "../agents/agent.js";
4
4
  import type { LoadOptions } from "./index.js";
5
5
  import { chatModelSchema, imageModelSchema } from "./schema.js";
6
6
  export interface HooksSchema {
@@ -65,6 +65,7 @@ export interface AgentSchema {
65
65
  context?: AFSContextSchema;
66
66
  });
67
67
  shareAFS?: boolean;
68
+ historyConfig?: Agent["historyConfig"];
68
69
  [key: string]: unknown;
69
70
  }
70
71
  export declare function parseAgentFile(path: string, data: any, options: LoadOptions): Promise<AgentSchema>;
@@ -1,5 +1,9 @@
1
+ import type { AFSListOptions } from "@aigne/afs";
1
2
  import type { Agent } from "../../../agents/agent.js";
2
- export declare function getHistories(agent: Agent): Promise<{
3
+ export declare function getHistories({ filter, agent, }: {
4
+ filter: AFSListOptions["filter"];
5
+ agent: Agent;
6
+ }): Promise<{
3
7
  role: "user" | "agent";
4
8
  content: unknown;
5
9
  }[]>;
@@ -1,14 +1,16 @@
1
1
  import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
- import { Agent, type AgentInvokeOptions, type Message } from "../agents/agent.js";
2
+ import { Agent, type Message } from "../agents/agent.js";
3
3
  import { type AIAgent } from "../agents/ai-agent.js";
4
- import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
4
+ import { type ChatModel, type ChatModelInput, type ChatModelInputMessage } from "../agents/chat-model.js";
5
5
  import { type FileUnionContent } from "../agents/model.js";
6
+ import type { Context } from "../aigne/context.js";
6
7
  import { ChatMessagesTemplate } from "./template.js";
7
8
  export interface PromptBuilderOptions {
8
9
  instructions?: string | ChatMessagesTemplate;
9
10
  workingDir?: string;
10
11
  }
11
- export interface PromptBuildOptions extends Partial<Pick<AgentInvokeOptions, "context">> {
12
+ export interface PromptBuildOptions {
13
+ context?: Context;
12
14
  agent?: AIAgent;
13
15
  input?: Message;
14
16
  model?: ChatModel;
@@ -37,10 +39,12 @@ export declare class PromptBuilder {
37
39
  }>;
38
40
  private getTemplateVariables;
39
41
  private buildMessages;
40
- getHistories(options: PromptBuildOptions): Promise<{
41
- role: "user" | "agent";
42
- content: unknown;
43
- }[]>;
42
+ protected deprecatedMemories(message: string | undefined, options: PromptBuildOptions): Promise<ChatModelInputMessage[]>;
43
+ getHistories({ agentId, userId, sessionId, ...options }: PromptBuildOptions & {
44
+ agentId?: string;
45
+ userId?: string;
46
+ sessionId?: string;
47
+ }): Promise<ChatModelInputMessage[]>;
44
48
  private refineMessages;
45
49
  private convertMemoriesToMessages;
46
50
  private buildResponseFormat;
@@ -9,7 +9,7 @@ import type { Memory, MemoryAgent } from "../memory/memory.js";
9
9
  import type { MemoryRecorderInput } from "../memory/recorder.js";
10
10
  import type { MemoryRetrieverInput } from "../memory/retriever.js";
11
11
  import { type Nullish, type PromiseOrValue, type XOr } from "../utils/type-utils.js";
12
- import type { ChatModel } from "./chat-model.js";
12
+ import type { ChatModel, ChatModelInputMessage } from "./chat-model.js";
13
13
  import type { GuideRailAgent, GuideRailAgentOutput } from "./guide-rail-agent.js";
14
14
  import type { ImageModel } from "./image-model.js";
15
15
  import { type GetterSchema, type TransferAgentOutput } from "./types.js";
@@ -350,7 +350,20 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
350
350
  */
351
351
  private disableEvents?;
352
352
  historyConfig?: {
353
- disabled?: boolean;
353
+ /**
354
+ * Whether to enable history recording and injection
355
+ * @default false
356
+ */
357
+ enabled?: boolean;
358
+ /**
359
+ * Whether to record history entries, default to enabled when history is enabled
360
+ */
361
+ record?: boolean;
362
+ /**
363
+ * Whether to inject history entries into the context, default to enabled when history is enabled
364
+ */
365
+ inject?: boolean;
366
+ useOldMemory?: boolean;
354
367
  maxTokens?: number;
355
368
  maxItems?: number;
356
369
  };
@@ -455,7 +468,9 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
455
468
  * @param options Invocation options
456
469
  * @returns Final processed output
457
470
  */
458
- protected processAgentOutput(input: I, output: Exclude<AgentResponse<O>, AgentResponseStream<O>>, options: AgentInvokeOptions): Promise<O>;
471
+ protected processAgentOutput(input: I, output: Exclude<AgentResponse<O>, AgentResponseStream<O>>, { messages, ...options }: AgentInvokeOptions & {
472
+ messages?: ChatModelInputMessage[];
473
+ }): Promise<O>;
459
474
  /**
460
475
  * Process errors that occur during agent execution
461
476
  *
@@ -785,29 +800,29 @@ export interface AgentResponseProgress {
785
800
  error: Error;
786
801
  } | {
787
802
  event: "message";
788
- role: "user" | "agent";
789
- message: ({
790
- type: "text";
791
- content: string;
792
- } | {
793
- type: "thinking";
794
- thoughts: string;
795
- } | {
796
- type: "tool_use";
797
- toolUseId: string;
798
- name: string;
799
- input: unknown;
800
- } | {
801
- type: "tool_result";
802
- toolUseId: string;
803
- content: unknown;
804
- })[];
803
+ message: ChatModelInputMessage;
805
804
  }) & Omit<AgentEvent, "agent"> & {
806
805
  agent: {
807
806
  name: string;
808
807
  };
809
808
  };
810
809
  }
810
+ export type AgentResponseProgressMessageItem = {
811
+ type: "text";
812
+ content: string;
813
+ } | {
814
+ type: "thinking";
815
+ thoughts: string;
816
+ } | {
817
+ type: "tool_use";
818
+ toolUseId: string;
819
+ name: string;
820
+ input: unknown;
821
+ } | {
822
+ type: "tool_result";
823
+ toolUseId: string;
824
+ content: unknown;
825
+ };
811
826
  export declare function isAgentResponseProgress<T>(chunk: AgentResponseChunk<T>): chunk is AgentResponseProgress;
812
827
  /**
813
828
  * Creates a text delta for streaming responses
@@ -415,11 +415,15 @@ export class Agent {
415
415
  : isAsyncGenerator(response)
416
416
  ? asyncGeneratorToReadableStream(response)
417
417
  : objectToAgentResponseStream(response);
418
+ const messages = [];
418
419
  for await (const chunk of stream) {
419
420
  mergeAgentResponseChunk(output, chunk);
420
421
  yield chunk;
422
+ if (isAgentResponseProgress(chunk) && chunk.progress.event === "message") {
423
+ messages.push(chunk.progress.message);
424
+ }
421
425
  }
422
- let result = await this.processAgentOutput(input, output, options);
426
+ let result = await this.processAgentOutput(input, output, { ...options, messages });
423
427
  if (attempt > 0) {
424
428
  result = { ...result, $meta: { ...result.$meta, retries: attempt } };
425
429
  }
@@ -516,7 +520,7 @@ export class Agent {
516
520
  * @param options Invocation options
517
521
  * @returns Final processed output
518
522
  */
519
- async processAgentOutput(input, output, options) {
523
+ async processAgentOutput(input, output, { messages, ...options }) {
520
524
  const { context } = options;
521
525
  if (!isRecord(output)) {
522
526
  throw new Error(`expect to return a record type such as {result: ...}, but got (${typeof output}): ${output}`);
@@ -528,8 +532,17 @@ export class Agent {
528
532
  const o = await this.callHooks(["onSuccess", "onEnd"], { input, output: finalOutput }, options);
529
533
  if (o?.output)
530
534
  finalOutput = o.output;
531
- if (this.historyConfig?.disabled !== true)
532
- this.afs?.emit("agentSucceed", { input, output: finalOutput });
535
+ if (this.historyConfig?.record === true ||
536
+ (this.historyConfig?.record !== false && this.historyConfig?.enabled)) {
537
+ this.afs?.emit("agentSucceed", {
538
+ agentId: this.name,
539
+ userId: context.userContext.userId,
540
+ sessionId: context.userContext.sessionId,
541
+ input,
542
+ output: finalOutput,
543
+ messages,
544
+ });
545
+ }
533
546
  if (!this.disableEvents)
534
547
  context.emit("agentSucceed", { agent: this, output: finalOutput });
535
548
  return finalOutput;
@@ -313,8 +313,10 @@ export class AIAgent extends Agent {
313
313
  yield {
314
314
  progress: {
315
315
  event: "message",
316
- role: "user",
317
- message: [{ type: "text", content: inputMessage }],
316
+ message: {
317
+ role: "user",
318
+ content: [{ type: "text", text: inputMessage }],
319
+ },
318
320
  },
319
321
  };
320
322
  }
@@ -343,15 +345,22 @@ export class AIAgent extends Agent {
343
345
  }
344
346
  }
345
347
  const { toolCalls, json, text, thoughts, files } = modelOutput;
346
- if (text) {
347
- yield {
348
- progress: { event: "message", role: "agent", message: [{ type: "text", content: text }] },
349
- };
350
- }
351
- if (thoughts) {
352
- yield {
353
- progress: { event: "message", role: "agent", message: [{ type: "thinking", thoughts }] },
354
- };
348
+ if (text || thoughts) {
349
+ const content = [];
350
+ if (thoughts) {
351
+ content.push({ type: "text", text: thoughts, isThinking: true });
352
+ }
353
+ if (text) {
354
+ content.push({ type: "text", text });
355
+ }
356
+ if (content.length) {
357
+ yield {
358
+ progress: {
359
+ event: "message",
360
+ message: { role: "agent", content },
361
+ },
362
+ };
363
+ }
355
364
  }
356
365
  if (toolCalls?.length) {
357
366
  if (this.keepTextInToolUses !== true) {
@@ -383,25 +392,14 @@ export class AIAgent extends Agent {
383
392
  queue.killAndDrain();
384
393
  }
385
394
  }, this.toolCallsConcurrency || 1);
395
+ yield {
396
+ progress: { event: "message", message: { role: "agent", toolCalls } },
397
+ };
386
398
  // Execute tools
387
399
  for (const call of toolCalls) {
388
400
  const tool = toolsMap.get(call.function.name);
389
401
  if (!tool)
390
402
  throw new Error(`Tool not found: ${call.function.name}`);
391
- yield {
392
- progress: {
393
- event: "message",
394
- role: "agent",
395
- message: [
396
- {
397
- type: "tool_use",
398
- name: call.function.name,
399
- input: call.function.arguments,
400
- toolUseId: call.id,
401
- },
402
- ],
403
- },
404
- };
405
403
  queue.push({ tool, call });
406
404
  }
407
405
  await queue.drained();
@@ -413,14 +411,11 @@ export class AIAgent extends Agent {
413
411
  yield {
414
412
  progress: {
415
413
  event: "message",
416
- role: "agent",
417
- message: [
418
- {
419
- type: "tool_result",
420
- toolUseId: call.id,
421
- content: output,
422
- },
423
- ],
414
+ message: {
415
+ role: "tool",
416
+ toolCallId: call.id,
417
+ content: JSON.stringify(output),
418
+ },
424
419
  },
425
420
  };
426
421
  }
@@ -444,11 +439,6 @@ export class AIAgent extends Agent {
444
439
  if (!isEmpty(result)) {
445
440
  yield { delta: { json: result } };
446
441
  }
447
- if (text) {
448
- yield {
449
- progress: { event: "message", role: "agent", message: [{ type: "text", content: text }] },
450
- };
451
- }
452
442
  return;
453
443
  }
454
444
  }
@@ -225,6 +225,7 @@ export type ChatModelInputMessageContent = string | UnionContent[];
225
225
  export type TextContent = {
226
226
  type: "text";
227
227
  text: string;
228
+ isThinking?: boolean;
228
229
  /**
229
230
  * Cache control marker (only supported by Claude)
230
231
  *
@@ -340,15 +340,29 @@ const modelOptionsSchemaProperties = {
340
340
  z.literal("medium"),
341
341
  z.literal("high"),
342
342
  ]),
343
+ cacheConfig: z.object({
344
+ enabled: optionalize(z.boolean().default(true)),
345
+ ttl: optionalize(z.union([z.literal("5m"), z.literal("1h"), z.number()]).default("5m")),
346
+ strategy: optionalize(z.union([z.literal("auto"), z.literal("manual")]).default("auto")),
347
+ autoBreakpoints: optionalize(z.object({
348
+ tools: optionalize(z.boolean().default(true)),
349
+ system: optionalize(z.boolean().default(true)),
350
+ lastMessage: optionalize(z.boolean().default(false)),
351
+ })),
352
+ }),
343
353
  };
344
- const modelOptionsSchema = z.object(Object.fromEntries(Object.entries(modelOptionsSchemaProperties).map(([key, schema]) => [
354
+ const modelOptionsSchema = z
355
+ .object(Object.fromEntries(Object.entries(modelOptionsSchemaProperties).map(([key, schema]) => [
345
356
  key,
346
357
  optionalize(schema),
347
- ])));
348
- const modelOptionsWithGetterSchema = z.object(Object.fromEntries(Object.entries(modelOptionsSchemaProperties).map(([key, schema]) => [
358
+ ])))
359
+ .passthrough();
360
+ const modelOptionsWithGetterSchema = z
361
+ .object(Object.fromEntries(Object.entries(modelOptionsSchemaProperties).map(([key, schema]) => [
349
362
  key,
350
363
  optionalize(getterSchema(schema)),
351
- ])));
364
+ ])))
365
+ .passthrough();
352
366
  const chatModelOptionsSchema = agentOptionsSchema.extend({
353
367
  model: optionalize(z.string()),
354
368
  modelOptions: optionalize(modelOptionsWithGetterSchema),
@@ -1,6 +1,6 @@
1
1
  import type { AFSOptions } from "@aigne/afs";
2
2
  import { type ZodType, z } from "zod";
3
- import type { AgentHooks, TaskRenderMode } from "../agents/agent.js";
3
+ import type { Agent, AgentHooks, TaskRenderMode } from "../agents/agent.js";
4
4
  import type { LoadOptions } from "./index.js";
5
5
  import { chatModelSchema, imageModelSchema } from "./schema.js";
6
6
  export interface HooksSchema {
@@ -65,6 +65,7 @@ export interface AgentSchema {
65
65
  context?: AFSContextSchema;
66
66
  });
67
67
  shareAFS?: boolean;
68
+ historyConfig?: Agent["historyConfig"];
68
69
  [key: string]: unknown;
69
70
  }
70
71
  export declare function parseAgentFile(path: string, data: any, options: LoadOptions): Promise<AgentSchema>;
@@ -95,6 +95,14 @@ export const getAgentSchema = ({ filepath }) => {
95
95
  })),
96
96
  ])),
97
97
  shareAFS: optionalize(z.boolean()),
98
+ historyConfig: camelizeSchema(optionalize(z.object({
99
+ enabled: optionalize(z.boolean()),
100
+ record: optionalize(z.boolean()),
101
+ inject: optionalize(z.boolean()),
102
+ use_old_memory: optionalize(z.boolean()),
103
+ maxTokens: optionalize(z.number().int().positive()),
104
+ maxItems: optionalize(z.number().int().positive()),
105
+ }))),
98
106
  });
99
107
  return camelizeSchema(baseAgentSchema.passthrough());
100
108
  });
@@ -1,5 +1,9 @@
1
+ import type { AFSListOptions } from "@aigne/afs";
1
2
  import type { Agent } from "../../../agents/agent.js";
2
- export declare function getHistories(agent: Agent): Promise<{
3
+ export declare function getHistories({ filter, agent, }: {
4
+ filter: AFSListOptions["filter"];
5
+ agent: Agent;
6
+ }): Promise<{
3
7
  role: "user" | "agent";
4
8
  content: unknown;
5
9
  }[]>;
@@ -1,6 +1,6 @@
1
1
  import { AFSHistory } from "@aigne/afs-history";
2
2
  import { isNonNullable } from "../../../utils/type-utils.js";
3
- export async function getHistories(agent) {
3
+ export async function getHistories({ filter, agent, }) {
4
4
  const afs = agent?.afs;
5
5
  if (!afs)
6
6
  return [];
@@ -8,6 +8,7 @@ export async function getHistories(agent) {
8
8
  if (!historyModule)
9
9
  return [];
10
10
  const history = (await afs.list(historyModule.path, {
11
+ filter,
11
12
  limit: agent.historyConfig?.maxItems || 10,
12
13
  orderBy: [["createdAt", "desc"]],
13
14
  })).data;
@@ -17,7 +17,14 @@ export function createAFSContext(agent, context) {
17
17
  get histories() {
18
18
  if (!agent)
19
19
  return Promise.resolve([]);
20
- return getHistories(agent);
20
+ return getHistories({
21
+ agent,
22
+ filter: {
23
+ agentId: agent.name,
24
+ userId: context?.userContext.userId,
25
+ sessionId: context?.userContext.sessionId,
26
+ },
27
+ });
21
28
  },
22
29
  get skills() {
23
30
  const afs = agent?.afs;
@@ -1,14 +1,16 @@
1
1
  import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
- import { Agent, type AgentInvokeOptions, type Message } from "../agents/agent.js";
2
+ import { Agent, type Message } from "../agents/agent.js";
3
3
  import { type AIAgent } from "../agents/ai-agent.js";
4
- import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
4
+ import { type ChatModel, type ChatModelInput, type ChatModelInputMessage } from "../agents/chat-model.js";
5
5
  import { type FileUnionContent } from "../agents/model.js";
6
+ import type { Context } from "../aigne/context.js";
6
7
  import { ChatMessagesTemplate } from "./template.js";
7
8
  export interface PromptBuilderOptions {
8
9
  instructions?: string | ChatMessagesTemplate;
9
10
  workingDir?: string;
10
11
  }
11
- export interface PromptBuildOptions extends Partial<Pick<AgentInvokeOptions, "context">> {
12
+ export interface PromptBuildOptions {
13
+ context?: Context;
12
14
  agent?: AIAgent;
13
15
  input?: Message;
14
16
  model?: ChatModel;
@@ -37,10 +39,12 @@ export declare class PromptBuilder {
37
39
  }>;
38
40
  private getTemplateVariables;
39
41
  private buildMessages;
40
- getHistories(options: PromptBuildOptions): Promise<{
41
- role: "user" | "agent";
42
- content: unknown;
43
- }[]>;
42
+ protected deprecatedMemories(message: string | undefined, options: PromptBuildOptions): Promise<ChatModelInputMessage[]>;
43
+ getHistories({ agentId, userId, sessionId, ...options }: PromptBuildOptions & {
44
+ agentId?: string;
45
+ userId?: string;
46
+ sessionId?: string;
47
+ }): Promise<ChatModelInputMessage[]>;
44
48
  private refineMessages;
45
49
  private convertMemoriesToMessages;
46
50
  private buildResponseFormat;