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.
Files changed (91) hide show
  1. package/LICENSE +30 -0
  2. package/README.en.md +27 -0
  3. package/README.md +94 -2
  4. package/agents/dsh-agy-image-view.md +17 -0
  5. package/agents/dsh-agy-mcp-executor.md +32 -0
  6. package/agents/dsh-agy-read-only.md +20 -0
  7. package/agents/dsh-agy-tool-free.md +16 -0
  8. package/agents/dsh-agy-workspace-write.md +23 -0
  9. package/bin/dsh-agy-cli.js +9 -0
  10. package/bin/win32-x64/agy-launcher.exe +0 -0
  11. package/cordis.patch.yml +16 -0
  12. package/dist/client.js +4259 -0
  13. package/lib/agent-installer.d.ts +66 -0
  14. package/lib/agent-installer.js +147 -0
  15. package/lib/agent-presets.d.ts +42 -0
  16. package/lib/agent-presets.js +130 -0
  17. package/lib/agents-cli.d.ts +3 -0
  18. package/lib/agents-cli.js +110 -0
  19. package/lib/agy/diagnostics.d.ts +29 -0
  20. package/lib/agy/diagnostics.js +109 -0
  21. package/lib/agy/errors.d.ts +20 -0
  22. package/lib/agy/errors.js +77 -0
  23. package/lib/agy/experimental-transport.d.ts +79 -0
  24. package/lib/agy/experimental-transport.js +612 -0
  25. package/lib/agy/keepalive.d.ts +140 -0
  26. package/lib/agy/keepalive.js +424 -0
  27. package/lib/agy/limiter.d.ts +32 -0
  28. package/lib/agy/limiter.js +111 -0
  29. package/lib/agy/log.d.ts +214 -0
  30. package/lib/agy/log.js +503 -0
  31. package/lib/agy/models.d.ts +49 -0
  32. package/lib/agy/models.js +203 -0
  33. package/lib/agy/overrides.d.ts +17 -0
  34. package/lib/agy/overrides.js +73 -0
  35. package/lib/agy/parser.d.ts +102 -0
  36. package/lib/agy/parser.js +492 -0
  37. package/lib/agy/persistent-transport.d.ts +101 -0
  38. package/lib/agy/persistent-transport.js +753 -0
  39. package/lib/agy/process.d.ts +144 -0
  40. package/lib/agy/process.js +452 -0
  41. package/lib/agy/redact.d.ts +3 -0
  42. package/lib/agy/redact.js +24 -0
  43. package/lib/agy/stream-protocol.d.ts +50 -0
  44. package/lib/agy/stream-protocol.js +156 -0
  45. package/lib/agy/windows-launcher.d.ts +21 -0
  46. package/lib/agy/windows-launcher.js +76 -0
  47. package/lib/diagnostics.d.ts +78 -0
  48. package/lib/diagnostics.js +162 -0
  49. package/lib/doctor.d.ts +138 -0
  50. package/lib/doctor.js +923 -0
  51. package/lib/dsh/context.d.ts +133 -0
  52. package/lib/dsh/context.js +352 -0
  53. package/lib/dsh-home.d.ts +6 -0
  54. package/lib/dsh-home.js +11 -0
  55. package/lib/index.d.ts +43 -0
  56. package/lib/index.js +256 -0
  57. package/lib/mcp/agy-registration.d.ts +70 -0
  58. package/lib/mcp/agy-registration.js +245 -0
  59. package/lib/mcp/bridge.d.ts +73 -0
  60. package/lib/mcp/bridge.js +295 -0
  61. package/lib/mcp/endpoint.d.ts +41 -0
  62. package/lib/mcp/endpoint.js +142 -0
  63. package/lib/mcp/protocol.d.ts +107 -0
  64. package/lib/mcp/protocol.js +197 -0
  65. package/lib/mcp/tool-projection.d.ts +64 -0
  66. package/lib/mcp/tool-projection.js +168 -0
  67. package/lib/provider/agy.d.ts +153 -0
  68. package/lib/provider/agy.js +2159 -0
  69. package/lib/provider/config.d.ts +226 -0
  70. package/lib/provider/config.js +294 -0
  71. package/lib/provider/error-codes.d.ts +22 -0
  72. package/lib/provider/error-codes.js +29 -0
  73. package/lib/provider/image-bridge.d.ts +60 -0
  74. package/lib/provider/image-bridge.js +290 -0
  75. package/lib/provider/mock.d.ts +15 -0
  76. package/lib/provider/mock.js +78 -0
  77. package/lib/provider/prompt-budget.d.ts +45 -0
  78. package/lib/provider/prompt-budget.js +596 -0
  79. package/lib/provider/serialize.d.ts +15 -0
  80. package/lib/provider/serialize.js +82 -0
  81. package/lib/provider/tool-protocol.d.ts +80 -0
  82. package/lib/provider/tool-protocol.js +848 -0
  83. package/lib/provider/tool-schema-file.d.ts +11 -0
  84. package/lib/provider/tool-schema-file.js +27 -0
  85. package/lib/session/file-store.d.ts +56 -0
  86. package/lib/session/file-store.js +186 -0
  87. package/lib/session/store.d.ts +49 -0
  88. package/lib/session/store.js +62 -0
  89. package/lib/web/router.d.ts +19 -0
  90. package/lib/web/router.js +906 -0
  91. 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