dsh-agy-cli 0.0.0-stage → 0.12.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/LICENSE +30 -0
- package/README.en.md +27 -0
- package/README.md +94 -2
- package/agents/dsh-agy-image-view.md +17 -0
- package/agents/dsh-agy-mcp-executor.md +32 -0
- package/agents/dsh-agy-read-only.md +20 -0
- package/agents/dsh-agy-tool-free.md +16 -0
- package/agents/dsh-agy-workspace-write.md +23 -0
- package/bin/dsh-agy-cli.js +9 -0
- package/bin/win32-x64/agy-launcher.exe +0 -0
- package/cordis.patch.yml +16 -0
- package/dist/client.js +4259 -0
- package/lib/agent-installer.d.ts +66 -0
- package/lib/agent-installer.js +147 -0
- package/lib/agent-presets.d.ts +42 -0
- package/lib/agent-presets.js +130 -0
- package/lib/agents-cli.d.ts +3 -0
- package/lib/agents-cli.js +110 -0
- package/lib/agy/diagnostics.d.ts +29 -0
- package/lib/agy/diagnostics.js +109 -0
- package/lib/agy/errors.d.ts +20 -0
- package/lib/agy/errors.js +77 -0
- package/lib/agy/experimental-transport.d.ts +79 -0
- package/lib/agy/experimental-transport.js +612 -0
- package/lib/agy/keepalive.d.ts +140 -0
- package/lib/agy/keepalive.js +424 -0
- package/lib/agy/limiter.d.ts +32 -0
- package/lib/agy/limiter.js +111 -0
- package/lib/agy/log.d.ts +214 -0
- package/lib/agy/log.js +503 -0
- package/lib/agy/models.d.ts +49 -0
- package/lib/agy/models.js +203 -0
- package/lib/agy/overrides.d.ts +17 -0
- package/lib/agy/overrides.js +73 -0
- package/lib/agy/parser.d.ts +102 -0
- package/lib/agy/parser.js +492 -0
- package/lib/agy/persistent-transport.d.ts +101 -0
- package/lib/agy/persistent-transport.js +753 -0
- package/lib/agy/process.d.ts +144 -0
- package/lib/agy/process.js +452 -0
- package/lib/agy/redact.d.ts +3 -0
- package/lib/agy/redact.js +24 -0
- package/lib/agy/stream-protocol.d.ts +50 -0
- package/lib/agy/stream-protocol.js +156 -0
- package/lib/agy/windows-launcher.d.ts +21 -0
- package/lib/agy/windows-launcher.js +76 -0
- package/lib/diagnostics.d.ts +78 -0
- package/lib/diagnostics.js +162 -0
- package/lib/doctor.d.ts +138 -0
- package/lib/doctor.js +923 -0
- package/lib/dsh/context.d.ts +133 -0
- package/lib/dsh/context.js +352 -0
- package/lib/dsh-home.d.ts +6 -0
- package/lib/dsh-home.js +11 -0
- package/lib/index.d.ts +43 -0
- package/lib/index.js +256 -0
- package/lib/mcp/agy-registration.d.ts +70 -0
- package/lib/mcp/agy-registration.js +245 -0
- package/lib/mcp/bridge.d.ts +73 -0
- package/lib/mcp/bridge.js +295 -0
- package/lib/mcp/endpoint.d.ts +41 -0
- package/lib/mcp/endpoint.js +142 -0
- package/lib/mcp/protocol.d.ts +107 -0
- package/lib/mcp/protocol.js +197 -0
- package/lib/mcp/tool-projection.d.ts +64 -0
- package/lib/mcp/tool-projection.js +168 -0
- package/lib/provider/agy.d.ts +153 -0
- package/lib/provider/agy.js +2159 -0
- package/lib/provider/config.d.ts +226 -0
- package/lib/provider/config.js +294 -0
- package/lib/provider/error-codes.d.ts +22 -0
- package/lib/provider/error-codes.js +29 -0
- package/lib/provider/image-bridge.d.ts +60 -0
- package/lib/provider/image-bridge.js +290 -0
- package/lib/provider/mock.d.ts +15 -0
- package/lib/provider/mock.js +78 -0
- package/lib/provider/prompt-budget.d.ts +45 -0
- package/lib/provider/prompt-budget.js +596 -0
- package/lib/provider/serialize.d.ts +15 -0
- package/lib/provider/serialize.js +82 -0
- package/lib/provider/tool-protocol.d.ts +80 -0
- package/lib/provider/tool-protocol.js +848 -0
- package/lib/provider/tool-schema-file.d.ts +11 -0
- package/lib/provider/tool-schema-file.js +27 -0
- package/lib/session/file-store.d.ts +56 -0
- package/lib/session/file-store.js +186 -0
- package/lib/session/store.d.ts +49 -0
- package/lib/session/store.js +62 -0
- package/lib/web/router.d.ts +19 -0
- package/lib/web/router.js +906 -0
- package/package.json +112 -4
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { CONTEXT_WINDOW_EXCEEDED_CODE, QUOTA_EXCEEDED_CODE } from '@deepseek-ai/dsh-llm';
|
|
2
|
+
import { redactText } from './redact.js';
|
|
3
|
+
// Billing/account-level failure wording: no amount of waiting helps, the caller
|
|
4
|
+
// must stop and surface it. Kept separate from the drained-bucket pattern below
|
|
5
|
+
// because the two deserve opposite treatment (fail-closed vs bounded retry).
|
|
6
|
+
const ACCOUNT_QUOTA_WORDS = /quota|credit|balance|billing|budget|usage\s+limit|limit\s+(?:exceeded|reached)/i;
|
|
7
|
+
// Wording that means "the 5h/weekly bucket is drained" rather than a billing
|
|
8
|
+
// failure. The distinction is load-bearing: a drained bucket is retryable (it
|
|
9
|
+
// sits on a boundary value where ~1 in 5 attempts succeeds, and the window
|
|
10
|
+
// resets on its own), while a billing failure never clears by waiting.
|
|
11
|
+
// "Individual quota reached. … Resets in 96h12m27s" → bucket drained, resets on the window
|
|
12
|
+
// "Resource has been exhausted (e.g. check quota)." → burst/rate limit, no reset hint
|
|
13
|
+
// Peer references (same rule, independently derived):
|
|
14
|
+
// OmniRoute open-sse/services/antigravity429Engine.ts QUOTA_EXHAUSTED_KEYWORDS
|
|
15
|
+
// = ['quota_exhausted','quota exhausted','quota reached','enable overages','individual quota']
|
|
16
|
+
// plus `/\breset\s+(?:after|in)\s+0s\b/` → rate_limited
|
|
17
|
+
// chaos-03x dsh-agy src/runtime/classify.ts:93-119 QUOTA_EXHAUSTED_KEYWORDS
|
|
18
|
+
// Deliberately narrow: `limit\s+(?:exceeded|reached)` needs a neighbouring word
|
|
19
|
+
// that ties it to a window (quota/usage/weekly/5-hour) so that
|
|
20
|
+
// "billing budget limit reached" stays a billing failure. Over-broad matching
|
|
21
|
+
// produced ghost cooldowns in agy-link (repo_amlyczz__dsh-agy-link
|
|
22
|
+
// src/common/types.ts:320).
|
|
23
|
+
const DRAINED_QUOTA_WORDS = /(?:quota|usage|weekly|5[-\s]?hour)[-\s]*(?:limit|limits)\s+(?:reached|exceeded)|limit\s+(?:reached|exceeded)\s+(?:for|on)\s+(?:quota|usage|weekly|5[-\s]?hour)|individual\s+quota|quota\s+(?:reached|exhausted)|out\s+of\s+quota|insufficient\s+quota/i;
|
|
24
|
+
const RESETS_IMMEDIATELY = /\breset\s+(?:after|in)\s+0s\b/i;
|
|
25
|
+
/**
|
|
26
|
+
* Classify observed AGY status/stderr/error-event detail. This is deliberately
|
|
27
|
+
* conservative: unknown text keeps the caller-supplied fallback code.
|
|
28
|
+
*
|
|
29
|
+
* Note the ordering is load-bearing for 429s. AGY emits
|
|
30
|
+
* `RESOURCE_EXHAUSTED (code 429)` for both a drained 5h/weekly bucket and a
|
|
31
|
+
* transient burst limit; only the drained form names a reset far in the future.
|
|
32
|
+
* The drained form is reported as RATE_LIMIT so the bounded retry in
|
|
33
|
+
* `dsh-llm-retry` can re-issue the turn — live probes showed the bucket sits on
|
|
34
|
+
* a boundary value where 1 in 5 attempts succeeds (probe_retry_efficacy.mjs:
|
|
35
|
+
* 5/5 rounds recovered, 2-3 attempts each), while a 92-96h reset means retrying
|
|
36
|
+
* beyond a few attempts is pure token burn.
|
|
37
|
+
*/
|
|
38
|
+
export function classifyAgyFailure(detail, fallback) {
|
|
39
|
+
const value = detail.trim().slice(0, 2_048);
|
|
40
|
+
if (value.length === 0)
|
|
41
|
+
return fallback;
|
|
42
|
+
if (/(?:context(?:\s+window)?|prompt|input).{0,48}(?:too\s+(?:long|large)|exceed|maximum|limit)|(?:maximum|limit).{0,48}(?:context|prompt|input)/i.test(value)) {
|
|
43
|
+
return CONTEXT_WINDOW_EXCEEDED_CODE;
|
|
44
|
+
}
|
|
45
|
+
if (ACCOUNT_QUOTA_WORDS.test(value) && !DRAINED_QUOTA_WORDS.test(value)) {
|
|
46
|
+
return QUOTA_EXCEEDED_CODE;
|
|
47
|
+
}
|
|
48
|
+
// A drained-bucket 429 that promises an immediate reset is really a burst limit.
|
|
49
|
+
if (DRAINED_QUOTA_WORDS.test(value) && !RESETS_IMMEDIATELY.test(value))
|
|
50
|
+
return 'RATE_LIMIT';
|
|
51
|
+
if (/(?:rate\s*limit|too\s+many\s+requests|throttl|\b429\b)/i.test(value))
|
|
52
|
+
return 'RATE_LIMIT';
|
|
53
|
+
// Transport-layer flakes: the local proxy or the upstream edge cuts the
|
|
54
|
+
// connection mid-request. AGY itself labels these `"retryable": true` in its
|
|
55
|
+
// AGY_ERROR trailer; honoring that keeps a transient blip from killing the
|
|
56
|
+
// whole turn (observed: `wsarecv`/`EOF` against 127.0.0.1:12450 on exit 3).
|
|
57
|
+
if (/"retryable"\s*:\s*true/i.test(value))
|
|
58
|
+
return 'TRANSPORT';
|
|
59
|
+
if (/\bEOF\b|wsarecv|forcibly\s+closed|connection\s+(?:reset|aborted|closed)|broken\s+pipe|EPIPE|ECONNRESET|stream\s+was\s+interrupted/i.test(value)) {
|
|
60
|
+
return 'TRANSPORT';
|
|
61
|
+
}
|
|
62
|
+
if (/(?:model|deployment).{0,48}(?:not\s+found|unknown|invalid|unavailable|does\s+not\s+exist)|no\s+such\s+model/i.test(value)) {
|
|
63
|
+
return 'MODEL_NOT_FOUND';
|
|
64
|
+
}
|
|
65
|
+
if (/(?:agent|profile).{0,48}(?:not\s+found|unknown|missing|invalid)/i.test(value))
|
|
66
|
+
return 'AGY_AGENT_MISSING';
|
|
67
|
+
if (/(?:unauthori[sz]ed|not\s+authenticated|authentication|login|sign[\s-]+in|invalid\s+credential|expired\s+token|invalid\s+token|access\s+denied|forbidden)/i.test(value)) {
|
|
68
|
+
return 'AUTH';
|
|
69
|
+
}
|
|
70
|
+
return fallback;
|
|
71
|
+
}
|
|
72
|
+
/** Keep user-facing failure text bounded and redacted; structured logs use only the code. */
|
|
73
|
+
export function safeAgyFailureMessage(prefix, detail) {
|
|
74
|
+
const safeDetail = detail === undefined ? '' : redactText(detail.trim(), 512);
|
|
75
|
+
return safeDetail.length === 0 ? prefix : `${prefix}: ${safeDetail}`;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export type PersistentTransportErrorCode = 'ABORTED' | 'DISPOSED' | 'EVENT_HANDLER_FAILED' | 'FRAME_TOO_LARGE' | 'PROTOCOL_ERROR' | 'TIMEOUT' | 'WORKER_BUSY' | 'WORKER_CRASHED' | 'WORKER_ERROR' | 'WORKER_LIMIT' | 'WORKER_START_FAILED' | 'WORKER_STOPPED' | 'OUTPUT_LIMIT';
|
|
2
|
+
export declare class PersistentTransportError extends Error {
|
|
3
|
+
readonly code: PersistentTransportErrorCode;
|
|
4
|
+
constructor(message: string, code: PersistentTransportErrorCode, options?: ErrorOptions);
|
|
5
|
+
}
|
|
6
|
+
export type PersistentWorkerState = 'starting' | 'idle' | 'busy' | 'stopping' | 'stopped';
|
|
7
|
+
export interface PersistentRequestFrame {
|
|
8
|
+
readonly kind: 'request';
|
|
9
|
+
readonly requestId: string;
|
|
10
|
+
readonly sessionId: string;
|
|
11
|
+
readonly payload: unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface PersistentShutdownFrame {
|
|
14
|
+
readonly kind: 'shutdown';
|
|
15
|
+
}
|
|
16
|
+
export type PersistentOutgoingFrame = PersistentRequestFrame | PersistentShutdownFrame;
|
|
17
|
+
export interface PersistentIncomingFrame {
|
|
18
|
+
readonly kind: 'ready' | 'event' | 'complete' | 'error';
|
|
19
|
+
readonly requestId?: string;
|
|
20
|
+
readonly sessionId?: string;
|
|
21
|
+
readonly payload?: unknown;
|
|
22
|
+
readonly message?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface PersistentTransportRequest {
|
|
25
|
+
readonly sessionId: string;
|
|
26
|
+
readonly payload: unknown;
|
|
27
|
+
readonly signal?: AbortSignal;
|
|
28
|
+
readonly timeoutMs?: number;
|
|
29
|
+
readonly maxOutputBytes?: number;
|
|
30
|
+
readonly onEvent?: (payload: unknown) => void;
|
|
31
|
+
}
|
|
32
|
+
export interface PersistentTransportResult {
|
|
33
|
+
readonly requestId: string;
|
|
34
|
+
readonly sessionId: string;
|
|
35
|
+
readonly events: readonly unknown[];
|
|
36
|
+
readonly durationMs: number;
|
|
37
|
+
readonly firstEventMs?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface ExperimentalAgyTransportOptions {
|
|
40
|
+
readonly executable: string;
|
|
41
|
+
readonly args?: readonly string[];
|
|
42
|
+
readonly cwd?: string;
|
|
43
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
44
|
+
readonly maxWorkers?: number;
|
|
45
|
+
readonly maxFrameBytes?: number;
|
|
46
|
+
readonly maxOutputBytes?: number;
|
|
47
|
+
readonly maxStderrBytes?: number;
|
|
48
|
+
readonly idleTtlMs?: number;
|
|
49
|
+
readonly readyTimeoutMs?: number;
|
|
50
|
+
readonly shutdownTimeoutMs?: number;
|
|
51
|
+
readonly defaultRequestTimeoutMs?: number;
|
|
52
|
+
}
|
|
53
|
+
export interface PersistentTransportStats {
|
|
54
|
+
readonly totalWorkers: number;
|
|
55
|
+
readonly startingWorkers: number;
|
|
56
|
+
readonly idleWorkers: number;
|
|
57
|
+
readonly busyWorkers: number;
|
|
58
|
+
readonly stoppingWorkers: number;
|
|
59
|
+
readonly maxWorkers: number;
|
|
60
|
+
readonly disposed: boolean;
|
|
61
|
+
}
|
|
62
|
+
/** Encode one bounded NDJSON frame, including its trailing newline. */
|
|
63
|
+
export declare function encodePersistentFrame(frame: PersistentOutgoingFrame, maxFrameBytes: number): string;
|
|
64
|
+
/** Parse and validate the small protocol envelope; payload remains opaque. */
|
|
65
|
+
export declare function parsePersistentFrame(line: string): PersistentIncomingFrame;
|
|
66
|
+
/**
|
|
67
|
+
* Experimental worker-per-session transport. It is intentionally not wired
|
|
68
|
+
* into AgyAdapter; callers must opt into this prototype directly.
|
|
69
|
+
*/
|
|
70
|
+
export declare class ExperimentalAgyTransport {
|
|
71
|
+
private readonly options;
|
|
72
|
+
private readonly workers;
|
|
73
|
+
private disposed;
|
|
74
|
+
constructor(options: ExperimentalAgyTransportOptions);
|
|
75
|
+
request(input: PersistentTransportRequest): Promise<PersistentTransportResult>;
|
|
76
|
+
dispose(): Promise<void>;
|
|
77
|
+
getStats(): PersistentTransportStats;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=experimental-transport.d.ts.map
|