fourmis-agents-sdk 0.3.1 → 0.4.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 (98) hide show
  1. package/dist/agent-loop.d.ts +21 -3
  2. package/dist/agent-loop.d.ts.map +1 -1
  3. package/dist/agent-loop.js +294 -90
  4. package/dist/agents/index.js +2798 -1857
  5. package/dist/agents/task-manager.js +15 -0
  6. package/dist/agents/tools.d.ts.map +1 -1
  7. package/dist/agents/tools.js +2798 -1857
  8. package/dist/agents/types.d.ts +4 -0
  9. package/dist/agents/types.d.ts.map +1 -1
  10. package/dist/api.d.ts +8 -5
  11. package/dist/api.d.ts.map +1 -1
  12. package/dist/api.js +2140 -923
  13. package/dist/auth/gemini-oauth.js +15 -0
  14. package/dist/auth/login-openai.js +15 -0
  15. package/dist/auth/openai-oauth.js +15 -0
  16. package/dist/hooks.d.ts +19 -1
  17. package/dist/hooks.d.ts.map +1 -1
  18. package/dist/hooks.js +42 -2
  19. package/dist/index.d.ts +8 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +2148 -924
  22. package/dist/mcp/client.d.ts +7 -0
  23. package/dist/mcp/client.d.ts.map +1 -1
  24. package/dist/mcp/client.js +146 -12
  25. package/dist/mcp/index.js +146 -12
  26. package/dist/mcp/server.js +15 -0
  27. package/dist/mcp/types.d.ts +19 -1
  28. package/dist/mcp/types.d.ts.map +1 -1
  29. package/dist/memory/index.js +15 -0
  30. package/dist/memory/memory-handler.js +15 -0
  31. package/dist/permissions.d.ts.map +1 -1
  32. package/dist/permissions.js +22 -3
  33. package/dist/providers/anthropic.d.ts.map +1 -1
  34. package/dist/providers/anthropic.js +56 -2
  35. package/dist/providers/gemini.js +15 -0
  36. package/dist/providers/openai.js +15 -0
  37. package/dist/providers/registry.js +56 -2
  38. package/dist/providers/types.d.ts +4 -1
  39. package/dist/providers/types.d.ts.map +1 -1
  40. package/dist/query.d.ts +21 -2
  41. package/dist/query.d.ts.map +1 -1
  42. package/dist/query.js +84 -1
  43. package/dist/settings.js +15 -0
  44. package/dist/skills/frontmatter.js +15 -0
  45. package/dist/skills/index.js +38 -1
  46. package/dist/skills/skills.d.ts +16 -0
  47. package/dist/skills/skills.d.ts.map +1 -1
  48. package/dist/skills/skills.js +38 -1
  49. package/dist/tools/ask-user-question.d.ts +7 -0
  50. package/dist/tools/ask-user-question.d.ts.map +1 -0
  51. package/dist/tools/ask-user-question.js +63 -0
  52. package/dist/tools/bash.d.ts.map +1 -1
  53. package/dist/tools/bash.js +62 -2
  54. package/dist/tools/config.d.ts +7 -0
  55. package/dist/tools/config.d.ts.map +1 -0
  56. package/dist/tools/config.js +129 -0
  57. package/dist/tools/edit.js +15 -0
  58. package/dist/tools/exit-plan-mode.d.ts +7 -0
  59. package/dist/tools/exit-plan-mode.d.ts.map +1 -0
  60. package/dist/tools/exit-plan-mode.js +49 -0
  61. package/dist/tools/glob.js +15 -0
  62. package/dist/tools/grep.js +15 -0
  63. package/dist/tools/index.d.ts +7 -0
  64. package/dist/tools/index.d.ts.map +1 -1
  65. package/dist/tools/index.js +521 -9
  66. package/dist/tools/mcp-resources.js +15 -0
  67. package/dist/tools/notebook-edit.d.ts +7 -0
  68. package/dist/tools/notebook-edit.d.ts.map +1 -0
  69. package/dist/tools/notebook-edit.js +98 -0
  70. package/dist/tools/presets.d.ts +2 -1
  71. package/dist/tools/presets.d.ts.map +1 -1
  72. package/dist/tools/presets.js +37 -4
  73. package/dist/tools/read.d.ts.map +1 -1
  74. package/dist/tools/read.js +27 -1
  75. package/dist/tools/registry.d.ts +2 -0
  76. package/dist/tools/registry.d.ts.map +1 -1
  77. package/dist/tools/registry.js +25 -0
  78. package/dist/tools/todo-write.d.ts +7 -0
  79. package/dist/tools/todo-write.d.ts.map +1 -0
  80. package/dist/tools/todo-write.js +84 -0
  81. package/dist/tools/web-fetch.d.ts +6 -0
  82. package/dist/tools/web-fetch.d.ts.map +1 -0
  83. package/dist/tools/web-fetch.js +100 -0
  84. package/dist/tools/web-search.d.ts +7 -0
  85. package/dist/tools/web-search.d.ts.map +1 -0
  86. package/dist/tools/web-search.js +93 -0
  87. package/dist/tools/write.js +15 -0
  88. package/dist/types.d.ts +344 -42
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/types.js +15 -0
  91. package/dist/utils/cost.js +15 -0
  92. package/dist/utils/session-store.d.ts +1 -1
  93. package/dist/utils/session-store.d.ts.map +1 -1
  94. package/dist/utils/session-store.js +64 -2
  95. package/dist/utils/system-prompt.d.ts +2 -0
  96. package/dist/utils/system-prompt.d.ts.map +1 -1
  97. package/dist/utils/system-prompt.js +48 -4
  98. package/package.json +3 -2
