@margay/ccl-core 1.4.5-rc.8 → 1.4.6-beta.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/QUICKSTART.md +6 -5
- package/README.md +7 -6
- package/dist/cli.js +9488 -6652
- package/dist/sdk/index.d.ts +3 -1
- package/dist/sdk/index.js +1 -0
- package/dist/sdk/query.d.ts +2 -29
- package/dist/sdk/query.js +52 -14
- package/dist/sdk/queryHandle.d.ts +4 -4
- package/dist/sdk/queryHandle.js +44 -9
- package/dist/sdk/queryInput.d.ts +13 -0
- package/dist/sdk/queryInput.js +70 -0
- package/dist/sdk/requestProgress.d.ts +14 -0
- package/dist/sdk/requestProgress.js +26 -0
- package/dist/sdk/session.d.ts +48 -0
- package/dist/sdk/session.js +167 -0
- package/dist/sdk/types.d.ts +24 -1
- package/docs/ccl-duo-agent.md +2 -0
- package/docs/cli-installation.md +86 -0
- package/docs/context-checkpoints-and-daemon.md +54 -0
- package/docs/error-recovery-usage.md +29 -0
- package/docs/gateway-quickstart.md +52 -0
- package/docs/releases/1.4.5-rc.10.md +50 -0
- package/docs/releases/1.4.5-rc.9.md +22 -0
- package/docs/releases/1.4.6-beta.0.md +54 -0
- package/package.json +10 -4
- package/sdk/API.md +35 -3
- package/sdk/README.md +94 -0
package/sdk/API.md
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from '@margay/ccl-core/sdk'
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
- **运行时**:Node ≥
|
|
20
|
+
- **运行时**:Node ≥ 22.19.0(ESM),依赖随 `@margay/ccl-core` 安装。
|
|
21
21
|
- **CLI 定位**:SDK 以受管子进程方式运行 CCL CLI(全管道 stdio,无 TTY)。CLI 路径解析顺序:
|
|
22
22
|
1. `options.cliPath`
|
|
23
23
|
2. 环境变量 `CCL_SDK_CLI_PATH`
|
|
@@ -29,10 +29,16 @@ import {
|
|
|
29
29
|
|
|
30
30
|
## 2. 核心入口
|
|
31
31
|
|
|
32
|
-
### 2.1 `query(prompt, options?) →
|
|
32
|
+
### 2.1 `query({ prompt, options? }) → Query`
|
|
33
33
|
|
|
34
34
|
发起一轮对话(一次 agentic 任务),异步迭代产出事件,直到终态事件(`result` / `suspended` / fatal `error`)后结束。
|
|
35
35
|
|
|
36
|
+
上面的单轮语义适用于字符串输入;旧的双参数形式仍兼容。`prompt` 也可传
|
|
37
|
+
`AsyncIterable<SDKUserMessage>`:每条输入完成后再消费下一条,`result.turnId`
|
|
38
|
+
关联输入的 `uuid`(未提供时自动生成)。输入结束、生成器错误、abort 或 close
|
|
39
|
+
都会回收流式 query 的 CLI 进程。必须持续消费事件;流式输出积压超过 1024 项
|
|
40
|
+
会明确报错并关闭,避免无限占用内存。
|
|
41
|
+
|
|
36
42
|
```ts
|
|
37
43
|
for await (const event of query('检查收件箱并起草回复', {
|
|
38
44
|
cwd: '/srv/cos-workspace',
|
|
@@ -73,6 +79,20 @@ for await (const event of resumeWithDecision(sessionId, { behavior: 'allow' }))
|
|
|
73
79
|
|
|
74
80
|
`query(newPrompt, { resume: sessionId })` —— 在已有会话上继续新一轮对话(非审批场景的普通 resume)。
|
|
75
81
|
|
|
82
|
+
### 2.5 `createSession(options?) → Session`
|
|
83
|
+
|
|
84
|
+
在同一个 CLI 进程中连续交互。`prompt(content)`、`followUp(content)` 返回
|
|
85
|
+
`Turn { id, result, cancel() }`,按顺序执行;`steer(content)` 中断当前轮,将纠偏
|
|
86
|
+
放到等待队列前面。已产生的工具副作用不会回滚。
|
|
87
|
+
|
|
88
|
+
`maxPendingTurns` 默认 32,包含正在执行的轮次,队满时同步拒绝新输入。
|
|
89
|
+
`onEvent(event)` 接收即时事件,Session 不保存事件历史。`controls` 提供原有
|
|
90
|
+
Query 控制方法,`pid` 用于宿主监控。
|
|
91
|
+
|
|
92
|
+
`endInput()` 停止接受新输入并等待已接受轮次,但保留进程和控制通道;`close()`
|
|
93
|
+
终止进程并拒绝未完成轮次。权限回调可等待宿主决定,interrupt/close 会取消
|
|
94
|
+
等待;返回 `pending` 仍表示持久挂起,后续用 `resumeWithDecision` 恢复。
|
|
95
|
+
|
|
76
96
|
---
|
|
77
97
|
|
|
78
98
|
## 3. 事件参考(SDKEvent)
|
|
@@ -92,7 +112,9 @@ for await (const event of resumeWithDecision(sessionId, { behavior: 'allow' }))
|
|
|
92
112
|
| `error_diagnostic` | `diagnostic: RecoveryDiagnostic`, `sessionId?` | 可选过程事件,仅 `includeErrorDiagnostics:true` 时输出;不是终态 |
|
|
93
113
|
| `raw` | `message` | 透传子进程原始消息(仅 `includeRaw:true` 时产出,调试用) |
|
|
94
114
|
|
|
95
|
-
|
|
115
|
+
**终态约定**:字符串 query 的 `result` 结束该次输入。流式 query / Session 的
|
|
116
|
+
`result` 只结束对应 `turnId`,后续仍可能有输入。`suspended`、fatal `error`、
|
|
117
|
+
关闭或输入 EOF 结束流式 query;不要把首个 result 当作常驻 Session 已关闭。
|
|
96
118
|
|
|
97
119
|
### 恢复结果与用户介入
|
|
98
120
|
|
|
@@ -390,3 +412,13 @@ query('用 filesystem server 列目录', {
|
|
|
390
412
|
|
|
391
413
|
新增事件:`{ type:'stream_event', event, sessionId? }`;result 事件新增 `structuredOutput?`。
|
|
392
414
|
新增 hooks:`onSessionStart` / `onUserPromptSubmit`;`onTurnEnd` 事件新增 `usage?`。
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
### Optional gateway request progress (source candidate)
|
|
418
|
+
|
|
419
|
+
`QueryOptions.includeRequestProgress?: boolean` defaults to false. When enabled,
|
|
420
|
+
`SDKEvent` additionally includes `{ type: 'request_progress', progress }`, where
|
|
421
|
+
`progress` is the exported `GatewayRequestProgress` type. See the
|
|
422
|
+
[request status guide](./README.md#gateway-request-status-source-candidate) for
|
|
423
|
+
phases, bounded delivery and host lifecycle rules. This nonterminal event must
|
|
424
|
+
not be used as an assistant message, a successful result, or a retry instruction.
|
package/sdk/README.md
CHANGED
|
@@ -66,6 +66,43 @@ process events. Those events do not replace or add a terminal result.
|
|
|
66
66
|
See the [API contract](./API.md) and [recovery guide](../docs/error-recovery-usage.md)
|
|
67
67
|
for consent, external blockers, and continuation rules.
|
|
68
68
|
|
|
69
|
+
## Gateway request status (source candidate)
|
|
70
|
+
|
|
71
|
+
Set `includeRequestProgress: true` to receive nonterminal `request_progress`
|
|
72
|
+
events. This is off by default, independent of raw/partial/error diagnostic
|
|
73
|
+
options. It does not change `result`, cancellation, or `onSessionEnd`.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
for await (const event of query('Summarize this project.', {
|
|
77
|
+
includeRequestProgress: true,
|
|
78
|
+
})) {
|
|
79
|
+
if (event.type === 'request_progress') {
|
|
80
|
+
const { requestId, phase, attempt, elapsedMs, idleMs, slow } = event.progress
|
|
81
|
+
// Update a transient status indicator, keyed by requestId.
|
|
82
|
+
}
|
|
83
|
+
if (event.type === 'result') {
|
|
84
|
+
// End the turn using the existing success/error contract.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Phases are `preparing`, `connecting`, `sending`, `waiting_response`,
|
|
90
|
+
`response_headers`, `retry_wait`, `streaming`, and `finished`. `connecting`
|
|
91
|
+
includes pool waiting, DNS, TCP, TLS and proxy negotiation; it does not identify
|
|
92
|
+
which of those substeps is slow. `idleMs` measures time without effective model
|
|
93
|
+
progress. Events contain no prompt, headers, credentials or endpoint URL.
|
|
94
|
+
|
|
95
|
+
Events are finite (at most 32 per model request), not periodic heartbeats.
|
|
96
|
+
A slow notice never counts as model progress or grants permission to retry.
|
|
97
|
+
`finished` ends a request, not necessarily the turn; clear status on the existing
|
|
98
|
+
result/abort/disconnect path as well. Hosts should keep their own deadlines
|
|
99
|
+
and avoid replaying tools when the remote completion state is unknown.
|
|
100
|
+
|
|
101
|
+
CLI users can opt in with `--print --output-format stream-json
|
|
102
|
+
--include-request-progress`; each wire event is `system/request_progress`.
|
|
103
|
+
The flag is invalid with text or JSON output. See
|
|
104
|
+
[request deadlines](../docs/gateway-quickstart.md#request-deadlines-and-slow-waits).
|
|
105
|
+
|
|
69
106
|
## Architecture
|
|
70
107
|
|
|
71
108
|
The SDK is the **host side** of the stream-json control protocol that
|
|
@@ -146,3 +183,60 @@ provider mapping, skills-dir wrapping, hooks, usage accumulation, file-store
|
|
|
146
183
|
round-trip. The issue's live end-to-end DoD slice (real model + mock outbound
|
|
147
184
|
endpoint + real process exit) is CoS-side per the issue's division of labor —
|
|
148
185
|
the SDK-side seams it needs are all covered above.
|
|
186
|
+
# Minimal mode and explicit tools
|
|
187
|
+
|
|
188
|
+
When passing `--bare` through `extraArgs`, the built-in tool set is Bash, Read,
|
|
189
|
+
and Edit (REPL/coordinator modes have their own subset). `--tools default` uses
|
|
190
|
+
that mode's available set; an explicit incompatible selection such as
|
|
191
|
+
`--bare --tools Write` fails with a diagnostic before a model request. Remove
|
|
192
|
+
`--bare` and unset `CLAUDE_CODE_SIMPLE` to request Write. Allow/deny permissions
|
|
193
|
+
still apply; `--allowedTools` does not add tools to the available set.
|
|
194
|
+
|
|
195
|
+
Use `extraArgs: ['--thinking', 'disabled']` to explicitly disable thinking on
|
|
196
|
+
Anthropic Messages compatible routes. Omitting the option retains the route's
|
|
197
|
+
default. The selection persists across requests; a query handle's
|
|
198
|
+
`setMaxThinkingTokens(0)` explicitly disables it, and `null` restores the default.
|
|
199
|
+
# Persistent sessions and streamed input
|
|
200
|
+
|
|
201
|
+
`query({ prompt: asyncIterable, options })` accepts `SDKUserMessage` values. It
|
|
202
|
+
submits one message at a time, waits for its result before pulling the next,
|
|
203
|
+
and adds the input UUID as `result.turnId` (generating a UUID if omitted).
|
|
204
|
+
Input EOF closes a streamed query. Invalid messages or producer failures reject
|
|
205
|
+
the event iterator. Consume events as they arrive: an unread streamed query fails
|
|
206
|
+
explicitly at 1024 buffered events instead of retaining unlimited output.
|
|
207
|
+
|
|
208
|
+
Use `createSession` when the host owns a longer conversation:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { createSession } from '@margay/ccl-core/sdk'
|
|
212
|
+
|
|
213
|
+
const session = createSession({ cwd: projectDir, maxPendingTurns: 32 })
|
|
214
|
+
try {
|
|
215
|
+
const first = session.prompt('Inspect the project and describe the failing test.')
|
|
216
|
+
console.log(await first.result)
|
|
217
|
+
const next = session.followUp('Fix that failure and run the relevant test.')
|
|
218
|
+
console.log(await next.result)
|
|
219
|
+
await session.endInput()
|
|
220
|
+
// The same child and controls remain alive until close().
|
|
221
|
+
console.log(session.pid, await session.controls.initializationResult())
|
|
222
|
+
} finally {
|
|
223
|
+
await session.close()
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`prompt` and `followUp` enqueue FIFO; exceeding `maxPendingTurns` throws before
|
|
228
|
+
acceptance. Each `Turn` has a stable `id`, a `result` promise and `cancel()`.
|
|
229
|
+
Cancelling a queued turn rejects its promise. Cancelling an active turn interrupts
|
|
230
|
+
the CLI and returns its interrupted result; already executed tool effects remain.
|
|
231
|
+
`steer(text)` interrupts the active turn and puts the correction ahead of waiting
|
|
232
|
+
follow-ups. It does not undo earlier effects. `endInput()` rejects new inputs and
|
|
233
|
+
waits for accepted turns while preserving controls; `close()` terminates the child
|
|
234
|
+
and rejects unfinished turns. `onEvent` observes events without retaining history.
|
|
235
|
+
|
|
236
|
+
Permission callbacks can wait for a host decision while the process stays alive.
|
|
237
|
+
Interrupt and close cancel that wait. Returning `{ behavior: 'pending' }` retains
|
|
238
|
+
the existing durable suspend contract: it ends this process and requires
|
|
239
|
+
`resumeWithDecision(sessionId, decision)`; it does not imply automatic approval.
|
|
240
|
+
Uncooperative application iterators/callbacks cannot be forcibly stopped, but do
|
|
241
|
+
not prevent CLI cleanup. One-shot string queries and post-result `rewindFiles`
|
|
242
|
+
retain their existing behavior.
|