@acontext/acontext 0.0.19 → 0.0.21

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.
@@ -2,15 +2,49 @@
2
2
  * Skill tools for agent operations.
3
3
  */
4
4
  import { AcontextClient } from '../client';
5
+ import { Skill } from '../types';
5
6
  import { AbstractBaseTool, BaseContext, BaseToolPool } from './base';
7
+ /**
8
+ * Context for skill tools with preloaded skill name mapping.
9
+ */
6
10
  export interface SkillContext extends BaseContext {
7
11
  client: AcontextClient;
12
+ skills: Map<string, Skill>;
13
+ }
14
+ /**
15
+ * Create a SkillContext by preloading skills from a list of skill IDs.
16
+ *
17
+ * @param client - The Acontext client instance.
18
+ * @param skillIds - List of skill UUIDs to preload.
19
+ * @returns SkillContext with preloaded skills mapped by name.
20
+ * @throws Error if duplicate skill names are found.
21
+ */
22
+ export declare function createSkillContext(client: AcontextClient, skillIds: string[]): Promise<SkillContext>;
23
+ /**
24
+ * Get a skill by name from the preloaded skills.
25
+ *
26
+ * @param ctx - The skill context.
27
+ * @param skillName - The name of the skill.
28
+ * @returns The Skill object.
29
+ * @throws Error if the skill is not found in the context.
30
+ */
31
+ export declare function getSkillFromContext(ctx: SkillContext, skillName: string): Skill;
32
+ /**
33
+ * Return list of available skill names in this context.
34
+ */
35
+ export declare function listSkillNamesFromContext(ctx: SkillContext): string[];
36
+ export declare class ListSkillsTool extends AbstractBaseTool {
37
+ readonly name = "list_skills";
38
+ readonly description = "List all available skills in the current context with their names and descriptions.";
39
+ readonly arguments: {};
40
+ readonly requiredArguments: string[];
41
+ execute(ctx: SkillContext, _llmArguments: Record<string, unknown>): Promise<string>;
8
42
  }
