@adecore/agents 0.29.0 → 0.29.1

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.
package/dist/fs.d.ts CHANGED
@@ -6,4 +6,7 @@ export declare function writeAtomic(target: string, content: string | Uint8Array
6
6
  export declare function replaceSync(temp: string, target: string): void;
7
7
  export declare function writeAtomicSync(target: string, content: string | Uint8Array, mode?: number): void;
8
8
  export declare function isNotFound(e: unknown): boolean;
9
+ export declare function removeFile(path: string, remove?: (path: string, options: {
10
+ force: true;
11
+ }) => Promise<void>): Promise<void>;
9
12
  export declare function fileExists(path: string): Promise<boolean>;
package/dist/fs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { renameSync, writeFileSync } from 'node:fs';
2
- import { open, rename, stat, writeFile } from 'node:fs/promises';
2
+ import { open, rename, rm, stat, writeFile } from 'node:fs/promises';
3
3
  import { dirname } from 'node:path';
4
4
  // Windows can refuse a rename while a watcher or an indexer holds the target; a few short retries cover it.
5
5
  const RENAME_RETRIES = 5;
@@ -96,6 +96,17 @@ export function writeAtomicSync(target, content, mode = 0o600) {
96
96
  export function isNotFound(e) {
97
97
  return typeof e === 'object' && e !== null && 'code' in e && e.code === 'ENOENT';
98
98
  }
99
+ // Bun on Windows fails a forced rm with EFAULT while another delete of the same file is pending; it goes either way.
100
+ export async function removeFile(path, remove = rm) {
101
+ try {
102
+ await remove(path, { force: true });
103
+ }
104
+ catch (e) {
105
+ if (!(typeof e === 'object' && e !== null && 'code' in e && e.code === 'EFAULT')) {
106
+ throw e;
107
+ }
108
+ }
109
+ }
99
110
  export async function fileExists(path) {
100
111
  try {
101
112
  await stat(path);
@@ -1,6 +1,6 @@
1
- import { mkdir, readdir, readFile, rm } from 'node:fs/promises';
1
+ import { mkdir, readdir, readFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
- import { isNotFound, writeAtomic } from './fs.js';
3
+ import { isNotFound, removeFile, writeAtomic } from './fs.js';
4
4
  import { KeyedSerializer } from './serializer.js';
5
5
  // The id is a node id or a chat id a client chose, so it is encoded before it becomes a file name.
6
6
  export function recordFileName(id) {
@@ -59,7 +59,7 @@ export class RecordDirectory {
59
59
  }
60
60
  const record = this.keep === null ? parsed.data : this.keep(parsed.data);
61
61
  if (record === null) {
62
- await rm(join(this.dir, name), { force: true });
62
+ await removeFile(join(this.dir, name));
63
63
  continue;
64
64
  }
65
65
  this.records.set(this.idOf(record), record);
@@ -89,7 +89,7 @@ export class RecordDirectory {
89
89
  await mkdir(this.dir, { recursive: true, mode: 0o700 });
90
90
  await this.writeFile(this.pathOf(id), JSON.stringify(record));
91
91
  if (!this.records.has(id)) {
92
- await rm(this.pathOf(id), { force: true });
92
+ await removeFile(this.pathOf(id));
93
93
  return false;
94
94
  }
95
95
  return true;
@@ -98,7 +98,7 @@ export class RecordDirectory {
98
98
  /* Forgets a record here and now; its file follows. */
99
99
  remove(id) {
100
100
  this.records.delete(id);
101
- return rm(this.pathOf(id), { force: true });
101
+ return removeFile(this.pathOf(id));
102
102
  }
103
103
  async prune(drop) {
104
104
  for (const listed of this.all()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/agents",
3
- "version": "0.29.0",
3
+ "version": "0.29.1",
4
4
  "description": "Node-compatible agent chat hosts, providers, accounts, usage and durable task coordination.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -81,8 +81,8 @@
81
81
  "test": "bun --conditions=source test"
82
82
  },
83
83
  "dependencies": {
84
- "@adecore/agent-contracts": "0.29.0",
85
- "@adecore/intelligent-ui": "0.29.0",
84
+ "@adecore/agent-contracts": "0.29.1",
85
+ "@adecore/intelligent-ui": "0.29.1",
86
86
  "zod": "^4.6.5"
87
87
  },
88
88
  "devDependencies": {
package/src/fs.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { renameSync, writeFileSync } from 'node:fs';
2
- import { open, rename, stat, writeFile } from 'node:fs/promises';
2
+ import { open, rename, rm, stat, writeFile } from 'node:fs/promises';
3
3
  import { dirname } from 'node:path';
4
4
 
5
5
  // Windows can refuse a rename while a watcher or an indexer holds the target; a few short retries cover it.
@@ -108,6 +108,17 @@ export function isNotFound(e: unknown): boolean {
108
108
  return typeof e === 'object' && e !== null && 'code' in e && e.code === 'ENOENT';
109
109
  }
110
110
 
111
+ // Bun on Windows fails a forced rm with EFAULT while another delete of the same file is pending; it goes either way.
112
+ export async function removeFile(path: string, remove: (path: string, options: { force: true }) => Promise<void> = rm): Promise<void> {
113
+ try {
114
+ await remove(path, { force: true });
115
+ } catch (e) {
116
+ if (!(typeof e === 'object' && e !== null && 'code' in e && e.code === 'EFAULT')) {
117
+ throw e;
118
+ }
119
+ }
120
+ }
121
+
111
122
  export async function fileExists(path: string): Promise<boolean> {
112
123
  try {
113
124
  await stat(path);
@@ -1,7 +1,7 @@
1
- import { mkdir, readdir, readFile, rm } from 'node:fs/promises';
1
+ import { mkdir, readdir, readFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import type { z } from 'zod';
4
- import { isNotFound, writeAtomic } from './fs.ts';
4
+ import { isNotFound, removeFile, writeAtomic } from './fs.ts';
5
5
  import { KeyedSerializer } from './serializer.ts';
6
6
 
7
7
  // The id is a node id or a chat id a client chose, so it is encoded before it becomes a file name.
@@ -74,7 +74,7 @@ export class RecordDirectory<T> {
74
74
  }
75
75
  const record = this.keep === null ? parsed.data : this.keep(parsed.data);
76
76
  if (record === null) {
77
- await rm(join(this.dir, name), { force: true });
77
+ await removeFile(join(this.dir, name));
78
78
  continue;
79
79
  }
80
80
  this.records.set(this.idOf(record), record);
@@ -108,7 +108,7 @@ export class RecordDirectory<T> {
108
108
  await mkdir(this.dir, { recursive: true, mode: 0o700 });
109
109
  await this.writeFile(this.pathOf(id), JSON.stringify(record));
110
110
  if (!this.records.has(id)) {
111
- await rm(this.pathOf(id), { force: true });
111
+ await removeFile(this.pathOf(id));
112
112
  return false;
113
113
  }
114
114
  return true;
@@ -118,7 +118,7 @@ export class RecordDirectory<T> {
118
118
  /* Forgets a record here and now; its file follows. */
119
119
  remove(id: string): Promise<void> {
120
120
  this.records.delete(id);
121
- return rm(this.pathOf(id), { force: true });
121
+ return removeFile(this.pathOf(id));
122
122
  }
123
123
 
124
124
  async prune(drop: (record: T) => boolean): Promise<void> {