@@ -1,5 +1,20 @@
1
1
  // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
2
4
  var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
3
18
  var __export = (target, all) => {
4
19
  for (var name in all)
5
20
  __defProp(target, name, {
@@ -37,6 +52,13 @@ function mergeUsage(a, b) {
37
52
  import { readFileSync, appendFileSync, mkdirSync, readdirSync, statSync } from "fs";
38
53
  import { join } from "path";
39
54
  import { homedir } from "os";
55
+ function safeStringify(value) {
56
+ try {
57
+ return JSON.stringify(value);
58
+ } catch {
59
+ return String(value);
60
+ }
61
+ }
40
62
  function sanitizeCwd(cwd) {
41
63
  return cwd.replace(/[/.]/g, "-");
42
64
  }
@@ -100,7 +122,7 @@ function findLatestSession(cwd) {
100
122
  return null;
101
123
  }
102
124
  }
103
- function loadSessionMessages(cwd, sessionId) {
125
+ function loadSessionMessages(cwd, sessionId, resumeSessionAt) {
104
126
  const dir = sessionsDir(cwd);
105
127
  const filePath = join(dir, `${sessionId}.jsonl`);
106
128
  let lines;
@@ -111,7 +133,10 @@ function loadSessionMessages(cwd, sessionId) {
111
133
  return [];
112
134
  }
113
135
  const messages = [];
136
+ let reachedResumePoint = false;
114
137
  for (const line of lines) {
138
+ if (resumeSessionAt && reachedResumePoint)
139
+ break;
115
140
  try {
116
141
  const entry = JSON.parse(line);
117
142
  if (entry.type !== "user" && entry.type !== "assistant")
@@ -126,11 +151,48 @@ function loadSessionMessages(cwd, sessionId) {
126
151
  if (typeof message.content === "string") {
127
152
  content = message.content;
128
153
  } else if (Array.isArray(message.content)) {
129
- content = message.content.filter((c) => c.type === "text" || c.type === "tool_use" || c.type === "tool_result").map((c) => c);
154
+ const normalizedBlocks = [];
155
+ for (const c of message.content) {
156
+ if (!c || typeof c !== "object")
157
+ continue;
158
+ const block = c;
159
+ if (typeof block.type !== "string")
160
+ continue;
161
+ if (block.type === "text" && typeof block.text === "string") {
162
+ normalizedBlocks.push({ type: "text", text: block.text });
163
+ continue;
164
+ }
165
+ if (block.type === "tool_use" && typeof block.id === "string" && typeof block.name === "string") {
166
+ normalizedBlocks.push({
167
+ type: "tool_use",
168
+ id: block.id,
169
+ name: block.name,
170
+ input: block.input ?? {}
171
+ });
172
+ continue;
173
+ }
174
+ if (block.type === "tool_result" && typeof block.tool_use_id === "string") {
175
+ normalizedBlocks.push({
176
+ type: "tool_result",
177
+ tool_use_id: block.tool_use_id,
178
+ content: typeof block.content === "string" ? block.content : safeStringify(block.content),
179
+ is_error: typeof block.is_error === "boolean" ? block.is_error : undefined
180
+ });
181
+ continue;
182
+ }
183
+ normalizedBlocks.push({
184
+ type: "text",
185
+ text: `[session:${block.type}] ${safeStringify(block)}`
186
+ });
187
+ }
188
+ content = normalizedBlocks;
130
189
  } else {
131
190
  continue;
132
191
  }
133
192
  messages.push({ role, content });
193
+ if (resumeSessionAt && entry.uuid === resumeSessionAt) {
194
+ reachedResumePoint = true;
195
+ }
134
196
  } catch {}
135
197
  }
136
198
  return messages;
@@ -5,6 +5,8 @@ import type { Skill } from "../skills/index.js";
5
5
  export type SystemPromptContext = {
6
6
  tools: string[];
7
7
  cwd?: string;
8
+ additionalDirectories?: string[];
9
+ loadProjectInstructions?: boolean;
8
10
  permissionMode?: string;
9
11
  customPrompt?: string;
10
12
  skills?: Skill[];
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/utils/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AA6DhD,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAsCtE"}
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/utils/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AA6DhD,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA8CtE"}
@@ -1,5 +1,20 @@
1
1
  // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
2
4
  var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
3
18
  var __export = (target, all) => {
4
19
  for (var name in all)
5
20
  __defProp(target, name, {
@@ -52,6 +67,7 @@ import { homedir } from "os";
52
67
  import { basename, dirname, isAbsolute, join, resolve } from "path";
53
68
  var MAX_NAME_LENGTH = 64;
54
69
  var MAX_DESCRIPTION_LENGTH = 1024;
70
+ var MAX_COMPATIBILITY_LENGTH = 500;
55
71
  var CONFIG_DIR_NAME = ".claude";
56
72
  function shouldIgnore(name) {
57
73
  return name.startsWith(".") || name === "node_modules";
@@ -84,6 +100,14 @@ function validateDescription(description) {
84
100
  }
85
101
  return errors;
86
102
  }
103
+ function validateCompatibility(compatibility) {
104
+ if (!compatibility)
105
+ return [];
106
+ if (compatibility.length > MAX_COMPATIBILITY_LENGTH) {
107
+ return [`compatibility exceeds ${MAX_COMPATIBILITY_LENGTH} characters (${compatibility.length})`];
108
+ }
109
+ return [];
110
+ }
87
111
  function loadSkillsFromDir(options) {
88
112
  return loadSkillsFromDirInternal(options.dir, options.source, true);
89
113
  }
@@ -148,9 +172,15 @@ function loadSkillFromFile(filePath, source) {
148
172
  for (const error of nameErrors) {
149
173
  diagnostics.push({ type: "warning", message: error, path: filePath });
150
174
  }
175
+ const compatErrors = validateCompatibility(frontmatter.compatibility);
176
+ for (const error of compatErrors) {
177
+ diagnostics.push({ type: "warning", message: error, path: filePath });
178
+ }
151
179
  if (!frontmatter.description || frontmatter.description.trim() === "") {
152
180
  return { skill: null, diagnostics };
153
181
  }
182
+ const allowedToolsRaw = frontmatter["allowed-tools"];
183
+ const allowedTools = allowedToolsRaw ? allowedToolsRaw.split(/\s+/).filter(Boolean) : undefined;
154
184
  return {
155
185
  skill: {
156
186
  name,
@@ -158,7 +188,11 @@ function loadSkillFromFile(filePath, source) {
158
188
  filePath,
159
189
  baseDir: skillDir,
160
190
  source,
161
- disableModelInvocation: frontmatter["disable-model-invocation"] === true
191
+ disableModelInvocation: frontmatter["disable-model-invocation"] === true,
192
+ license: frontmatter.license,
193
+ compatibility: frontmatter.compatibility,
194
+ metadata: frontmatter.metadata,
195
+ allowedTools
162
196
  },
163
197
  diagnostics
164
198
  };
@@ -274,6 +308,9 @@ function formatSkillsForPrompt(skills) {
274
308
  lines.push(` <name>${escapeXml(skill.name)}</name>`);
275
309
  lines.push(` <description>${escapeXml(skill.description)}</description>`);
276
310
  lines.push(` <location>${escapeXml(skill.filePath)}</location>`);
311
+ if (skill.allowedTools?.length) {
312
+ lines.push(` <allowed-tools>${escapeXml(skill.allowedTools.join(" "))}</allowed-tools>`);
313
+ }
277
314
  lines.push(" </skill>");
278
315
  }
279
316
  lines.push("</available_skills>");
@@ -346,11 +383,18 @@ function buildSystemPrompt(context) {
346
383
  sections.push(`# Environment
347
384
 
348
385
  Working directory: ${context.cwd}`);
349
- const instructions = readProjectInstructions(context.cwd);
350
- if (instructions) {
351
- sections.push(`# Project Instructions
386
+ if (context.additionalDirectories && context.additionalDirectories.length > 0) {
387
+ sections.push(`Additional allowed directories:
388
+ ${context.additionalDirectories.map((d) => `- ${d}`).join(`
389
+ `)}`);
390
+ }
391
+ if (context.loadProjectInstructions) {
392
+ const instructions = readProjectInstructions(context.cwd);
393
+ if (instructions) {
394
+ sections.push(`# Project Instructions
352
395
 
353
396
  ${instructions}`);
397
+ }
354
398
  }
355
399
  }
356
400
  if (context.skills && context.skills.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fourmis-agents-sdk",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Multi-provider AI agent SDK with direct API access and in-process tool execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -58,7 +58,8 @@
58
58
  "typecheck": "tsc --noEmit",
59
59
  "test": "bun test",
60
60
  "test:tools": "bun test tests/tools/",
61
- "test:integration": "bun test tests/integration.test.ts"
61
+ "test:integration": "bun test tests/integration.test.ts",
62
+ "test:compat": "bun run tests/compat/run-compat.ts"
62
63
  },
63
64
  "dependencies": {
64
65
  "@anthropic-ai/sdk": "^0.74.0",