@khorsheed/dsh-local-agent-claude-code 0.2.0-rc.1 → 0.2.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/CHANGELOG.md +27 -0
- package/README.en.md +24 -106
- package/README.i18n.yaml +2 -2
- package/README.md +24 -106
- package/lib/client.js +842 -315
- package/lib/index.js +1707 -1392
- package/lib/types/claude-cli-provider.d.ts +86 -6
- package/lib/types/claude-cli-provider.js +391 -146
- package/lib/types/client/SettingsCard.d.ts +75 -24
- package/lib/types/client/SettingsCard.js +106 -128
- package/lib/types/client/icons.d.ts +1 -1
- package/lib/types/client/index.d.ts +12 -25
- package/lib/types/client/index.js +135 -50
- package/lib/types/client/locales.d.ts +36 -24
- package/lib/types/client/locales.js +40 -28
- package/lib/types/endpoint-auth.d.ts +181 -0
- package/lib/types/endpoint-auth.js +297 -0
- package/lib/types/index.d.ts +32 -16
- package/lib/types/index.js +128 -62
- package/lib/types/live-driver.d.ts +9 -6
- package/lib/types/live-driver.js +277 -119
- package/lib/types/live-switch.d.ts +4 -1
- package/lib/types/model-broker.d.ts +4 -2
- package/lib/types/model-broker.js +63 -10
- package/lib/types/model-catalog.d.ts +35 -6
- package/lib/types/model-catalog.js +58 -68
- package/lib/types/provision.d.ts +34 -27
- package/lib/types/provision.js +49 -31
- package/lib/types/records.d.ts +4 -62
- package/lib/types/records.js +5 -382
- package/locale/en.json +2 -2
- package/locale/zh.json +2 -2
- package/package.json +20 -21
- package/lib/invariant.js +0 -31
- package/lib/types/invariant.d.ts +0 -16
- package/lib/types/invariant.js +0 -33
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* loud, by design).
|
|
15
15
|
* @module @khorsheed/dsh-local-agent-claude-code/claude-cli-provider
|
|
16
16
|
*/
|
|
17
|
-
import type { ContentBlock, TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
17
|
+
import type { ContentBlock, ReasoningEffortId, TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
18
18
|
import type { TodoItem } from '@deepseek-ai/dsh-tool-todo';
|
|
19
19
|
import { type ResolvedSubagentStartRequest, type SubagentCapabilities, type SubagentProvider, type SubagentRun, type SubagentStartRequest, type SubagentStopReason } from '@deepseek-ai/dsh-subagent';
|
|
20
20
|
import type { Context } from '@deepseek-ai/cordis';
|
|
@@ -22,14 +22,31 @@ import type { Session } from '@deepseek-ai/dsh-session';
|
|
|
22
22
|
import type { SubprocessHandle, SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess';
|
|
23
23
|
import type { DelegationExecTarget, LocalAgentToolCalls } from '@khorsheed/dsh-local-agent/types';
|
|
24
24
|
import type { ClaudeLiveDriver } from './live-driver.ts';
|
|
25
|
+
import type { ClaudeEndpointAuth } from './endpoint-auth.ts';
|
|
26
|
+
/**
|
|
27
|
+
* The synthesized result for a call whose result the stream never recorded
|
|
28
|
+
* (a settle-pass fold after a kill or a truncated stream). The released-log
|
|
29
|
+
* contract resolves every advertised call before its step closes, so an
|
|
30
|
+
* interrupted call folds with this error result. Shared verbatim with the
|
|
31
|
+
* kimi provider (`KIMI_INTERRUPTED_TOOL_RESULT`) so the family reads one text.
|
|
32
|
+
*/
|
|
33
|
+
export declare const CLAUDE_INTERRUPTED_TOOL_RESULT = "\uFF08\u5DE5\u5177\u8C03\u7528\u88AB\u4E2D\u65AD\uFF0C\u672A\u80FD\u8BB0\u5F55\u8FD4\u56DE\u7ED3\u679C\uFF09";
|
|
25
34
|
/** Default POSIX grace between subprocess termination tiers. */
|
|
26
35
|
export declare const DEFAULT_DISPOSE_GRACE_MS = 3000;
|
|
27
36
|
/**
|
|
28
37
|
* Auth-shaped failure signatures in claude's result error or stderr: the
|
|
29
|
-
* endpoint rejected the credential (401/403, revoked
|
|
30
|
-
*
|
|
38
|
+
* endpoint rejected the credential (401/403, revoked key). Matches the CLI's
|
|
39
|
+
* own phrasing ("Failed to authenticate. API Error: 401 …", the
|
|
40
|
+
* `authentication_failed` error tag) plus the relay phrasings seen in the
|
|
41
|
+
* wild ("invalid x-api-key" and friends). Narrow on purpose — matched against
|
|
42
|
+
* provider-controlled error strings only.
|
|
31
43
|
*/
|
|
32
44
|
export declare const CLAUDE_AUTH_FAILURE: RegExp;
|
|
45
|
+
/**
|
|
46
|
+
* The MCP tool-call bound for a member's claude process (`MCP_TOOL_TIMEOUT`,
|
|
47
|
+
* ms): a bridge call may wait up to 30 minutes for the human's answer.
|
|
48
|
+
*/
|
|
49
|
+
export declare const MEMBER_TOOL_TIMEOUT_MS: string;
|
|
33
50
|
/**
|
|
34
51
|
* Member channel registration for one claude process lifetime: mint the
|
|
35
52
|
* per-run token and build the bridge MCP declaration for the spawn argv
|
|
@@ -62,7 +79,7 @@ export declare function claudeCliVersion(ctx: Context, homeDir: string): Promise
|
|
|
62
79
|
export declare class ClaudeCliProvider implements SubagentProvider {
|
|
63
80
|
private readonly ctx;
|
|
64
81
|
private readonly permissionMode;
|
|
65
|
-
private readonly
|
|
82
|
+
private readonly endpoint?;
|
|
66
83
|
private readonly live?;
|
|
67
84
|
private readonly model?;
|
|
68
85
|
readonly name = "claude-local";
|
|
@@ -73,6 +90,11 @@ export declare class ClaudeCliProvider implements SubagentProvider {
|
|
|
73
90
|
* generation's driver per member (the settings toggle swaps generations;
|
|
74
91
|
* a resolver may return undefined to steer one member's round to exec
|
|
75
92
|
* while a retiring generation still hosts it).
|
|
93
|
+
* @param endpoint - resolver for the round's endpoint credential (endpoint-auth.ts:
|
|
94
|
+
* the scope's endpoint-auth.json over the plugin config triple), read PER
|
|
95
|
+
* ROUND against the round's scoped home, so a key rotation or a profile
|
|
96
|
+
* edit takes effect on the next delegation without a reload. Absent, no
|
|
97
|
+
* `ANTHROPIC_*` variables reach the child at all.
|
|
76
98
|
* @param model - resolver for the member's effective model, read PER ROUND
|
|
77
99
|
* so a settings-card write or a composer switch takes effect on the next
|
|
78
100
|
* delegation without a reload. Receives the member (the child session id)
|
|
@@ -81,7 +103,7 @@ export declare class ClaudeCliProvider implements SubagentProvider {
|
|
|
81
103
|
* resolver not passed), the delegation's own model still rides, exactly
|
|
82
104
|
* as before the key existed.
|
|
83
105
|
*/
|
|
84
|
-
constructor(ctx: Context, permissionMode?: 'skip' | 'normal',
|
|
106
|
+
constructor(ctx: Context, permissionMode?: 'skip' | 'normal', endpoint?: ((homeDir: string) => Promise<ClaudeEndpointAuth>) | undefined, live?: ClaudeLiveDriver | ((childSessionId: string) => ClaudeLiveDriver | undefined) | undefined, model?: ((childSessionId: string, delegationModel?: string) => string | undefined) | undefined);
|
|
85
107
|
/** Resolve the live driver for one round's member, if live is on for it. */
|
|
86
108
|
private liveDriver;
|
|
87
109
|
/** The round's model fragment for the exec spawn spec (see {@link resolveRoundModel}). */
|
|
@@ -202,16 +224,25 @@ export type ClaudeTranscriptLine = {
|
|
|
202
224
|
kind: 'think';
|
|
203
225
|
text: string;
|
|
204
226
|
streamId?: string;
|
|
227
|
+
messageId?: string;
|
|
228
|
+
usage?: TokenUsage;
|
|
205
229
|
} | {
|
|
206
230
|
kind: 'text';
|
|
207
231
|
text: string;
|
|
208
232
|
streamId?: string;
|
|
233
|
+
messageId?: string;
|
|
234
|
+
usage?: TokenUsage;
|
|
209
235
|
}
|
|
210
236
|
/**
|
|
211
237
|
* Tool activity: one `tool_use` with its (possibly still pending)
|
|
212
238
|
* `tool_result`. `id` is the stream's tool_use id when present, else a
|
|
213
239
|
* synthesized position-based id — stable within a run either way, so the
|
|
214
|
-
* child session's `tool/call`/`tool/result` events pair by it.
|
|
240
|
+
* child session's `tool/call`/`tool/result` events pair by it. `usage` is
|
|
241
|
+
* the API call's own accounting (claude reports it inline on every
|
|
242
|
+
* assistant event): it rides the call's LAST folded line — a tool-only
|
|
243
|
+
* call's lands on the tool line's advertising message. `messageId` groups
|
|
244
|
+
* the per-block events of ONE API call (claude emits one assistant event
|
|
245
|
+
* per content block, each repeating the message's usage).
|
|
215
246
|
*/
|
|
216
247
|
| {
|
|
217
248
|
kind: 'tool';
|
|
@@ -219,12 +250,21 @@ export type ClaudeTranscriptLine = {
|
|
|
219
250
|
name: string;
|
|
220
251
|
args?: string;
|
|
221
252
|
result?: string;
|
|
253
|
+
messageId?: string;
|
|
254
|
+
usage?: TokenUsage;
|
|
222
255
|
};
|
|
256
|
+
/** Group the lines of one API call (consecutive lines sharing a message id).
|
|
257
|
+
* Lines without an id stay singleton units (the pre-grouping shape). */
|
|
258
|
+
export declare function groupClaudeTranscriptLines(lines: readonly ClaudeTranscriptLine[]): ClaudeTranscriptLine[][];
|
|
223
259
|
/** Mutable fold state shared by the batch parse and the incremental parser. */
|
|
224
260
|
interface ClaudeStreamFoldState {
|
|
225
261
|
readonly lines: ClaudeTranscriptLine[];
|
|
226
262
|
/** tool_use id → transcript line index, so a result pairs with its own call. */
|
|
227
263
|
readonly callsById: Map<string, number>;
|
|
264
|
+
/** message id → the line index its usage currently rides (per-call dedupe:
|
|
265
|
+
* claude repeats one call's usage on EVERY per-block assistant event, and
|
|
266
|
+
* only the call's last line may keep it). */
|
|
267
|
+
readonly usageStamped: Map<string, number>;
|
|
228
268
|
text: string | undefined;
|
|
229
269
|
usage: TokenUsage | undefined;
|
|
230
270
|
sessionId: string | undefined;
|
|
@@ -302,6 +342,7 @@ export declare class ClaudeStreamParser implements ClaudeStreamFoldState {
|
|
|
302
342
|
private buffer;
|
|
303
343
|
readonly lines: ClaudeTranscriptLine[];
|
|
304
344
|
readonly callsById: Map<string, number>;
|
|
345
|
+
readonly usageStamped: Map<string, number>;
|
|
305
346
|
text: string | undefined;
|
|
306
347
|
usage: TokenUsage | undefined;
|
|
307
348
|
sessionId: string | undefined;
|
|
@@ -347,6 +388,17 @@ export declare function parseClaudeStreamJson(output: string): {
|
|
|
347
388
|
};
|
|
348
389
|
/** The placeholder think line for a `redacted_thinking` block (content is server-encrypted by design). */
|
|
349
390
|
export declare const REDACTED_THINKING_TEXT = "\uFF08\u601D\u8003\u5185\u5BB9\u5DF2\u7531\u670D\u52A1\u7AEF\u9690\u85CF\uFF1Aredacted_thinking\uFF0C\u5185\u5BB9\u6309\u8BBE\u8BA1\u4E0D\u53EF\u89C1\uFF0C\u6B64\u884C\u4EC5\u6807\u793A\u5B83\u5B58\u5728\uFF09";
|
|
391
|
+
/**
|
|
392
|
+
* Map claude's usage payload onto the shared usage contract. Claude's
|
|
393
|
+
* `input_tokens` is the uncached input; cache reads and cache creation are
|
|
394
|
+
* reported separately, so each maps to its own bucket with no subtraction.
|
|
395
|
+
* When the payload carries ANY cache field, `cacheReadTokens` is always
|
|
396
|
+
* written (0 when the read counter is absent or zero) — a reader can then
|
|
397
|
+
* tell "no hits" from "not reported".
|
|
398
|
+
* @param usage - the raw claude usage object.
|
|
399
|
+
* @returns the shared usage record.
|
|
400
|
+
*/
|
|
401
|
+
export declare function usageFromClaude(usage: unknown): TokenUsage;
|
|
350
402
|
/**
|
|
351
403
|
* Start the real `claude -p` child and publish its run. The claude
|
|
352
404
|
* result arrives as an NDJSON event stream on stdout (`--verbose
|
|
@@ -362,6 +414,17 @@ export declare const REDACTED_THINKING_TEXT = "\uFF08\u601D\u8003\u5185\u5BB9\u5
|
|
|
362
414
|
*/
|
|
363
415
|
export declare function startClaudeCliRun(request: SubagentStartRequest, spec: ClaudeCliRunSpec): Promise<SubagentRun>;
|
|
364
416
|
/** One assistant-role message event, attributed to the claude route. */
|
|
417
|
+
/**
|
|
418
|
+
* Write the round's request/header when the config differs from the child
|
|
419
|
+
* log's last one (the host logs changed snapshots, not per-call duplicates):
|
|
420
|
+
* the first write is `initial`, a differing one `change`, an identical one
|
|
421
|
+
* skipped. Context Lens reads the child log's config from these headers.
|
|
422
|
+
*/
|
|
423
|
+
export declare function appendClaudeRequestHeader(childSession: Session, config: {
|
|
424
|
+
provider: string;
|
|
425
|
+
model: string;
|
|
426
|
+
reasoningEffort?: ReasoningEffortId;
|
|
427
|
+
}): void;
|
|
365
428
|
export declare function assistantEvent(blocks: readonly ContentBlock[]): import("@deepseek-ai/dsh-llm").AssistantMessage;
|
|
366
429
|
/**
|
|
367
430
|
* Fold one transcript line into the child session as one assistant step,
|
|
@@ -371,10 +434,27 @@ export declare function assistantEvent(blocks: readonly ContentBlock[]): import(
|
|
|
371
434
|
* the real-time view renders nothing (only a full rebuild, which mints step
|
|
372
435
|
* drafts from the explicit coordinates, recovers it). Tool cards escape that
|
|
373
436
|
* fate only because their definition does not consult the step location.
|
|
437
|
+
*
|
|
438
|
+
* A tool line folds the native lifecycle inside its one step: an assistant
|
|
439
|
+
* message advertising the tool-call block, the `tool/call`, and its
|
|
440
|
+
* `tool/result` — the released-log reader pairs call and result against the
|
|
441
|
+
* advertisement and resolves every advertised call before the step closes, so
|
|
442
|
+
* a line whose result the stream has not recorded yet must NOT reach this
|
|
443
|
+
* fold mid-round (the callers hold there; the result merges into the call's
|
|
444
|
+
* line in place, so a later pass sees it). A line still unresulted at settle
|
|
445
|
+
* folds with the interrupted placeholder ({@link CLAUDE_INTERRUPTED_TOOL_RESULT}).
|
|
374
446
|
*/
|
|
375
447
|
export declare function appendClaudeTranscriptLine(childSession: Session, turn: number, step: number, line: ClaudeTranscriptLine, usage: TokenUsage | undefined): void;
|
|
376
448
|
/** The delta-progress text for one transcript line. */
|
|
377
449
|
export declare function claudeLineText(line: ClaudeTranscriptLine): string;
|
|
450
|
+
/**
|
|
451
|
+
* Fold one API call (a message-id group) into the child session as ONE
|
|
452
|
+
* assistant step: a single assistant/message carrying the call's reasoning,
|
|
453
|
+
* text and tool-call blocks (the host's own mixed-content shape), then each
|
|
454
|
+
* call's native lifecycle, then step/end. The call's usage rides the message
|
|
455
|
+
* once — the group's own per-call stamp wins over the round-total fallback.
|
|
456
|
+
*/
|
|
457
|
+
export declare function appendClaudeTranscriptGroup(childSession: Session, turn: number, step: number, group: readonly ClaudeTranscriptLine[], usage: TokenUsage | undefined): void;
|
|
378
458
|
/**
|
|
379
459
|
* Persist the child session's mirrored events. Thin wrapper over the core's
|
|
380
460
|
* {@link persistChildSession}: a live session syncs through the core's cached
|