@the-open-engine/zeroshot 5.4.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 +539 -0
- package/LICENSE +21 -0
- package/README.md +508 -0
- package/cli/commands/inspect-render.js +135 -0
- package/cli/commands/inspect.js +294 -0
- package/cli/commands/providers.js +149 -0
- package/cli/index.js +5431 -0
- package/cli/lib/first-run.js +211 -0
- package/cli/lib/update-checker.js +281 -0
- package/cli/message-formatter-utils.js +75 -0
- package/cli/message-formatters-normal.js +275 -0
- package/cli/message-formatters-watch.js +185 -0
- package/cluster-templates/base-templates/debug-workflow.json +422 -0
- package/cluster-templates/base-templates/full-workflow.json +727 -0
- package/cluster-templates/base-templates/heavy-validation.json +272 -0
- package/cluster-templates/base-templates/quick-validation.json +285 -0
- package/cluster-templates/base-templates/single-worker.json +71 -0
- package/cluster-templates/base-templates/worker-validator.json +230 -0
- package/cluster-templates/conductor-bootstrap.json +130 -0
- package/docker/zeroshot-cluster/Dockerfile +153 -0
- package/docker/zeroshot-cluster/pre-baked-deps.json +28 -0
- package/lib/agent-cli-provider/adapters/claude-parser.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/claude-parser.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/claude-parser.js +122 -0
- package/lib/agent-cli-provider/adapters/claude-parser.js.map +1 -0
- package/lib/agent-cli-provider/adapters/claude-recovery.d.ts +15 -0
- package/lib/agent-cli-provider/adapters/claude-recovery.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/claude-recovery.js +165 -0
- package/lib/agent-cli-provider/adapters/claude-recovery.js.map +1 -0
- package/lib/agent-cli-provider/adapters/claude.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/claude.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/claude.js +181 -0
- package/lib/agent-cli-provider/adapters/claude.js.map +1 -0
- package/lib/agent-cli-provider/adapters/codex-parser.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/codex-parser.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/codex-parser.js +192 -0
- package/lib/agent-cli-provider/adapters/codex-parser.js.map +1 -0
- package/lib/agent-cli-provider/adapters/codex.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/codex.js +151 -0
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -0
- package/lib/agent-cli-provider/adapters/common.d.ts +28 -0
- package/lib/agent-cli-provider/adapters/common.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/common.js +71 -0
- package/lib/agent-cli-provider/adapters/common.js.map +1 -0
- package/lib/agent-cli-provider/adapters/gemini.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/gemini.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/gemini.js +176 -0
- package/lib/agent-cli-provider/adapters/gemini.js.map +1 -0
- package/lib/agent-cli-provider/adapters/index.d.ts +9 -0
- package/lib/agent-cli-provider/adapters/index.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/index.js +95 -0
- package/lib/agent-cli-provider/adapters/index.js.map +1 -0
- package/lib/agent-cli-provider/adapters/opencode.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/opencode.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/opencode.js +228 -0
- package/lib/agent-cli-provider/adapters/opencode.js.map +1 -0
- package/lib/agent-cli-provider/contract-actions.d.ts +5 -0
- package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-actions.js +140 -0
- package/lib/agent-cli-provider/contract-actions.js.map +1 -0
- package/lib/agent-cli-provider/contract-env.d.ts +11 -0
- package/lib/agent-cli-provider/contract-env.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-env.js +113 -0
- package/lib/agent-cli-provider/contract-env.js.map +1 -0
- package/lib/agent-cli-provider/contract-envelope.d.ts +49 -0
- package/lib/agent-cli-provider/contract-envelope.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-envelope.js +52 -0
- package/lib/agent-cli-provider/contract-envelope.js.map +1 -0
- package/lib/agent-cli-provider/contract-errors.d.ts +22 -0
- package/lib/agent-cli-provider/contract-errors.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-errors.js +71 -0
- package/lib/agent-cli-provider/contract-errors.js.map +1 -0
- package/lib/agent-cli-provider/contract-fallback.d.ts +7 -0
- package/lib/agent-cli-provider/contract-fallback.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-fallback.js +102 -0
- package/lib/agent-cli-provider/contract-fallback.js.map +1 -0
- package/lib/agent-cli-provider/contract-invoke.d.ts +5 -0
- package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-invoke.js +89 -0
- package/lib/agent-cli-provider/contract-invoke.js.map +1 -0
- package/lib/agent-cli-provider/contract-options.d.ts +3 -0
- package/lib/agent-cli-provider/contract-options.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-options.js +140 -0
- package/lib/agent-cli-provider/contract-options.js.map +1 -0
- package/lib/agent-cli-provider/contract-parse.d.ts +15 -0
- package/lib/agent-cli-provider/contract-parse.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-parse.js +81 -0
- package/lib/agent-cli-provider/contract-parse.js.map +1 -0
- package/lib/agent-cli-provider/contract-support.d.ts +18 -0
- package/lib/agent-cli-provider/contract-support.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract-support.js +154 -0
- package/lib/agent-cli-provider/contract-support.js.map +1 -0
- package/lib/agent-cli-provider/contract.d.ts +13 -0
- package/lib/agent-cli-provider/contract.d.ts.map +1 -0
- package/lib/agent-cli-provider/contract.js +30 -0
- package/lib/agent-cli-provider/contract.js.map +1 -0
- package/lib/agent-cli-provider/env-safety.d.ts +11 -0
- package/lib/agent-cli-provider/env-safety.d.ts.map +1 -0
- package/lib/agent-cli-provider/env-safety.js +83 -0
- package/lib/agent-cli-provider/env-safety.js.map +1 -0
- package/lib/agent-cli-provider/errors.d.ts +5 -0
- package/lib/agent-cli-provider/errors.d.ts.map +1 -0
- package/lib/agent-cli-provider/errors.js +115 -0
- package/lib/agent-cli-provider/errors.js.map +1 -0
- package/lib/agent-cli-provider/executable.d.ts +3 -0
- package/lib/agent-cli-provider/executable.d.ts.map +1 -0
- package/lib/agent-cli-provider/executable.js +24 -0
- package/lib/agent-cli-provider/executable.js.map +1 -0
- package/lib/agent-cli-provider/index.d.ts +8 -0
- package/lib/agent-cli-provider/index.d.ts.map +1 -0
- package/lib/agent-cli-provider/index.js +31 -0
- package/lib/agent-cli-provider/index.js.map +1 -0
- package/lib/agent-cli-provider/invoke-evidence.d.ts +4 -0
- package/lib/agent-cli-provider/invoke-evidence.d.ts.map +1 -0
- package/lib/agent-cli-provider/invoke-evidence.js +17 -0
- package/lib/agent-cli-provider/invoke-evidence.js.map +1 -0
- package/lib/agent-cli-provider/json.d.ts +16 -0
- package/lib/agent-cli-provider/json.d.ts.map +1 -0
- package/lib/agent-cli-provider/json.js +110 -0
- package/lib/agent-cli-provider/json.js.map +1 -0
- package/lib/agent-cli-provider/log-prefix.d.ts +2 -0
- package/lib/agent-cli-provider/log-prefix.d.ts.map +1 -0
- package/lib/agent-cli-provider/log-prefix.js +22 -0
- package/lib/agent-cli-provider/log-prefix.js.map +1 -0
- package/lib/agent-cli-provider/process-runner.d.ts +17 -0
- package/lib/agent-cli-provider/process-runner.d.ts.map +1 -0
- package/lib/agent-cli-provider/process-runner.js +89 -0
- package/lib/agent-cli-provider/process-runner.js.map +1 -0
- package/lib/agent-cli-provider/redaction.d.ts +9 -0
- package/lib/agent-cli-provider/redaction.d.ts.map +1 -0
- package/lib/agent-cli-provider/redaction.js +227 -0
- package/lib/agent-cli-provider/redaction.js.map +1 -0
- package/lib/agent-cli-provider/schema.d.ts +5 -0
- package/lib/agent-cli-provider/schema.d.ts.map +1 -0
- package/lib/agent-cli-provider/schema.js +136 -0
- package/lib/agent-cli-provider/schema.js.map +1 -0
- package/lib/agent-cli-provider/single-agent-runtime.d.ts +15 -0
- package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -0
- package/lib/agent-cli-provider/single-agent-runtime.js +228 -0
- package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -0
- package/lib/agent-cli-provider/types.d.ts +194 -0
- package/lib/agent-cli-provider/types.d.ts.map +1 -0
- package/lib/agent-cli-provider/types.js +12 -0
- package/lib/agent-cli-provider/types.js.map +1 -0
- package/lib/completion.js +174 -0
- package/lib/detached-startup.js +220 -0
- package/lib/docker-config.js +220 -0
- package/lib/git-remote-utils.js +165 -0
- package/lib/id-detector.js +55 -0
- package/lib/provider-defaults.js +62 -0
- package/lib/provider-detection.js +59 -0
- package/lib/provider-names.js +57 -0
- package/lib/repo-settings.js +69 -0
- package/lib/settings/claude-auth.js +78 -0
- package/lib/settings.js +542 -0
- package/lib/start-cluster.js +321 -0
- package/lib/stream-json-parser.js +67 -0
- package/package.json +162 -0
- package/scripts/fix-node-pty-permissions.js +75 -0
- package/scripts/record-demo.sh +279 -0
- package/scripts/setup-merge-queue.sh +170 -0
- package/scripts/test-install.sh +40 -0
- package/scripts/validate-templates.js +107 -0
- package/src/agent/agent-config.js +266 -0
- package/src/agent/agent-context-builder.js +189 -0
- package/src/agent/agent-context-sections.js +338 -0
- package/src/agent/agent-context-sources.js +147 -0
- package/src/agent/agent-hook-executor.js +721 -0
- package/src/agent/agent-input-injector.js +141 -0
- package/src/agent/agent-lifecycle.js +982 -0
- package/src/agent/agent-quality-gate-schema.js +93 -0
- package/src/agent/agent-quality-gates-context.js +51 -0
- package/src/agent/agent-stuck-detector.js +256 -0
- package/src/agent/agent-task-executor.js +2028 -0
- package/src/agent/agent-trigger-evaluator.js +67 -0
- package/src/agent/context-metrics.js +160 -0
- package/src/agent/context-pack-builder.js +367 -0
- package/src/agent/context-replay-policy.js +51 -0
- package/src/agent/guidance-queue.js +77 -0
- package/src/agent/output-extraction.js +367 -0
- package/src/agent/output-reformatter.js +175 -0
- package/src/agent/pr-verification.js +653 -0
- package/src/agent/rate-limit-backoff.js +82 -0
- package/src/agent/schema-utils.js +146 -0
- package/src/agent/validation-platform.js +35 -0
- package/src/agent-cli-provider/adapters/claude-parser.ts +133 -0
- package/src/agent-cli-provider/adapters/claude-recovery.ts +203 -0
- package/src/agent-cli-provider/adapters/claude.ts +247 -0
- package/src/agent-cli-provider/adapters/codex-parser.ts +211 -0
- package/src/agent-cli-provider/adapters/codex.ts +217 -0
- package/src/agent-cli-provider/adapters/common.ts +124 -0
- package/src/agent-cli-provider/adapters/gemini.ts +243 -0
- package/src/agent-cli-provider/adapters/index.ts +126 -0
- package/src/agent-cli-provider/adapters/opencode.ts +286 -0
- package/src/agent-cli-provider/contract-actions.ts +150 -0
- package/src/agent-cli-provider/contract-env.ts +111 -0
- package/src/agent-cli-provider/contract-envelope.ts +110 -0
- package/src/agent-cli-provider/contract-errors.ts +66 -0
- package/src/agent-cli-provider/contract-fallback.ts +121 -0
- package/src/agent-cli-provider/contract-invoke.ts +104 -0
- package/src/agent-cli-provider/contract-options.ts +173 -0
- package/src/agent-cli-provider/contract-parse.ts +94 -0
- package/src/agent-cli-provider/contract-support.ts +167 -0
- package/src/agent-cli-provider/contract.ts +56 -0
- package/src/agent-cli-provider/env-safety.ts +82 -0
- package/src/agent-cli-provider/errors.ts +122 -0
- package/src/agent-cli-provider/executable.ts +24 -0
- package/src/agent-cli-provider/index.ts +83 -0
- package/src/agent-cli-provider/invoke-evidence.ts +18 -0
- package/src/agent-cli-provider/json.ts +114 -0
- package/src/agent-cli-provider/log-prefix.ts +20 -0
- package/src/agent-cli-provider/process-runner.ts +145 -0
- package/src/agent-cli-provider/redaction.ts +282 -0
- package/src/agent-cli-provider/schema.ts +115 -0
- package/src/agent-cli-provider/single-agent-runtime.ts +311 -0
- package/src/agent-cli-provider/types.ts +237 -0
- package/src/agent-wrapper.js +615 -0
- package/src/agents/git-pusher-template.js +705 -0
- package/src/attach/attach-client.js +438 -0
- package/src/attach/attach-server.js +543 -0
- package/src/attach/index.js +37 -0
- package/src/attach/protocol.js +220 -0
- package/src/attach/ring-buffer.js +121 -0
- package/src/attach/send-input.js +88 -0
- package/src/attach/socket-discovery.js +267 -0
- package/src/claude-task-runner.js +661 -0
- package/src/config-router.js +89 -0
- package/src/config-validator.js +2202 -0
- package/src/copy-worker.js +43 -0
- package/src/guidance-topics.js +10 -0
- package/src/input-helpers.js +65 -0
- package/src/isolation-manager.js +1734 -0
- package/src/issue-providers/README.md +305 -0
- package/src/issue-providers/azure-devops-provider.js +307 -0
- package/src/issue-providers/base-provider.js +232 -0
- package/src/issue-providers/github-provider.js +210 -0
- package/src/issue-providers/gitlab-provider.js +262 -0
- package/src/issue-providers/index.js +196 -0
- package/src/issue-providers/jira-provider.js +260 -0
- package/src/ledger.js +692 -0
- package/src/lib/gc.js +232 -0
- package/src/lib/safe-exec.js +88 -0
- package/src/logic-engine.js +201 -0
- package/src/message-buffer.js +81 -0
- package/src/message-bus-bridge.js +144 -0
- package/src/message-bus.js +256 -0
- package/src/name-generator.js +232 -0
- package/src/orchestrator.js +3924 -0
- package/src/preflight.js +712 -0
- package/src/process-metrics.js +608 -0
- package/src/providers/anthropic/index.js +3 -0
- package/src/providers/base-provider.js +355 -0
- package/src/providers/capabilities.js +60 -0
- package/src/providers/google/index.js +3 -0
- package/src/providers/index.js +293 -0
- package/src/providers/openai/index.js +3 -0
- package/src/providers/opencode/index.js +3 -0
- package/src/quality-gates.js +143 -0
- package/src/schemas/sub-cluster.js +208 -0
- package/src/state-snapshot.js +398 -0
- package/src/state-snapshotter.js +142 -0
- package/src/status-footer.js +1026 -0
- package/src/sub-cluster-wrapper.js +693 -0
- package/src/task-runner.js +30 -0
- package/src/template-resolver.js +425 -0
- package/src/template-validation/index.js +338 -0
- package/src/template-validation/simulate-consensus-gates.js +324 -0
- package/src/template-validation/simulate-random-topology.js +541 -0
- package/src/template-validation/simulate-two-stage-validation.js +270 -0
- package/src/worktree-claude-config.js +135 -0
- package/src/worktree-tooling-env.js +150 -0
- package/task-lib/attachable-watcher.js +381 -0
- package/task-lib/commands/clean.js +50 -0
- package/task-lib/commands/episodes.js +105 -0
- package/task-lib/commands/get-log-path.js +23 -0
- package/task-lib/commands/kill.js +32 -0
- package/task-lib/commands/list.js +105 -0
- package/task-lib/commands/logs.js +439 -0
- package/task-lib/commands/resume.js +42 -0
- package/task-lib/commands/run.js +57 -0
- package/task-lib/commands/schedule.js +105 -0
- package/task-lib/commands/scheduler-cmd.js +96 -0
- package/task-lib/commands/schedules.js +148 -0
- package/task-lib/commands/status.js +44 -0
- package/task-lib/commands/unschedule.js +16 -0
- package/task-lib/completion.js +9 -0
- package/task-lib/config.js +11 -0
- package/task-lib/name-generator.js +230 -0
- package/task-lib/package.json +3 -0
- package/task-lib/provider-helper-runtime.js +29 -0
- package/task-lib/runner.js +190 -0
- package/task-lib/scheduler.js +252 -0
- package/task-lib/store.js +529 -0
- package/task-lib/watcher.js +305 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
basePermanentErrorPatterns,
|
|
3
|
+
baseRetryableErrorPatterns,
|
|
4
|
+
classifyErrorWithPatterns,
|
|
5
|
+
} from '../errors';
|
|
6
|
+
import {
|
|
7
|
+
InvalidProviderModelError,
|
|
8
|
+
type BuildProviderCommandOptions,
|
|
9
|
+
type CliFeatureOverrides,
|
|
10
|
+
type CleanupMetadata,
|
|
11
|
+
type CommandSpec,
|
|
12
|
+
type ErrorClassification,
|
|
13
|
+
type LevelModelSpec,
|
|
14
|
+
type LevelOverrides,
|
|
15
|
+
type ModelCatalogEntry,
|
|
16
|
+
type ModelLevel,
|
|
17
|
+
type ProviderId,
|
|
18
|
+
type ProviderParserState,
|
|
19
|
+
type RedactionMetadata,
|
|
20
|
+
type ResolvedModelSpec,
|
|
21
|
+
type WarningMetadata,
|
|
22
|
+
} from '../types';
|
|
23
|
+
|
|
24
|
+
export function createParserState(provider: ProviderId): ProviderParserState {
|
|
25
|
+
return {
|
|
26
|
+
provider,
|
|
27
|
+
lastToolId: undefined,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function commandSpec(input: {
|
|
32
|
+
readonly binary: string;
|
|
33
|
+
readonly args: readonly string[];
|
|
34
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
35
|
+
readonly cwd?: string;
|
|
36
|
+
readonly cleanup?: readonly string[];
|
|
37
|
+
readonly cleanupMetadata?: readonly CleanupMetadata[];
|
|
38
|
+
readonly warnings?: readonly WarningMetadata[];
|
|
39
|
+
readonly redactions?: readonly RedactionMetadata[];
|
|
40
|
+
}): CommandSpec {
|
|
41
|
+
const spec = {
|
|
42
|
+
binary: input.binary,
|
|
43
|
+
args: input.args,
|
|
44
|
+
env: input.env ?? {},
|
|
45
|
+
cleanupMetadata: input.cleanupMetadata ?? [],
|
|
46
|
+
warnings: input.warnings ?? [],
|
|
47
|
+
redactions: input.redactions ?? [],
|
|
48
|
+
};
|
|
49
|
+
const specWithCwd = input.cwd === undefined ? spec : { ...spec, cwd: input.cwd };
|
|
50
|
+
if (input.cleanup === undefined) return specWithCwd;
|
|
51
|
+
return { ...specWithCwd, cleanup: input.cleanup };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function warning(provider: ProviderId, code: string, message: string): WarningMetadata {
|
|
55
|
+
return { provider, code, message };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function unsupportedSessionControlWarnings(
|
|
59
|
+
provider: ProviderId,
|
|
60
|
+
options: BuildProviderCommandOptions
|
|
61
|
+
): WarningMetadata[] {
|
|
62
|
+
if (!options.resumeSessionId && !options.continueSession) return [];
|
|
63
|
+
return [
|
|
64
|
+
warning(
|
|
65
|
+
provider,
|
|
66
|
+
'unsupported-session-control',
|
|
67
|
+
'resume/continue is only supported for Claude CLI; ignoring.'
|
|
68
|
+
),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function envRedactions(env: Readonly<Record<string, string>>): readonly RedactionMetadata[] {
|
|
73
|
+
return Object.keys(env).map((key) => ({ kind: 'env', key }));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface ModelResolutionConfig {
|
|
77
|
+
readonly mapping: Readonly<Record<ModelLevel, LevelModelSpec>>;
|
|
78
|
+
readonly defaultLevel: ModelLevel;
|
|
79
|
+
readonly level: ModelLevel;
|
|
80
|
+
readonly overrides: LevelOverrides | undefined;
|
|
81
|
+
readonly validateModelId: (modelId: string | null | undefined) => string | null | undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function resolveModelSpecWithConfig(config: ModelResolutionConfig): ResolvedModelSpec {
|
|
85
|
+
const base = config.mapping[config.level] ?? config.mapping[config.defaultLevel];
|
|
86
|
+
const override = config.overrides?.[config.level];
|
|
87
|
+
const selectedModel = override?.model || base.model;
|
|
88
|
+
const validatedModel = config.validateModelId(selectedModel);
|
|
89
|
+
return {
|
|
90
|
+
level: config.level,
|
|
91
|
+
model: validatedModel ?? null,
|
|
92
|
+
reasoningEffort: override?.reasoningEffort || base.reasoningEffort,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function validateModelIdFromCatalog(
|
|
97
|
+
provider: ProviderId,
|
|
98
|
+
catalog: Readonly<Record<string, ModelCatalogEntry>>,
|
|
99
|
+
modelId: string | null | undefined
|
|
100
|
+
): string | null | undefined {
|
|
101
|
+
if (!modelId) return modelId;
|
|
102
|
+
if (catalog[modelId] !== undefined) return modelId;
|
|
103
|
+
throw new InvalidProviderModelError(
|
|
104
|
+
`Invalid model "${modelId}" for provider "${provider}". Use a model listed in provider settings/catalog.`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function classifyBaseProviderError(
|
|
109
|
+
error: unknown,
|
|
110
|
+
retryablePatterns: readonly RegExp[],
|
|
111
|
+
permanentPatterns: readonly RegExp[]
|
|
112
|
+
): ErrorClassification {
|
|
113
|
+
return classifyErrorWithPatterns(
|
|
114
|
+
error,
|
|
115
|
+
[...baseRetryableErrorPatterns(), ...retryablePatterns],
|
|
116
|
+
[...basePermanentErrorPatterns(), ...permanentPatterns]
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function optionFeatures(
|
|
121
|
+
options: BuildProviderCommandOptions | undefined
|
|
122
|
+
): CliFeatureOverrides {
|
|
123
|
+
return options?.cliFeatures ?? {};
|
|
124
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { appendJsonSchemaPrompt } from '../schema';
|
|
2
|
+
import {
|
|
3
|
+
getOrStringFromKeys,
|
|
4
|
+
getOrStringFromKeysWithFallback,
|
|
5
|
+
getString,
|
|
6
|
+
isRecord,
|
|
7
|
+
tryParseJson,
|
|
8
|
+
} from '../json';
|
|
9
|
+
import {
|
|
10
|
+
type BuildProviderCommandOptions,
|
|
11
|
+
type CommandSpec,
|
|
12
|
+
type ErrorClassification,
|
|
13
|
+
type GeminiCliFeatures,
|
|
14
|
+
type LevelModelSpec,
|
|
15
|
+
type LevelOverrides,
|
|
16
|
+
type ModelCatalogEntry,
|
|
17
|
+
type ModelLevel,
|
|
18
|
+
type OutputEvent,
|
|
19
|
+
type ProviderAdapter,
|
|
20
|
+
type ProviderParserState,
|
|
21
|
+
type ResolvedModelSpec,
|
|
22
|
+
type WarningMetadata,
|
|
23
|
+
} from '../types';
|
|
24
|
+
import {
|
|
25
|
+
classifyBaseProviderError,
|
|
26
|
+
commandSpec,
|
|
27
|
+
createParserState,
|
|
28
|
+
optionFeatures,
|
|
29
|
+
resolveModelSpecWithConfig,
|
|
30
|
+
unsupportedSessionControlWarnings,
|
|
31
|
+
validateModelIdFromCatalog,
|
|
32
|
+
warning,
|
|
33
|
+
} from './common';
|
|
34
|
+
|
|
35
|
+
const MODEL_CATALOG: Readonly<Record<string, ModelCatalogEntry>> = {
|
|
36
|
+
'gemini-2.5-pro': { rank: 3 },
|
|
37
|
+
'gemini-2.0-flash': { rank: 1 },
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const LEVEL_MAPPING: Readonly<Record<ModelLevel, LevelModelSpec>> = {
|
|
41
|
+
level1: { rank: 1, model: null },
|
|
42
|
+
level2: { rank: 2, model: null },
|
|
43
|
+
level3: { rank: 3, model: null },
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
function detectCliFeatures(helpText?: string | null): GeminiCliFeatures {
|
|
47
|
+
const help = helpText ?? '';
|
|
48
|
+
const unknown = !help;
|
|
49
|
+
return {
|
|
50
|
+
provider: 'gemini',
|
|
51
|
+
supportsStreamJson: unknown ? true : /--output-format\b/.test(help),
|
|
52
|
+
supportsAutoApprove: unknown ? true : /--yolo\b/.test(help),
|
|
53
|
+
supportsCwd: unknown ? true : /--cwd\b/.test(help),
|
|
54
|
+
supportsModel: unknown ? true : /\s-m\b/.test(help) || /--model\b/.test(help),
|
|
55
|
+
unknown,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function addGeminiOptionalArgs(args: string[], options: BuildProviderCommandOptions): void {
|
|
60
|
+
const features = optionFeatures(options);
|
|
61
|
+
if (
|
|
62
|
+
(options.outputFormat === 'stream-json' || options.outputFormat === 'json') &&
|
|
63
|
+
features.supportsStreamJson
|
|
64
|
+
) {
|
|
65
|
+
args.push('--output-format', 'stream-json');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (options.modelSpec?.model) {
|
|
69
|
+
args.push('-m', options.modelSpec.model);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (options.cwd && features.supportsCwd) {
|
|
73
|
+
args.push('--cwd', options.cwd);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (options.autoApprove && features.supportsAutoApprove) {
|
|
77
|
+
args.push('--yolo');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function collectGeminiWarnings(options: BuildProviderCommandOptions): WarningMetadata[] {
|
|
82
|
+
const features = optionFeatures(options);
|
|
83
|
+
const warnings: WarningMetadata[] = unsupportedSessionControlWarnings('gemini', options);
|
|
84
|
+
if (options.autoApprove && features.supportsAutoApprove === false) {
|
|
85
|
+
warnings.push(
|
|
86
|
+
warning(
|
|
87
|
+
'gemini',
|
|
88
|
+
'gemini-auto-approve',
|
|
89
|
+
'Gemini CLI does not support --yolo; continuing without auto-approve.'
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return warnings;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function buildCommand(context: string, options: BuildProviderCommandOptions = {}): CommandSpec {
|
|
97
|
+
const finalContext = options.jsonSchema
|
|
98
|
+
? appendJsonSchemaPrompt(context, options.jsonSchema)
|
|
99
|
+
: context;
|
|
100
|
+
const args: string[] = ['-p', finalContext];
|
|
101
|
+
addGeminiOptionalArgs(args, options);
|
|
102
|
+
|
|
103
|
+
return commandSpec({
|
|
104
|
+
binary: 'gemini',
|
|
105
|
+
args,
|
|
106
|
+
env: {},
|
|
107
|
+
...(options.cwd === undefined ? {} : { cwd: options.cwd }),
|
|
108
|
+
warnings: collectGeminiWarnings(options),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function normalizeMessageContent(content: unknown): string {
|
|
113
|
+
if (typeof content === 'string') return content;
|
|
114
|
+
if (Array.isArray(content)) {
|
|
115
|
+
return content
|
|
116
|
+
.map((item) => {
|
|
117
|
+
if (typeof item === 'string') return item;
|
|
118
|
+
if (isRecord(item)) return getString(item, 'text') ?? '';
|
|
119
|
+
return '';
|
|
120
|
+
})
|
|
121
|
+
.join('');
|
|
122
|
+
}
|
|
123
|
+
if (isRecord(content)) return getString(content, 'text') ?? '';
|
|
124
|
+
return '';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function parseMessageEvent(event: Record<string, unknown>): OutputEvent | null {
|
|
128
|
+
if (getString(event, 'role') !== 'assistant') return null;
|
|
129
|
+
const text = normalizeMessageContent(event.content);
|
|
130
|
+
return text ? { type: 'text', text } : null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function parseToolUseEvent(
|
|
134
|
+
event: Record<string, unknown>,
|
|
135
|
+
state: ProviderParserState
|
|
136
|
+
): OutputEvent {
|
|
137
|
+
const toolId = getOrStringFromKeysWithFallback(
|
|
138
|
+
event,
|
|
139
|
+
['tool_call_id', 'tool_id', 'id'],
|
|
140
|
+
state.lastToolId
|
|
141
|
+
);
|
|
142
|
+
state.lastToolId = toolId;
|
|
143
|
+
return {
|
|
144
|
+
type: 'tool_call',
|
|
145
|
+
toolName: getOrStringFromKeys(event, ['tool_name', 'name']),
|
|
146
|
+
toolId,
|
|
147
|
+
input: event.parameters ?? event.input ?? {},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function parseToolResultEvent(
|
|
152
|
+
event: Record<string, unknown>,
|
|
153
|
+
state: ProviderParserState
|
|
154
|
+
): OutputEvent {
|
|
155
|
+
const toolId = getOrStringFromKeysWithFallback(
|
|
156
|
+
event,
|
|
157
|
+
['tool_call_id', 'tool_id', 'id'],
|
|
158
|
+
state.lastToolId
|
|
159
|
+
);
|
|
160
|
+
return {
|
|
161
|
+
type: 'tool_result',
|
|
162
|
+
toolId,
|
|
163
|
+
content: event.output ?? event.content ?? '',
|
|
164
|
+
isError: event.success === false,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function parseResultEvent(event: Record<string, unknown>): OutputEvent {
|
|
169
|
+
return {
|
|
170
|
+
type: 'result',
|
|
171
|
+
success: event.success !== false,
|
|
172
|
+
result: event.result || '',
|
|
173
|
+
error: event.success === false ? (getString(event, 'error') ?? 'Result failed') : null,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function parseEvent(line: string, state: ProviderParserState): OutputEvent | null {
|
|
178
|
+
const event = tryParseJson(line);
|
|
179
|
+
if (!isRecord(event)) return null;
|
|
180
|
+
|
|
181
|
+
switch (getString(event, 'type')) {
|
|
182
|
+
case 'init':
|
|
183
|
+
return null;
|
|
184
|
+
case 'message':
|
|
185
|
+
return parseMessageEvent(event);
|
|
186
|
+
case 'tool_use':
|
|
187
|
+
return parseToolUseEvent(event, state);
|
|
188
|
+
case 'tool_result':
|
|
189
|
+
return parseToolResultEvent(event, state);
|
|
190
|
+
case 'result':
|
|
191
|
+
return parseResultEvent(event);
|
|
192
|
+
default:
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function resolveModelSpec(level: ModelLevel, overrides?: LevelOverrides): ResolvedModelSpec {
|
|
198
|
+
return resolveModelSpecWithConfig({
|
|
199
|
+
mapping: LEVEL_MAPPING,
|
|
200
|
+
defaultLevel: 'level2',
|
|
201
|
+
level,
|
|
202
|
+
overrides,
|
|
203
|
+
validateModelId,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function validateModelId(modelId: string | null | undefined): string | null | undefined {
|
|
208
|
+
return validateModelIdFromCatalog('gemini', MODEL_CATALOG, modelId);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function classifyError(error: unknown): ErrorClassification {
|
|
212
|
+
return classifyBaseProviderError(
|
|
213
|
+
error,
|
|
214
|
+
[
|
|
215
|
+
/\bRESOURCE_EXHAUSTED\b/i,
|
|
216
|
+
/\bUNAVAILABLE\b/i,
|
|
217
|
+
/\bDEADLINE_EXCEEDED\b/i,
|
|
218
|
+
/No capacity available/i,
|
|
219
|
+
/quota.?exceeded/i,
|
|
220
|
+
],
|
|
221
|
+
[/\bINVALID_ARGUMENT\b/i, /\bPERMISSION_DENIED\b/i, /\bNOT_FOUND\b/i]
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export const geminiAdapter: ProviderAdapter = {
|
|
226
|
+
id: 'gemini',
|
|
227
|
+
displayName: 'Gemini',
|
|
228
|
+
binary: 'gemini',
|
|
229
|
+
adapterVersion: '1',
|
|
230
|
+
credentialEnvKeys: ['GEMINI_API_KEY', 'GOOGLE_API_KEY'],
|
|
231
|
+
modelCatalog: MODEL_CATALOG,
|
|
232
|
+
levelMapping: LEVEL_MAPPING,
|
|
233
|
+
defaultLevel: 'level2',
|
|
234
|
+
defaultMaxLevel: 'level3',
|
|
235
|
+
defaultMinLevel: 'level1',
|
|
236
|
+
detectCliFeatures,
|
|
237
|
+
buildCommand,
|
|
238
|
+
parseEvent,
|
|
239
|
+
createParserState: () => createParserState('gemini'),
|
|
240
|
+
resolveModelSpec,
|
|
241
|
+
validateModelId,
|
|
242
|
+
classifyError,
|
|
243
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { stripTimestampPrefix } from '../log-prefix';
|
|
2
|
+
import type {
|
|
3
|
+
BuildProviderCommandOptions,
|
|
4
|
+
CommandSpec,
|
|
5
|
+
ErrorClassification,
|
|
6
|
+
KnownProviderName,
|
|
7
|
+
LevelOverrides,
|
|
8
|
+
ModelLevel,
|
|
9
|
+
OutputEvent,
|
|
10
|
+
ProviderAdapter,
|
|
11
|
+
ProviderId,
|
|
12
|
+
ResolvedModelSpec,
|
|
13
|
+
} from '../types';
|
|
14
|
+
import { claudeAdapter } from './claude';
|
|
15
|
+
export {
|
|
16
|
+
NO_MESSAGES_RETURNED,
|
|
17
|
+
STREAMING_MODE_ERROR,
|
|
18
|
+
detectProviderFatalError,
|
|
19
|
+
detectProviderStreamingModeError,
|
|
20
|
+
recoverProviderStructuredOutput,
|
|
21
|
+
supportsProviderStructuredOutputRecovery,
|
|
22
|
+
type StreamingModeError,
|
|
23
|
+
type StructuredOutputRecovery,
|
|
24
|
+
} from './claude-recovery';
|
|
25
|
+
import { codexAdapter } from './codex';
|
|
26
|
+
import { geminiAdapter } from './gemini';
|
|
27
|
+
import { opencodeAdapter } from './opencode';
|
|
28
|
+
|
|
29
|
+
const ADAPTERS: Readonly<Record<ProviderId, ProviderAdapter>> = {
|
|
30
|
+
claude: claudeAdapter,
|
|
31
|
+
codex: codexAdapter,
|
|
32
|
+
gemini: geminiAdapter,
|
|
33
|
+
opencode: opencodeAdapter,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const PROVIDER_IDS: readonly ProviderId[] = ['claude', 'codex', 'gemini', 'opencode'];
|
|
37
|
+
|
|
38
|
+
function isOutputEventArray(
|
|
39
|
+
event: OutputEvent | readonly OutputEvent[]
|
|
40
|
+
): event is readonly OutputEvent[] {
|
|
41
|
+
return Array.isArray(event);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function normalizeProviderName(name: string): ProviderId | string {
|
|
45
|
+
const normalized = name.toLowerCase();
|
|
46
|
+
switch (normalized) {
|
|
47
|
+
case 'anthropic':
|
|
48
|
+
case 'claude':
|
|
49
|
+
return 'claude';
|
|
50
|
+
case 'openai':
|
|
51
|
+
case 'codex':
|
|
52
|
+
return 'codex';
|
|
53
|
+
case 'google':
|
|
54
|
+
case 'gemini':
|
|
55
|
+
return 'gemini';
|
|
56
|
+
case 'opencode':
|
|
57
|
+
return 'opencode';
|
|
58
|
+
default:
|
|
59
|
+
return name;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function adapterForProviderId(provider: ProviderId): ProviderAdapter {
|
|
64
|
+
return ADAPTERS[provider];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isProviderId(name: string): name is ProviderId {
|
|
68
|
+
return name === 'claude' || name === 'codex' || name === 'gemini' || name === 'opencode';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function getProviderAdapter(name: KnownProviderName | string): ProviderAdapter {
|
|
72
|
+
const normalized = normalizeProviderName(name || '');
|
|
73
|
+
if (isProviderId(normalized)) return adapterForProviderId(normalized);
|
|
74
|
+
throw new Error(`Unknown provider: ${name}. Valid: ${PROVIDER_IDS.join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function listProviderAdapters(): readonly ProviderId[] {
|
|
78
|
+
return PROVIDER_IDS;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function buildProviderCommand(
|
|
82
|
+
providerName: KnownProviderName | string,
|
|
83
|
+
context: string,
|
|
84
|
+
options?: BuildProviderCommandOptions
|
|
85
|
+
): CommandSpec {
|
|
86
|
+
return getProviderAdapter(providerName).buildCommand(context, options);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function parseProviderChunk(
|
|
90
|
+
providerName: KnownProviderName | string,
|
|
91
|
+
chunk: string
|
|
92
|
+
): readonly OutputEvent[] {
|
|
93
|
+
const adapter = getProviderAdapter(providerName || 'claude');
|
|
94
|
+
const state = adapter.createParserState();
|
|
95
|
+
const events: OutputEvent[] = [];
|
|
96
|
+
const lines = chunk.split('\n');
|
|
97
|
+
|
|
98
|
+
for (const line of lines) {
|
|
99
|
+
const content = stripTimestampPrefix(line);
|
|
100
|
+
if (!content) continue;
|
|
101
|
+
const event = adapter.parseEvent(content, state);
|
|
102
|
+
if (!event) continue;
|
|
103
|
+
if (isOutputEventArray(event)) {
|
|
104
|
+
events.push(...event);
|
|
105
|
+
} else {
|
|
106
|
+
events.push(event);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return events;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function resolveModelSpec(
|
|
114
|
+
providerName: KnownProviderName | string,
|
|
115
|
+
level: ModelLevel,
|
|
116
|
+
overrides?: LevelOverrides
|
|
117
|
+
): ResolvedModelSpec {
|
|
118
|
+
return getProviderAdapter(providerName).resolveModelSpec(level, overrides);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function classifyProviderError(
|
|
122
|
+
providerName: KnownProviderName | string,
|
|
123
|
+
error: unknown
|
|
124
|
+
): ErrorClassification {
|
|
125
|
+
return getProviderAdapter(providerName).classifyError(error);
|
|
126
|
+
}
|