9
43
  export declare class GetSkillTool extends AbstractBaseTool {
10
44
  readonly name = "get_skill";
11
- readonly description = "Get a skill by its name. Return the skill information including the relative paths of the files and their mime type categories";
45
+ readonly description = "Get a skill by its name. Returns the skill information including the relative paths of the files and their mime type categories.";
12
46
  readonly arguments: {
13
- name: {
47
+ skill_name: {
14
48
  type: string;
15
49
  description: string;
16
50
  };
@@ -20,7 +54,7 @@ export declare class GetSkillTool extends AbstractBaseTool {
20
54
  }
21
55
  export declare class GetSkillFileTool extends AbstractBaseTool {
22
56
  readonly name = "get_skill_file";
23
- readonly description = "Get a file from a skill by name. The file_path should be a relative path within the skill (e.g., 'scripts/extract_text.json'). ";
57
+ readonly description: string;
24
58
  readonly arguments: {
25
59
  skill_name: {
26
60
  type: string;
@@ -39,6 +73,13 @@ export declare class GetSkillFileTool extends AbstractBaseTool {
39
73
  execute(ctx: SkillContext, llmArguments: Record<string, unknown>): Promise<string>;
40
74
  }
41
75
  export declare class SkillToolPool extends BaseToolPool {
42
- formatContext(client: AcontextClient): SkillContext;
76
+ /**
77
+ * Create a SkillContext by preloading skills from a list of skill IDs.
78
+ *
79
+ * @param client - The Acontext client instance.
80
+ * @param skillIds - List of skill UUIDs to preload.
81
+ * @returns Promise resolving to SkillContext with preloaded skills mapped by name.
82
+ */
83
+ formatContext(client: AcontextClient, skillIds: string[]): Promise<SkillContext>;
43
84
  }
44
85
  export declare const SKILL_TOOLS: SkillToolPool;
@@ -3,27 +3,95 @@
3
3
  * Skill tools for agent operations.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SKILL_TOOLS = exports.SkillToolPool = exports.GetSkillFileTool = exports.GetSkillTool = void 0;
6
+ exports.SKILL_TOOLS = exports.SkillToolPool = exports.GetSkillFileTool = exports.GetSkillTool = exports.ListSkillsTool = void 0;
7
+ exports.createSkillContext = createSkillContext;
8
+ exports.getSkillFromContext = getSkillFromContext;
9
+ exports.listSkillNamesFromContext = listSkillNamesFromContext;
7
10
  const base_1 = require("./base");
11
+ /**
12
+ * Create a SkillContext by preloading skills from a list of skill IDs.
13
+ *
14
+ * @param client - The Acontext client instance.
15
+ * @param skillIds - List of skill UUIDs to preload.
16
+ * @returns SkillContext with preloaded skills mapped by name.
17
+ * @throws Error if duplicate skill names are found.
18
+ */
19
+ async function createSkillContext(client, skillIds) {
20
+ const skills = new Map();
21
+ for (const skillId of skillIds) {
22
+ const skill = await client.skills.get(skillId);
23
+ if (skills.has(skill.name)) {
24
+ const existingSkill = skills.get(skill.name);
25
+ throw new Error(`Duplicate skill name '${skill.name}' found. ` +
26
+ `Existing ID: ${existingSkill.id}, New ID: ${skill.id}`);
27
+ }
28
+ skills.set(skill.name, skill);
29
+ }
30
+ return { client, skills };
31
+ }
32
+ /**
33
+ * Get a skill by name from the preloaded skills.
34
+ *
35
+ * @param ctx - The skill context.
36
+ * @param skillName - The name of the skill.
37
+ * @returns The Skill object.
38
+ * @throws Error if the skill is not found in the context.
39
+ */
40
+ function getSkillFromContext(ctx, skillName) {
41
+ const skill = ctx.skills.get(skillName);
42
+ if (!skill) {
43
+ const available = ctx.skills.size > 0 ? Array.from(ctx.skills.keys()).join(', ') : '[none]';
44
+ throw new Error(`Skill '${skillName}' not found in context. Available skills: ${available}`);
45
+ }
46
+ return skill;
47
+ }
48
+ /**
49
+ * Return list of available skill names in this context.
50
+ */
51
+ function listSkillNamesFromContext(ctx) {
52
+ return Array.from(ctx.skills.keys());
53
+ }
54
+ class ListSkillsTool extends base_1.AbstractBaseTool {
55
+ constructor() {
56
+ super(...arguments);
57
+ this.name = 'list_skills';
58
+ this.description = 'List all available skills in the current context with their names and descriptions.';
59
+ this.arguments = {};
60
+ this.requiredArguments = [];
61
+ }
62
+ async execute(ctx,
63
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
64
+ _llmArguments) {
65
+ if (ctx.skills.size === 0) {
66
+ return 'No skills available in the current context.';
67
+ }
68
+ const skillList = [];
69
+ for (const [skillName, skill] of ctx.skills.entries()) {
70
+ skillList.push(`- ${skillName}: ${skill.description}`);
71
+ }
72
+ return `Available skills (${ctx.skills.size}):\n${skillList.join('\n')}`;
73
+ }
74
+ }
75
+ exports.ListSkillsTool = ListSkillsTool;
8
76
  class GetSkillTool extends base_1.AbstractBaseTool {
9
77
  constructor() {
10
78
  super(...arguments);
11
79
  this.name = 'get_skill';
12
- this.description = 'Get a skill by its name. Return the skill information including the relative paths of the files and their mime type categories';
80
+ this.description = 'Get a skill by its name. Returns the skill information including the relative paths of the files and their mime type categories.';
13
81
  this.arguments = {
14
- name: {
82
+ skill_name: {
15
83
  type: 'string',
16
- description: 'The name of the skill (unique within project).',
84
+ description: 'The name of the skill.',
17
85
  },
18
86
  };
19
- this.requiredArguments = ['name'];
87
+ this.requiredArguments = ['skill_name'];
20
88
  }
21
89
  async execute(ctx, llmArguments) {
22
- const name = llmArguments.name;
23
- if (!name) {
24
- throw new Error('name is required');
90
+ const skillName = llmArguments.skill_name;
91
+ if (!skillName) {
92
+ throw new Error('skill_name is required');
25
93
  }
26
- const skill = await ctx.client.skills.getByName(name);
94
+ const skill = getSkillFromContext(ctx, skillName);
27
95
  const fileCount = skill.file_index.length;
28
96
  // Format all files with path and MIME type
29
97
  let fileList;
@@ -38,9 +106,7 @@ class GetSkillTool extends base_1.AbstractBaseTool {
38
106
  return (`Skill: ${skill.name} (ID: ${skill.id})\n` +
39
107
  `Description: ${skill.description}\n` +
40
108
  `Files: ${fileCount} file(s)\n` +
41
- `${fileList}\n` +
42
- `Created: ${skill.created_at}\n` +
43
- `Updated: ${skill.updated_at}`);
109
+ `${fileList}`);
44
110
  }
45
111
  }
46
112
  exports.GetSkillTool = GetSkillTool;
@@ -48,7 +114,8 @@ class GetSkillFileTool extends base_1.AbstractBaseTool {
48
114
  constructor() {
49
115
  super(...arguments);
50
116
  this.name = 'get_skill_file';
51
- this.description = "Get a file from a skill by name. The file_path should be a relative path within the skill (e.g., 'scripts/extract_text.json'). ";
117
+ this.description = "Get a file from a skill by name. The file_path should be a relative path within the skill (e.g., 'scripts/extract_text.json')." +
118
+ 'Tips: SKILL.md is the first file you should read to understand the full picture of this skill\'s content.';
52
119
  this.arguments = {
53
120
  skill_name: {
54
121
  type: 'string',
@@ -69,14 +136,15 @@ class GetSkillFileTool extends base_1.AbstractBaseTool {
69
136
  const skillName = llmArguments.skill_name;
70
137
  const filePath = llmArguments.file_path;
71
138
  const expire = llmArguments.expire;
72
- if (!filePath) {
73
- throw new Error('file_path is required');
74
- }
75
139
  if (!skillName) {
76
140
  throw new Error('skill_name is required');
77
141
  }
78
- const result = await ctx.client.skills.getFileByName({
79
- skillName,
142
+ if (!filePath) {
143
+ throw new Error('file_path is required');
144
+ }
145
+ const skill = getSkillFromContext(ctx, skillName);
146
+ const result = await ctx.client.skills.getFile({
147
+ skillId: skill.id,
80
148
  filePath,
81
149
  expire: expire || null,
82
150
  });
@@ -100,13 +168,19 @@ class GetSkillFileTool extends base_1.AbstractBaseTool {
100
168
  }
101
169
  exports.GetSkillFileTool = GetSkillFileTool;
102
170
  class SkillToolPool extends base_1.BaseToolPool {
103
- formatContext(client) {
104
- return {
105
- client,
106
- };
171
+ /**
172
+ * Create a SkillContext by preloading skills from a list of skill IDs.
173
+ *
174
+ * @param client - The Acontext client instance.
175
+ * @param skillIds - List of skill UUIDs to preload.
176
+ * @returns Promise resolving to SkillContext with preloaded skills mapped by name.
177
+ */
178
+ async formatContext(client, skillIds) {
179
+ return createSkillContext(client, skillIds);
107
180
  }
108
181
  }
109
182
  exports.SkillToolPool = SkillToolPool;
110
183
  exports.SKILL_TOOLS = new SkillToolPool();
184
+ exports.SKILL_TOOLS.addTool(new ListSkillsTool());
111
185
  exports.SKILL_TOOLS.addTool(new GetSkillTool());
112
186
  exports.SKILL_TOOLS.addTool(new GetSkillFileTool());
@@ -36,6 +36,17 @@ export declare class SessionsAPI {
36
36
  cursor?: string | null;
37
37
  timeDesc?: boolean | null;
38
38
  }): Promise<GetTasksOutput>;
39
+ /**
40
+ * Get a summary of all tasks in a session as a formatted string.
41
+ *
42
+ * @param sessionId - The UUID of the session.
43
+ * @param options - Options for retrieving the summary.
44
+ * @param options.limit - Maximum number of tasks to include in the summary.
45
+ * @returns A formatted string containing the session summary with all task information.
46
+ */
47
+ getSessionSummary(sessionId: string, options?: {
48
+ limit?: number | null;
49
+ }): Promise<string>;
39
50
  storeMessage(sessionId: string, blob: MessageBlob, options?: {
40
51
  format?: 'acontext' | 'openai' | 'anthropic' | 'gemini';
41
52
  fileField?: string | null;
@@ -54,6 +65,7 @@ export declare class SessionsAPI {
54
65
  * @param options.editStrategies - Optional list of edit strategies to apply before format conversion.
55
66
  * Examples:
56
67
  * - Remove tool results: [{ type: 'remove_tool_result', params: { keep_recent_n_tool_results: 3 } }]
68
+ * - Middle out: [{ type: 'middle_out', params: { token_reduce_to: 5000 } }]
57
69
  * - Token limit: [{ type: 'token_limit', params: { limit_tokens: 20000 } }]
58
70
  * @param options.pinEditingStrategiesAtMessage - Message ID to pin editing strategies at.
59
71
  * When provided, strategies are only applied to messages up to and including this message ID,
@@ -79,6 +79,47 @@ class SessionsAPI {
79
79
  });
80
80
  return types_1.GetTasksOutputSchema.parse(data);
81
81
  }
82
+ /**
83
+ * Get a summary of all tasks in a session as a formatted string.
84
+ *
85
+ * @param sessionId - The UUID of the session.
86
+ * @param options - Options for retrieving the summary.
87
+ * @param options.limit - Maximum number of tasks to include in the summary.
88
+ * @returns A formatted string containing the session summary with all task information.
89
+ */
90
+ async getSessionSummary(sessionId, options) {
91
+ const tasksOutput = await this.getTasks(sessionId, {
92
+ limit: options?.limit,
93
+ timeDesc: false,
94
+ });
95
+ const tasks = tasksOutput.items;
96
+ if (tasks.length === 0) {
97
+ return '';
98
+ }
99
+ const parts = [];
100
+ for (const task of tasks) {
101
+ const taskLines = [
102
+ `<task id="${task.order}" description="${task.data.task_description}">`
103
+ ];
104
+ if (task.data.progresses && task.data.progresses.length > 0) {
105
+ taskLines.push('<progress>');
106
+ task.data.progresses.forEach((p, i) => {
107
+ taskLines.push(`${i + 1}. ${p}`);
108
+ });
109
+ taskLines.push('</progress>');
110
+ }
111
+ if (task.data.user_preferences && task.data.user_preferences.length > 0) {
112
+ taskLines.push('<user_preference>');
113
+ task.data.user_preferences.forEach((pref, i) => {
114
+ taskLines.push(`${i + 1}. ${pref}`);
115
+ });
116
+ taskLines.push('</user_preference>');
117
+ }
118
+ taskLines.push('</task>');
119
+ parts.push(taskLines.join('\n'));
120
+ }
121
+ return parts.join('\n');
122
+ }
82
123
  async storeMessage(sessionId, blob, options) {
83
124
  const format = options?.format ?? 'openai';
84
125
  if (!['acontext', 'openai', 'anthropic', 'gemini'].includes(format)) {
@@ -137,6 +178,7 @@ class SessionsAPI {
137
178
  * @param options.editStrategies - Optional list of edit strategies to apply before format conversion.
138
179
  * Examples:
139
180
  * - Remove tool results: [{ type: 'remove_tool_result', params: { keep_recent_n_tool_results: 3 } }]
181
+ * - Middle out: [{ type: 'middle_out', params: { token_reduce_to: 5000 } }]
140
182
  * - Token limit: [{ type: 'token_limit', params: { limit_tokens: 20000 } }]
141
183
  * @param options.pinEditingStrategiesAtMessage - Message ID to pin editing strategies at.
142
184
  * When provided, strategies are only applied to messages up to and including this message ID,
@@ -23,16 +23,34 @@ export declare class SkillsAPI {
23
23
  * @returns ListSkillsOutput containing skills with name and description for the current page,
24
24
  * along with pagination information (next_cursor and has_more)
25
25
  */
26
- list_catalog(options?: {
26
+ listCatalog(options?: {
27
27
  user?: string | null;
28
28
  limit?: number | null;
29
29
  cursor?: string | null;
30
30
  timeDesc?: boolean | null;
31
31
  }): Promise<ListSkillsOutput>;
32
- getByName(name: string): Promise<Skill>;
32
+ /**
33
+ * Get a skill by its ID.
34
+ *
35
+ * @param skillId - The UUID of the skill
36
+ * @returns Skill containing the full skill information including file_index
37
+ */
38
+ get(skillId: string): Promise<Skill>;
33
39
  delete(skillId: string): Promise<void>;
34
- getFileByName(options: {
35
- skillName: string;
40
+ /**
41
+ * Get a file from a skill by skill ID.
42
+ *
43
+ * The backend automatically returns content for parseable text files, or a presigned URL
44
+ * for non-parseable files (binary, images, etc.).
45
+ *
46
+ * @param options - File retrieval options
47
+ * @param options.skillId - The UUID of the skill
48
+ * @param options.filePath - Relative path to the file within the skill (e.g., 'scripts/extract_text.json')
49
+ * @param options.expire - URL expiration time in seconds (defaults to 900 / 15 minutes)
50
+ * @returns GetSkillFileResp containing the file path, MIME type, and either content or URL
51
+ */
52
+ getFile(options: {
53
+ skillId: string;
36
54
  filePath: string;
37
55
  expire?: number | null;
38
56
  }): Promise<GetSkillFileResp>;
@@ -4,7 +4,6 @@
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.SkillsAPI = void 0;
7
- const zod_1 = require("zod");
8
7
  const uploads_1 = require("../uploads");
9
8
  const utils_1 = require("../utils");
10
9
  const types_1 = require("../types");
@@ -41,13 +40,7 @@ class SkillsAPI {
41
40
  * @returns ListSkillsOutput containing skills with name and description for the current page,
42
41
  * along with pagination information (next_cursor and has_more)
43
42
  */
44
- async list_catalog(options) {
45
- // Parse API response (contains full Skill objects)
46
- const apiResponseSchema = zod_1.z.object({
47
- items: zod_1.z.array(types_1.SkillSchema),
48
- next_cursor: zod_1.z.string().nullable().optional(),
49
- has_more: zod_1.z.boolean(),
50
- });
43
+ async listCatalog(options) {
51
44
  // Use 100 as default for catalog listing (only name and description, lightweight)
52
45
  const effectiveLimit = options?.limit ?? 100;
53
46
  const params = (0, utils_1.buildParams)({
@@ -59,29 +52,36 @@ class SkillsAPI {
59
52
  const data = await this.requester.request('GET', '/agent_skills', {
60
53
  params: Object.keys(params).length > 0 ? params : undefined,
61
54
  });
62
- const apiResponse = apiResponseSchema.parse(data);
63
- // Convert to catalog format (name and description only)
64
- return types_1.ListSkillsOutputSchema.parse({
65
- items: apiResponse.items.map((skill) => ({
66
- name: skill.name,
67
- description: skill.description,
68
- })),
69
- next_cursor: apiResponse.next_cursor ?? null,
70
- has_more: apiResponse.has_more,
71
- });
55
+ // Zod strips unknown keys, so ListSkillsOutputSchema extracts only name/description
56
+ return types_1.ListSkillsOutputSchema.parse(data);
72
57
  }
73
- async getByName(name) {
74
- const params = { name };
75
- const data = await this.requester.request('GET', '/agent_skills/by_name', {
76
- params,
77
- });
58
+ /**
59
+ * Get a skill by its ID.
60
+ *
61
+ * @param skillId - The UUID of the skill
62
+ * @returns Skill containing the full skill information including file_index
63
+ */
64
+ async get(skillId) {
65
+ const data = await this.requester.request('GET', `/agent_skills/${skillId}`);
78
66
  return types_1.SkillSchema.parse(data);
79
67
  }
80
68
  async delete(skillId) {
81
69
  await this.requester.request('DELETE', `/agent_skills/${skillId}`);
82
70
  }
83
- async getFileByName(options) {
84
- const endpoint = `/agent_skills/by_name/${options.skillName}/file`;
71
+ /**
72
+ * Get a file from a skill by skill ID.
73
+ *
74
+ * The backend automatically returns content for parseable text files, or a presigned URL
75
+ * for non-parseable files (binary, images, etc.).
76
+ *
77
+ * @param options - File retrieval options
78
+ * @param options.skillId - The UUID of the skill
79
+ * @param options.filePath - Relative path to the file within the skill (e.g., 'scripts/extract_text.json')
80
+ * @param options.expire - URL expiration time in seconds (defaults to 900 / 15 minutes)
81
+ * @returns GetSkillFileResp containing the file path, MIME type, and either content or URL
82
+ */
83
+ async getFile(options) {
84
+ const endpoint = `/agent_skills/${options.skillId}/file`;
85
85
  const params = {
86
86
  file_path: options.filePath,
87
87
  };
@@ -235,6 +235,25 @@ export declare const TokenLimitStrategySchema: z.ZodObject<{
235
235
  }, z.core.$strip>;
236
236
  }, z.core.$strip>;
237
237
  export type TokenLimitStrategy = z.infer<typeof TokenLimitStrategySchema>;
238
+ /**
239
+ * Parameters for the middle_out edit strategy.
240
+ */
241
+ export declare const MiddleOutParamsSchema: z.ZodObject<{
242
+ token_reduce_to: z.ZodNumber;
243
+ }, z.core.$strip>;
244
+ export type MiddleOutParams = z.infer<typeof MiddleOutParamsSchema>;
245
+ /**
246
+ * Edit strategy to reduce prompt size by removing middle messages.
247
+ *
248
+ * Example: { type: 'middle_out', params: { token_reduce_to: 5000 } }
249
+ */
250
+ export declare const MiddleOutStrategySchema: z.ZodObject<{
251
+ type: z.ZodLiteral<"middle_out">;
252
+ params: z.ZodObject<{
253
+ token_reduce_to: z.ZodNumber;
254
+ }, z.core.$strip>;
255
+ }, z.core.$strip>;
256
+ export type MiddleOutStrategy = z.infer<typeof MiddleOutStrategySchema>;
238
257
  /**
239
258
  * Union schema for all edit strategies.
240
259
  * When adding new strategies, extend this union: z.union([RemoveToolResultStrategySchema, OtherStrategySchema, ...])
@@ -257,5 +276,10 @@ export declare const EditStrategySchema: z.ZodUnion<readonly [z.ZodObject<{
257
276
  params: z.ZodObject<{
258
277
  limit_tokens: z.ZodNumber;
259
278
  }, z.core.$strip>;
279
+ }, z.core.$strip>, z.ZodObject<{
280
+ type: z.ZodLiteral<"middle_out">;
281
+ params: z.ZodObject<{
282
+ token_reduce_to: z.ZodNumber;
283
+ }, z.core.$strip>;
260
284
  }, z.core.$strip>]>;
261
285
  export type EditStrategy = z.infer<typeof EditStrategySchema>;
@@ -3,7 +3,7 @@
3
3
  * Type definitions for session, message, and task resources.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.EditStrategySchema = exports.TokenLimitStrategySchema = exports.TokenLimitParamsSchema = exports.RemoveToolResultStrategySchema = exports.RemoveToolCallParamsStrategySchema = exports.RemoveToolCallParamsParamsSchema = exports.RemoveToolResultParamsSchema = exports.MessageObservingStatusSchema = exports.TokenCountsSchema = exports.LearningStatusSchema = exports.GetTasksOutputSchema = exports.GetMessagesOutputSchema = exports.PublicURLSchema = exports.ListSessionsOutputSchema = exports.TaskSchema = exports.TaskDataSchema = exports.SessionSchema = exports.MessageSchema = exports.PartSchema = exports.AssetSchema = void 0;
6
+ exports.EditStrategySchema = exports.MiddleOutStrategySchema = exports.MiddleOutParamsSchema = exports.TokenLimitStrategySchema = exports.TokenLimitParamsSchema = exports.RemoveToolResultStrategySchema = exports.RemoveToolCallParamsStrategySchema = exports.RemoveToolCallParamsParamsSchema = exports.RemoveToolResultParamsSchema = exports.MessageObservingStatusSchema = exports.TokenCountsSchema = exports.LearningStatusSchema = exports.GetTasksOutputSchema = exports.GetMessagesOutputSchema = exports.PublicURLSchema = exports.ListSessionsOutputSchema = exports.TaskSchema = exports.TaskDataSchema = exports.SessionSchema = exports.MessageSchema = exports.PartSchema = exports.AssetSchema = void 0;
7
7
  const zod_1 = require("zod");
8
8
  exports.AssetSchema = zod_1.z.object({
9
9
  bucket: zod_1.z.string(),
@@ -190,6 +190,21 @@ exports.TokenLimitStrategySchema = zod_1.z.object({
190
190
  type: zod_1.z.literal('token_limit'),
191
191
  params: exports.TokenLimitParamsSchema,
192
192
  });
193
+ /**
194
+ * Parameters for the middle_out edit strategy.
195
+ */
196
+ exports.MiddleOutParamsSchema = zod_1.z.object({
197
+ token_reduce_to: zod_1.z.number(),
198
+ });
199
+ /**
200
+ * Edit strategy to reduce prompt size by removing middle messages.
201
+ *
202
+ * Example: { type: 'middle_out', params: { token_reduce_to: 5000 } }
203
+ */
204
+ exports.MiddleOutStrategySchema = zod_1.z.object({
205
+ type: zod_1.z.literal('middle_out'),
206
+ params: exports.MiddleOutParamsSchema,
207
+ });
193
208
  /**
194
209
  * Union schema for all edit strategies.
195
210
  * When adding new strategies, extend this union: z.union([RemoveToolResultStrategySchema, OtherStrategySchema, ...])
@@ -198,4 +213,5 @@ exports.EditStrategySchema = zod_1.z.union([
198
213
  exports.RemoveToolResultStrategySchema,
199
214
  exports.RemoveToolCallParamsStrategySchema,
200
215
  exports.TokenLimitStrategySchema,
216
+ exports.MiddleOutStrategySchema,
201
217
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acontext/acontext",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "TypeScript SDK for the Acontext API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,6 +9,7 @@
9
9
  "dev": "tsc --watch",
10
10
  "test": "jest",
11
11
  "lint": "eslint src",
12
+ "e2e": "tsx examples/basic-usage.ts",
12
13
  "prepublishOnly": "npm run build"
13
14
  },
14
15
  "keywords": [
@@ -35,6 +36,7 @@
35
36
  "eslint": "^9.39.1",
36
37
  "jest": "^30.2.0",
37
38
  "ts-jest": "^29.4.5",
39
+ "tsx": "^4.19.0",
38
40
  "typescript": "^5.9.3"
39
41
  },
40
42
  "peerDependencies": {