@jigging/agent-acp 0.1.0-alpha.5 → 0.1.0-alpha.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.
- package/AGENTS.md +5 -0
- package/README.md +28 -0
- package/dist/flow.js +4 -2
- package/package.json +2 -2
- package/src/flow.ts +12 -2
- package/test/flow.test.ts +48 -0
package/AGENTS.md
CHANGED
|
@@ -33,6 +33,8 @@ retains credential, process, and dispatch authority.
|
|
|
33
33
|
- Jig consumers may select this declared dependency with `npm:@jigging/agent-acp`
|
|
34
34
|
in a local Binding; the Binding still grants the exact native client.
|
|
35
35
|
Contract-keyed project selection does not create that grant or choose a vendor.
|
|
36
|
+
The README teaches package-selected caller creation and offline contract import
|
|
37
|
+
from ordinary root/member installs; consumers do not name physical installer paths.
|
|
36
38
|
- Reuse `@jigging/agent-method` for prompt preparation and result validation.
|
|
37
39
|
Complete ACP dialogue and resource settlement are separate requirements.
|
|
38
40
|
- Locally detected invalid ACP cancels the resource while preserving that
|
|
@@ -45,6 +47,9 @@ retains credential, process, and dispatch authority.
|
|
|
45
47
|
closes the writer with `error: 'LAGGED'`; no clean EOF hides incomplete output.
|
|
46
48
|
Closed native warning notices go to console diagnostics, not answer text or
|
|
47
49
|
public events; the host strips raw metadata and rejects authoritative errors.
|
|
50
|
+
- A native request rejection reports its known finite ACP method with
|
|
51
|
+
`EXECUTION_FAILED`, never the client's error text or data. That phase does not
|
|
52
|
+
establish the private cause, remote dispatch or permission to retry.
|
|
48
53
|
- Optional conversational mode owns bounded direct commands/replies and per-turn
|
|
49
54
|
results in `src/conversation.ts`. Native maxTurns, serial dispatch and interruption
|
|
50
55
|
settlement remain host-enforced. One-shot calls retain their simple interface.
|
package/README.md
CHANGED
|
@@ -38,6 +38,10 @@ filesystem context are not supplied.
|
|
|
38
38
|
|
|
39
39
|
Native warnings are separate, sanitized console diagnostics rather than answer
|
|
40
40
|
text or Agent events. Authoritative native errors remain invocation failures.
|
|
41
|
+
Rejected native requests report the failed ACP step, such as `session/new` or
|
|
42
|
+
`session/prompt`, with `EXECUTION_FAILED`. The client's private error text and
|
|
43
|
+
data are withheld. The step identifies where the rejection was received; it
|
|
44
|
+
does not establish its cause, remote effects, or permission to repeat the call.
|
|
41
45
|
|
|
42
46
|
For conversational use, add `conversation: true` to input and connect direct
|
|
43
47
|
`commands` and `replies` channels from the complete contract bundle. Initial
|
|
@@ -127,6 +131,30 @@ The example's client is a choice, not a Jig default; `codex`, `claude` and `pi`
|
|
|
127
131
|
use the same grant interface. The operator configures the native installation, model and
|
|
128
132
|
authentication described in [Choose an Agent](https://jig.md/guide/agents).
|
|
129
133
|
|
|
134
|
+
To call this Agent from a new Flow, install the declared project dependency
|
|
135
|
+
with `bun install`, then select its complete contract when creating the caller:
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
jig new worker --use agent=npm:@jigging/agent-acp
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
For an existing caller, create its `contracts/` parent and import the bundle:
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
mkdir -p flows/worker/contracts
|
|
145
|
+
jig import-contract npm:@jigging/agent-acp flows/worker/contracts/agent
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Declare `uses.agent.contract: './contracts/agent/FLOW.contract.json'` in that
|
|
149
|
+
caller's metadata. Selection uses the nearest ordinary project or member-local
|
|
150
|
+
installation, copies all referenced channel descriptors offline, and runs no
|
|
151
|
+
package code. The copied contract belongs to the caller: an installation update
|
|
152
|
+
does not replace it or grant new authority. An existing destination is refused;
|
|
153
|
+
choose a new directory to inspect a changed contract before updating the caller.
|
|
154
|
+
See the [conversation walkthrough](https://jig.md/guide/conversations) for a
|
|
155
|
+
complete two-turn caller and the separate native turn grant. These authoring
|
|
156
|
+
commands require the matching Jig source candidate until its alpha is published.
|
|
157
|
+
|
|
130
158
|
```sh
|
|
131
159
|
jig review
|
|
132
160
|
jig run binding:agent --input '{"instructions":"Explain one useful check."}' --receive events
|
package/dist/flow.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// ../agent-method/dist/errors.js
|
|
2
2
|
class AgentMethodError extends Error {
|
|
3
3
|
code;
|
|
4
|
-
|
|
4
|
+
details;
|
|
5
|
+
constructor(code, message, details) {
|
|
5
6
|
super(message);
|
|
6
7
|
this.code = code;
|
|
8
|
+
this.details = details;
|
|
7
9
|
this.name = "AgentMethodError";
|
|
8
10
|
}
|
|
9
11
|
}
|
|
@@ -3215,7 +3217,7 @@ class FinitePeer {
|
|
|
3215
3217
|
if (frame.id !== id || Object.hasOwn(frame, "result") === Object.hasOwn(frame, "error"))
|
|
3216
3218
|
failure("Native ACP response does not match its request");
|
|
3217
3219
|
if (frame.error !== undefined)
|
|
3218
|
-
throw new OperationError("EXECUTION_FAILED",
|
|
3220
|
+
throw new OperationError("EXECUTION_FAILED", `Native ACP request failed during ${method}; private client details were withheld.`);
|
|
3219
3221
|
return object2(frame.result);
|
|
3220
3222
|
}
|
|
3221
3223
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jigging/agent-acp",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.7",
|
|
4
4
|
"description": "An ordinary Agent Flow over a finite, host-authorized ACP resource",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
],
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@jigging/flow": "0.1.0-alpha.13",
|
|
40
|
-
"@jigging/agent-method": "0.1.0-alpha.
|
|
40
|
+
"@jigging/agent-method": "0.1.0-alpha.6",
|
|
41
41
|
"@types/node": "24.13.3",
|
|
42
42
|
"typescript": "7.0.2"
|
|
43
43
|
}
|
package/src/flow.ts
CHANGED
|
@@ -32,6 +32,13 @@ const RESPONSES = './contracts/finite-acp/responses.json'
|
|
|
32
32
|
const MAX_TEXT_BYTES = 8_388_608
|
|
33
33
|
|
|
34
34
|
type Settlement = { result: RunResult } | { error: unknown }
|
|
35
|
+
type NativeRequestMethod =
|
|
36
|
+
| 'initialize'
|
|
37
|
+
| 'session/new'
|
|
38
|
+
| 'session/resume'
|
|
39
|
+
| 'session/set_config_option'
|
|
40
|
+
| 'session/set_mode'
|
|
41
|
+
| 'session/prompt'
|
|
35
42
|
|
|
36
43
|
/** One replaceable method; process, credentials and reviewed policy stay outside. */
|
|
37
44
|
export async function agentAcpFlow(run: RunContext): Promise<RunResult> {
|
|
@@ -261,7 +268,7 @@ class FinitePeer {
|
|
|
261
268
|
private readonly updates: OptionalUpdates,
|
|
262
269
|
) {}
|
|
263
270
|
|
|
264
|
-
async request(method:
|
|
271
|
+
async request(method: NativeRequestMethod, params: JsonObject): Promise<JsonObject> {
|
|
265
272
|
const id = ++this.operation
|
|
266
273
|
await this.write({ jsonrpc: '2.0', id, method, params })
|
|
267
274
|
for (;;) {
|
|
@@ -275,7 +282,10 @@ class FinitePeer {
|
|
|
275
282
|
if (frame.id !== id || Object.hasOwn(frame, 'result') === Object.hasOwn(frame, 'error'))
|
|
276
283
|
failure('Native ACP response does not match its request')
|
|
277
284
|
if (frame.error !== undefined)
|
|
278
|
-
throw new OperationError(
|
|
285
|
+
throw new OperationError(
|
|
286
|
+
'EXECUTION_FAILED',
|
|
287
|
+
`Native ACP request failed during ${method}; private client details were withheld.`,
|
|
288
|
+
)
|
|
279
289
|
return object(frame.result)
|
|
280
290
|
}
|
|
281
291
|
}
|
package/test/flow.test.ts
CHANGED
|
@@ -248,6 +248,54 @@ function fixture(options: Options = {}) {
|
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
+
describe('native request failure diagnostics', () => {
|
|
252
|
+
test.each([
|
|
253
|
+
'initialize',
|
|
254
|
+
'session/new',
|
|
255
|
+
'session/resume',
|
|
256
|
+
'session/set_config_option',
|
|
257
|
+
'session/set_mode',
|
|
258
|
+
'session/prompt',
|
|
259
|
+
])(
|
|
260
|
+
'identifies %s without exposing native error text or sending further requests',
|
|
261
|
+
async (method) => {
|
|
262
|
+
const restoring = method === 'session/resume'
|
|
263
|
+
const f = fixture({
|
|
264
|
+
...(restoring
|
|
265
|
+
? {
|
|
266
|
+
input: {
|
|
267
|
+
instructions: 'Continue.',
|
|
268
|
+
session: { restore: '013579ab-cdef-4567-89ab-0123456789ab' },
|
|
269
|
+
},
|
|
270
|
+
ready: { ...ready, restoreSessionId: 'owned-session' },
|
|
271
|
+
}
|
|
272
|
+
: {}),
|
|
273
|
+
async emit(frame, send) {
|
|
274
|
+
if (frame.method !== method) return false
|
|
275
|
+
await f.frameSend(send, {
|
|
276
|
+
jsonrpc: '2.0',
|
|
277
|
+
id: frame.id!,
|
|
278
|
+
error: {
|
|
279
|
+
code: -32603,
|
|
280
|
+
message: '/private/native-state secret-token rejected private-model',
|
|
281
|
+
data: { credential: 'secret-token', cause: 'untrusted native detail' },
|
|
282
|
+
},
|
|
283
|
+
})
|
|
284
|
+
return true
|
|
285
|
+
},
|
|
286
|
+
})
|
|
287
|
+
const failure = await agentAcpFlow(f.run).catch((error) => error)
|
|
288
|
+
expect(failure).toBeInstanceOf(OperationError)
|
|
289
|
+
expect(failure).toMatchObject({
|
|
290
|
+
code: 'EXECUTION_FAILED',
|
|
291
|
+
message: `Native ACP request failed during ${method}; private client details were withheld.`,
|
|
292
|
+
})
|
|
293
|
+
expect(f.frames.at(-1)?.method).toBe(method)
|
|
294
|
+
expect(f.stats()).toEqual({ calls: 1, cancelled: true, settled: true })
|
|
295
|
+
},
|
|
296
|
+
)
|
|
297
|
+
})
|
|
298
|
+
|
|
251
299
|
describe('ordinary session retention and restoration', () => {
|
|
252
300
|
test.each(['active', 'settled'])(
|
|
253
301
|
'notice display during %s does not enter answers or selected public events',
|