@a3s-lab/code 2.5.0 → 3.0.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.
- package/README.md +54 -0
- package/index.d.ts +224 -0
- package/index.js +3 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -52,6 +52,60 @@ Omit `allowedTools` to allow every registered session tool except `program`.
|
|
|
52
52
|
Scripts can also be loaded from workspace-relative `.js` or `.mjs` files with
|
|
53
53
|
`{ path: 'scripts/ptc/search.js' }`.
|
|
54
54
|
|
|
55
|
+
## Workspace Backends And Direct Files
|
|
56
|
+
|
|
57
|
+
The default workspace backend is the local filesystem rooted at the session
|
|
58
|
+
workspace. SDK callers can pass an explicit typed backend through the same
|
|
59
|
+
option surface used by remote, browser, DFS, and container-backed workspaces:
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
const { Agent, LocalWorkspaceBackend } = require('@a3s-lab/code')
|
|
63
|
+
|
|
64
|
+
const agent = await Agent.create('agent.acl')
|
|
65
|
+
const session = agent.session('/repo', {
|
|
66
|
+
workspaceBackend: new LocalWorkspaceBackend('/repo'),
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
await session.writeFile('notes.txt', 'one\ntwo\n')
|
|
70
|
+
await session.readFile('notes.txt')
|
|
71
|
+
await session.ls()
|
|
72
|
+
await session.editFile('notes.txt', 'one', 'uno')
|
|
73
|
+
await session.patchFile('notes.txt', '@@ -1,2 +1,2 @@\n uno\n-two\n+dos')
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### S3-compatible object storage
|
|
77
|
+
|
|
78
|
+
`S3WorkspaceBackend` lets built-in file tools (`read`, `write`, `edit`,
|
|
79
|
+
`patch`, `ls`) target any S3-compatible endpoint — AWS S3, MinIO, RustFS,
|
|
80
|
+
Cloudflare R2, Backblaze B2, etc. `bash`, `git`, `grep`, and `glob` are
|
|
81
|
+
automatically hidden from the model because object storage cannot service
|
|
82
|
+
them.
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
const { Agent, S3WorkspaceBackend } = require('@a3s-lab/code')
|
|
86
|
+
|
|
87
|
+
const agent = await Agent.create('agent.acl')
|
|
88
|
+
const session = agent.session('s3://workspace/users/u1/sessions/s1', {
|
|
89
|
+
workspaceBackend: new S3WorkspaceBackend({
|
|
90
|
+
endpoint: 'https://minio.local:9000', // omit for AWS S3
|
|
91
|
+
region: 'us-east-1',
|
|
92
|
+
accessKeyId: 'AKIA...',
|
|
93
|
+
secretAccessKey: '...',
|
|
94
|
+
bucket: 'workspace',
|
|
95
|
+
prefix: 'users/u1/sessions/s1',
|
|
96
|
+
forcePathStyle: true, // true for MinIO/RustFS/R2
|
|
97
|
+
}),
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
await session.writeFile('notes/hello.txt', 'one\ntwo\n')
|
|
101
|
+
await session.readFile('notes/hello.txt')
|
|
102
|
+
await session.ls('notes')
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
S3 has no atomic read-modify-write, so concurrent writers to the same key
|
|
106
|
+
overwrite each other (last-writer-wins). Partition workspaces per session or
|
|
107
|
+
user via the `prefix` field when running multi-tenant.
|
|
108
|
+
|
|
55
109
|
## Planning Events
|
|
56
110
|
|
|
57
111
|
Planning is automatic by default. Prefer the explicit tri-state
|
package/index.d.ts
CHANGED
|
@@ -71,6 +71,14 @@ export interface AgentEvent {
|
|
|
71
71
|
verificationSummaryText?: string
|
|
72
72
|
/** Extra data for events that don't map to standard fields (JSON-encoded) */
|
|
73
73
|
data?: string
|
|
74
|
+
/**
|
|
75
|
+
* Structured discriminant for tool failures on `tool_end` events
|
|
76
|
+
* (JSON-encoded with a `type` field on the top level, e.g.
|
|
77
|
+
* `{"type":"version_conflict","path":"doc.md","expected":"etag-1","actual":"etag-2"}`).
|
|
78
|
+
* Undefined on success or untyped failure. Streaming consumers parse
|
|
79
|
+
* this to branch on the failure kind without scanning `toolOutput`.
|
|
80
|
+
*/
|
|
81
|
+
errorKindJson?: string
|
|
74
82
|
}
|
|
75
83
|
export interface VerificationCommand {
|
|
76
84
|
id: string
|
|
@@ -88,7 +96,32 @@ export interface ToolResult {
|
|
|
88
96
|
metadataJson?: string
|
|
89
97
|
/** Convenience JSON view of `metadata.document_runtime` when present. */
|
|
90
98
|
documentRuntimeJson?: string
|
|
99
|
+
/**
|
|
100
|
+
* Structured discriminant for tool failures, JSON-encoded with a
|
|
101
|
+
* `type` field on the top level — e.g.
|
|
102
|
+
* `{"type":"version_conflict","path":"doc.md","expected":"etag-1","actual":"etag-2"}`.
|
|
103
|
+
* Undefined on success or untyped failure. SDK callers parse it to
|
|
104
|
+
* branch on the failure kind without scanning the `output` string.
|
|
105
|
+
*/
|
|
106
|
+
errorKindJson?: string
|
|
91
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Parsed shape of `ToolResult.errorKindJson` / `AgentEvent.errorKindJson`.
|
|
111
|
+
*
|
|
112
|
+
* Use a discriminated union on the `type` field; new variants may be
|
|
113
|
+
* added in future minor releases — callers should match exhaustively on
|
|
114
|
+
* the kinds they care about and fall through to a default branch for
|
|
115
|
+
* unknown ones.
|
|
116
|
+
*/
|
|
117
|
+
export type ToolErrorKind =
|
|
118
|
+
| { type: 'version_conflict'; path: string; expected: string; actual: string | null }
|
|
119
|
+
| { type: 'remote_git_conflict'; code: string; message: string }
|
|
120
|
+
| { type: 'not_found'; path: string }
|
|
121
|
+
| { type: 'invalid_argument'; message: string }
|
|
122
|
+
| { type: 'unsupported'; message: string }
|
|
123
|
+
| { type: 'timeout'; op: string; duration_ms: number }
|
|
124
|
+
|
|
92
125
|
/** Execution limits for `Session.program`. */
|
|
93
126
|
export interface ProgramScriptLimits {
|
|
94
127
|
timeoutMs?: number
|
|
@@ -177,6 +210,115 @@ export interface JsSessionStore {
|
|
|
177
210
|
export interface JsSecurityProvider {
|
|
178
211
|
kind: string
|
|
179
212
|
}
|
|
213
|
+
export interface JsWorkspaceBackend {
|
|
214
|
+
kind: string
|
|
215
|
+
root?: string
|
|
216
|
+
s3?: JsS3BackendConfig
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Configuration for an S3-compatible workspace backend.
|
|
220
|
+
*
|
|
221
|
+
* Use this with [`S3WorkspaceBackend`] to point a session's built-in file
|
|
222
|
+
* tools at any S3-compatible endpoint (AWS S3, MinIO, RustFS, R2, etc.).
|
|
223
|
+
* `endpoint` is optional — omit it to use the AWS default. `prefix` is
|
|
224
|
+
* the logical workspace root inside the bucket; every workspace path
|
|
225
|
+
* becomes `<prefix>/<path>` when sent to S3.
|
|
226
|
+
*/
|
|
227
|
+
export interface JsS3BackendConfig {
|
|
228
|
+
/**
|
|
229
|
+
* Optional S3 endpoint URL. Omit for AWS S3 (the SDK will compute it
|
|
230
|
+
* from `region`). Set to `https://...` for MinIO / RustFS / R2 / etc.
|
|
231
|
+
*/
|
|
232
|
+
endpoint?: string
|
|
233
|
+
/** AWS region. Defaults to `us-east-1` when omitted. */
|
|
234
|
+
region?: string
|
|
235
|
+
/** Static access key. Use `sessionToken` together when STS-issued. */
|
|
236
|
+
accessKeyId: string
|
|
237
|
+
secretAccessKey: string
|
|
238
|
+
sessionToken?: string
|
|
239
|
+
/** Bucket name. */
|
|
240
|
+
bucket: string
|
|
241
|
+
/**
|
|
242
|
+
* Logical workspace prefix inside the bucket (without leading/trailing
|
|
243
|
+
* slashes). Use `""` to make the bucket root the workspace.
|
|
244
|
+
*/
|
|
245
|
+
prefix: string
|
|
246
|
+
/** `true` for MinIO / RustFS / most non-AWS endpoints; `false` for AWS S3. */
|
|
247
|
+
forcePathStyle?: boolean
|
|
248
|
+
/**
|
|
249
|
+
* Maximum bytes a single `read` may return. The backend rejects any
|
|
250
|
+
* response with `Content-Length` greater than this without buffering
|
|
251
|
+
* the body. Defaults to 10 MiB on the Rust side when omitted.
|
|
252
|
+
*/
|
|
253
|
+
maxReadBytes?: number
|
|
254
|
+
/**
|
|
255
|
+
* Enable degraded `grep` / `glob` against this S3 backend. Off by
|
|
256
|
+
* default — object storage has no native search, so the only viable
|
|
257
|
+
* strategy is `LIST` + `GET` + regex, which can be slow and expensive.
|
|
258
|
+
*/
|
|
259
|
+
searchEnabled?: boolean
|
|
260
|
+
/**
|
|
261
|
+
* Upper bound on objects considered per `grep` / `glob` call. Defaults
|
|
262
|
+
* to 500 on the Rust side. Ignored when `searchEnabled` is `false`.
|
|
263
|
+
*/
|
|
264
|
+
maxObjectsScanned?: number
|
|
265
|
+
/**
|
|
266
|
+
* Per-object body-size ceiling for `grep` downloads. Larger objects are
|
|
267
|
+
* skipped (debug-traced). Defaults to 1 MiB on the Rust side. Ignored
|
|
268
|
+
* when `searchEnabled` is `false`.
|
|
269
|
+
*/
|
|
270
|
+
maxGrepBytesPerObject?: number
|
|
271
|
+
/**
|
|
272
|
+
* Concurrent object downloads during `grep`. Defaults to 8 on the Rust
|
|
273
|
+
* side. Set lower when the gitserver / S3 endpoint rate-limits
|
|
274
|
+
* aggressively; set higher when latency dominates. Ignored when
|
|
275
|
+
* `searchEnabled` is `false`.
|
|
276
|
+
*/
|
|
277
|
+
searchConcurrency?: number
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Configuration for a `RemoteGitBackend` — an HTTP/JSON client that
|
|
281
|
+
* brings the `git` tool to non-local workspaces (S3, future container /
|
|
282
|
+
* DFS).
|
|
283
|
+
*
|
|
284
|
+
* Pass alongside `workspaceBackend` on a session to attach remote git
|
|
285
|
+
* on top of any filesystem backend.
|
|
286
|
+
*/
|
|
287
|
+
export interface JsRemoteGitBackendConfig {
|
|
288
|
+
/**
|
|
289
|
+
* Base URL of the gitserver, no trailing slash. The client builds
|
|
290
|
+
* `{baseUrl}/v1/repos/{repoId}/git/{op}` per the RFC.
|
|
291
|
+
*/
|
|
292
|
+
baseUrl: string
|
|
293
|
+
/**
|
|
294
|
+
* Opaque repository identifier, URL-safe. Negotiated out of band
|
|
295
|
+
* with the gitserver operator.
|
|
296
|
+
*/
|
|
297
|
+
repoId: string
|
|
298
|
+
/**
|
|
299
|
+
* Bearer token sent as `Authorization: Bearer <token>`. Required in
|
|
300
|
+
* production; omitting it emits a server-side warning and is only safe
|
|
301
|
+
* on a trusted localhost gitserver.
|
|
302
|
+
*/
|
|
303
|
+
bearerToken?: string
|
|
304
|
+
/**
|
|
305
|
+
* mTLS client certificate path (PEM). When set together with `clientKeyPem`,
|
|
306
|
+
* the backend reads both files at construction and configures mTLS on the
|
|
307
|
+
* HTTP client. Setting only one of the pair errors at construction.
|
|
308
|
+
*/
|
|
309
|
+
clientCertPem?: string
|
|
310
|
+
/**
|
|
311
|
+
* mTLS client private key path (PEM). PKCS#8 format expected for the
|
|
312
|
+
* `rustls-tls` backend. See `clientCertPem`.
|
|
313
|
+
*/
|
|
314
|
+
clientKeyPem?: string
|
|
315
|
+
/** Per-call HTTP timeout in milliseconds. Defaults to 30 000. */
|
|
316
|
+
requestTimeoutMs?: number
|
|
317
|
+
/** Client-side cap on `diff` response bytes. Defaults to 1 MiB. */
|
|
318
|
+
maxDiffBytes?: number
|
|
319
|
+
/** Client-side cap on `log` `max_count`. Defaults to 200. */
|
|
320
|
+
maxLogEntries?: number
|
|
321
|
+
}
|
|
180
322
|
/**
|
|
181
323
|
* Union type for AHP transport configuration.
|
|
182
324
|
* Accepts any of: StdioTransport, HttpTransport, WebSocketTransport, UnixSocketTransport.
|
|
@@ -339,6 +481,34 @@ export interface SessionOptions {
|
|
|
339
481
|
* ```
|
|
340
482
|
*/
|
|
341
483
|
securityProvider?: JsSecurityProvider
|
|
484
|
+
/**
|
|
485
|
+
* Workspace backend used by built-in tools.
|
|
486
|
+
*
|
|
487
|
+
* Pass `new LocalWorkspaceBackend("/repo")` to explicitly use the local
|
|
488
|
+
* filesystem backend. This option is the SDK surface for future remote,
|
|
489
|
+
* browser, DFS, and container-backed workspace implementations.
|
|
490
|
+
* ```js
|
|
491
|
+
* agent.session('/repo', { workspaceBackend: new LocalWorkspaceBackend('/repo') });
|
|
492
|
+
* ```
|
|
493
|
+
*/
|
|
494
|
+
workspaceBackend?: JsWorkspaceBackend
|
|
495
|
+
/**
|
|
496
|
+
* Optional remote git provider. When set, the resulting session attaches
|
|
497
|
+
* a `RemoteGitBackend` on top of `workspaceBackend` so the built-in
|
|
498
|
+
* `git` tool is available even on object-storage workspaces.
|
|
499
|
+
*
|
|
500
|
+
* ```js
|
|
501
|
+
* agent.session('s3://workspace/u1/s1', {
|
|
502
|
+
* workspaceBackend: new S3WorkspaceBackend({ ... }),
|
|
503
|
+
* remoteGit: {
|
|
504
|
+
* baseUrl: 'https://gitserver.internal',
|
|
505
|
+
* repoId: 'u1/s1',
|
|
506
|
+
* bearerToken: token,
|
|
507
|
+
* },
|
|
508
|
+
* });
|
|
509
|
+
* ```
|
|
510
|
+
*/
|
|
511
|
+
remoteGit?: JsRemoteGitBackendConfig
|
|
342
512
|
/**
|
|
343
513
|
* Custom role/identity prepended before the core agentic prompt.
|
|
344
514
|
* Example: "You are a senior Python developer specializing in FastAPI."
|
|
@@ -698,6 +868,52 @@ export declare class DefaultSecurityProvider {
|
|
|
698
868
|
kind: string
|
|
699
869
|
constructor()
|
|
700
870
|
}
|
|
871
|
+
/**
|
|
872
|
+
* Local filesystem workspace backend.
|
|
873
|
+
*
|
|
874
|
+
* This is the explicit typed form of the default local workspace behavior.
|
|
875
|
+
* It is useful when callers want to pass workspace backends through the same
|
|
876
|
+
* option surface that remote/browser backends will use.
|
|
877
|
+
*
|
|
878
|
+
* ```js
|
|
879
|
+
* agent.session('/repo', { workspaceBackend: new LocalWorkspaceBackend('/repo') });
|
|
880
|
+
* ```
|
|
881
|
+
*/
|
|
882
|
+
export declare class LocalWorkspaceBackend {
|
|
883
|
+
kind: string
|
|
884
|
+
root: string
|
|
885
|
+
/** Create a local filesystem workspace backend rooted at `root`. */
|
|
886
|
+
constructor(root: string)
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* S3-compatible object-storage workspace backend.
|
|
890
|
+
*
|
|
891
|
+
* Points built-in file tools (`read`, `write`, `edit`, `patch`, `ls`) at an
|
|
892
|
+
* S3-compatible bucket. Works with AWS S3, MinIO, RustFS, Cloudflare R2,
|
|
893
|
+
* Backblaze B2, and other S3-API-compatible services.
|
|
894
|
+
*
|
|
895
|
+
* `bash`, `git`, `grep`, and `glob` are intentionally **not** registered
|
|
896
|
+
* when this backend is in use — object storage cannot service them.
|
|
897
|
+
*
|
|
898
|
+
* ```js
|
|
899
|
+
* const backend = new S3WorkspaceBackend({
|
|
900
|
+
* endpoint: 'https://minio.local:9000',
|
|
901
|
+
* region: 'us-east-1',
|
|
902
|
+
* accessKeyId: 'AKIA...',
|
|
903
|
+
* secretAccessKey: '...',
|
|
904
|
+
* bucket: 'workspace',
|
|
905
|
+
* prefix: 'users/u1/sessions/s1',
|
|
906
|
+
* forcePathStyle: true,
|
|
907
|
+
* });
|
|
908
|
+
* agent.session('s3://workspace/users/u1/sessions/s1', { workspaceBackend: backend });
|
|
909
|
+
* ```
|
|
910
|
+
*/
|
|
911
|
+
export declare class S3WorkspaceBackend {
|
|
912
|
+
kind: string
|
|
913
|
+
s3: JsS3BackendConfig
|
|
914
|
+
/** Create an S3-compatible workspace backend. */
|
|
915
|
+
constructor(config: JsS3BackendConfig)
|
|
916
|
+
}
|
|
701
917
|
/**
|
|
702
918
|
* Stdio transport for AHP (Agent Harness Protocol).
|
|
703
919
|
*
|
|
@@ -919,6 +1135,14 @@ export declare class Session {
|
|
|
919
1135
|
program(options: ProgramScriptOptions): Promise<ToolResult>
|
|
920
1136
|
/** Read a file from the workspace. */
|
|
921
1137
|
readFile(path: string): Promise<string>
|
|
1138
|
+
/** Write a file in the workspace. */
|
|
1139
|
+
writeFile(path: string, content: string): Promise<ToolResult>
|
|
1140
|
+
/** List a directory in the workspace. */
|
|
1141
|
+
ls(path?: string | undefined | null): Promise<ToolResult>
|
|
1142
|
+
/** Edit a file by replacing text in the workspace. */
|
|
1143
|
+
editFile(path: string, oldString: string, newString: string, replaceAll?: boolean | undefined | null): Promise<ToolResult>
|
|
1144
|
+
/** Apply a unified diff patch to a workspace file. */
|
|
1145
|
+
patchFile(path: string, diff: string): Promise<ToolResult>
|
|
922
1146
|
/** Execute a bash command in the workspace. */
|
|
923
1147
|
bash(command: string): Promise<string>
|
|
924
1148
|
/** Search for files matching a glob pattern. */
|
package/index.js
CHANGED
|
@@ -310,7 +310,7 @@ if (!nativeBinding) {
|
|
|
310
310
|
throw new Error(`Failed to load native binding`)
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
const { formatVerificationSummary, EventStream, FileMemoryStore, FileSessionStore, MemorySessionStore, DefaultSecurityProvider, StdioTransport, HttpTransport, WebSocketTransport, UnixSocketTransport, Agent, Session, builtinSkills, BrowserBackend } = nativeBinding
|
|
313
|
+
const { formatVerificationSummary, EventStream, FileMemoryStore, FileSessionStore, MemorySessionStore, DefaultSecurityProvider, LocalWorkspaceBackend, S3WorkspaceBackend, StdioTransport, HttpTransport, WebSocketTransport, UnixSocketTransport, Agent, Session, builtinSkills, BrowserBackend } = nativeBinding
|
|
314
314
|
|
|
315
315
|
module.exports.formatVerificationSummary = formatVerificationSummary
|
|
316
316
|
module.exports.EventStream = EventStream
|
|
@@ -318,6 +318,8 @@ module.exports.FileMemoryStore = FileMemoryStore
|
|
|
318
318
|
module.exports.FileSessionStore = FileSessionStore
|
|
319
319
|
module.exports.MemorySessionStore = MemorySessionStore
|
|
320
320
|
module.exports.DefaultSecurityProvider = DefaultSecurityProvider
|
|
321
|
+
module.exports.LocalWorkspaceBackend = LocalWorkspaceBackend
|
|
322
|
+
module.exports.S3WorkspaceBackend = S3WorkspaceBackend
|
|
321
323
|
module.exports.StdioTransport = StdioTransport
|
|
322
324
|
module.exports.HttpTransport = HttpTransport
|
|
323
325
|
module.exports.WebSocketTransport = WebSocketTransport
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a3s-lab/code",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A3S Code - Native Node.js bindings for the coding-agent runtime",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"test:helpers": "node test-helpers.mjs"
|
|
41
41
|
},
|
|
42
42
|
"optionalDependencies": {
|
|
43
|
-
"@a3s-lab/code-darwin-arm64": "
|
|
44
|
-
"@a3s-lab/code-linux-x64-gnu": "
|
|
45
|
-
"@a3s-lab/code-linux-x64-musl": "
|
|
46
|
-
"@a3s-lab/code-linux-arm64-gnu": "
|
|
47
|
-
"@a3s-lab/code-linux-arm64-musl": "
|
|
48
|
-
"@a3s-lab/code-win32-x64-msvc": "
|
|
43
|
+
"@a3s-lab/code-darwin-arm64": "3.0.0",
|
|
44
|
+
"@a3s-lab/code-linux-x64-gnu": "3.0.0",
|
|
45
|
+
"@a3s-lab/code-linux-x64-musl": "3.0.0",
|
|
46
|
+
"@a3s-lab/code-linux-arm64-gnu": "3.0.0",
|
|
47
|
+
"@a3s-lab/code-linux-arm64-musl": "3.0.0",
|
|
48
|
+
"@a3s-lab/code-win32-x64-msvc": "3.0.0"
|
|
49
49
|
}
|
|
50
50
|
}
|