@gajae-code/coding-agent 0.5.0 → 0.5.2
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 +36 -0
- package/README.md +1 -1
- package/dist/types/async/job-manager.d.ts +26 -0
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/cli/list-models.d.ts +6 -0
- package/dist/types/cli/setup-cli.d.ts +8 -1
- package/dist/types/commands/gc.d.ts +26 -0
- package/dist/types/commands/setup.d.ts +7 -0
- package/dist/types/config/file-lock-gc.d.ts +5 -0
- package/dist/types/config/file-lock.d.ts +29 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/models-config-schema.d.ts +5 -0
- package/dist/types/config/settings-schema.d.ts +62 -0
- package/dist/types/coordinator/contract.d.ts +1 -1
- package/dist/types/defaults/gjc/extensions/grok-build/index.d.ts +1 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/index.d.ts +1 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.d.ts +25 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/payload/sanitize.d.ts +27 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/billing.d.ts +8 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.d.ts +5 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.d.ts +10 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/usage.d.ts +2 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.d.ts +2 -0
- package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/shared/errors.d.ts +38 -0
- package/dist/types/defaults/gjc-grok-cli.d.ts +5 -0
- package/dist/types/extensibility/extensions/index.d.ts +1 -0
- package/dist/types/extensibility/extensions/prefix-command-bridge.d.ts +35 -0
- package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +103 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +2 -0
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +112 -0
- package/dist/types/gjc-runtime/gc-render.d.ts +6 -0
- package/dist/types/gjc-runtime/gc-runtime.d.ts +134 -0
- package/dist/types/gjc-runtime/ledger-event-renderer.d.ts +68 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +64 -2
- package/dist/types/gjc-runtime/team-gc.d.ts +7 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +5 -0
- package/dist/types/gjc-runtime/tmux-common.d.ts +11 -0
- package/dist/types/gjc-runtime/tmux-gc.d.ts +7 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +13 -0
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +10 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +29 -0
- package/dist/types/harness-control-plane/gc-adapter.d.ts +3 -0
- package/dist/types/harness-control-plane/owner.d.ts +7 -0
- package/dist/types/harness-control-plane/storage.d.ts +20 -0
- package/dist/types/modes/components/hook-selector.d.ts +7 -1
- package/dist/types/modes/components/provider-onboarding-selector.d.ts +1 -1
- package/dist/types/modes/controllers/command-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/rpc/rpc-mode.d.ts +72 -2
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +13 -0
- package/dist/types/modes/shared/agent-wire/session-registry.d.ts +25 -0
- package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +2 -0
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +10 -0
- package/dist/types/modes/theme/defaults/index.d.ts +302 -0
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/types.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +1 -1
- package/dist/types/session/blob-store.d.ts +39 -3
- package/dist/types/session/history-storage.d.ts +2 -2
- package/dist/types/session/session-manager.d.ts +10 -1
- package/dist/types/setup/credential-import.d.ts +79 -0
- package/dist/types/skill-state/workflow-hud.d.ts +14 -0
- package/dist/types/task/executor.d.ts +1 -0
- package/dist/types/task/render.d.ts +1 -1
- package/dist/types/tools/ask.d.ts +15 -1
- package/dist/types/tools/subagent-render.d.ts +7 -1
- package/dist/types/tools/subagent.d.ts +27 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +5 -0
- package/dist/types/web/search/index.d.ts +4 -4
- package/dist/types/web/search/provider.d.ts +16 -20
- package/dist/types/web/search/providers/base.d.ts +2 -1
- package/dist/types/web/search/providers/openai-compatible.d.ts +9 -0
- package/dist/types/web/search/types.d.ts +14 -2
- package/package.json +7 -7
- package/scripts/build-binary.ts +7 -0
- package/src/async/job-manager.ts +52 -0
- package/src/cli/args.ts +5 -0
- package/src/cli/auth-broker-cli.ts +1 -0
- package/src/cli/fast-help.ts +2 -0
- package/src/cli/list-models.ts +13 -1
- package/src/cli/setup-cli.ts +138 -3
- package/src/cli.ts +1 -0
- package/src/commands/gc.ts +22 -0
- package/src/commands/harness.ts +7 -3
- package/src/commands/setup.ts +5 -1
- package/src/commands/ultragoal.ts +3 -1
- package/src/config/file-lock-gc.ts +193 -0
- package/src/config/file-lock.ts +66 -10
- package/src/config/model-profile-activation.ts +15 -3
- package/src/config/model-profiles.ts +39 -30
- package/src/config/model-registry.ts +21 -1
- package/src/config/models-config-schema.ts +1 -0
- package/src/config/settings-schema.ts +62 -0
- package/src/coordinator/contract.ts +1 -0
- package/src/coordinator-mcp/server.ts +459 -3
- package/src/defaults/gjc/agent.models.grok-cli.yml +36 -0
- package/src/defaults/gjc/extensions/grok-build/index.ts +1 -0
- package/src/defaults/gjc/extensions/grok-build/package.json +7 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/biome.json +39 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/package.json +8 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/index.ts +1 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +155 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/payload/sanitize.ts +361 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/billing.ts +57 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +99 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.ts +50 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/usage.ts +56 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +36 -0
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/errors.ts +44 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +131 -113
- package/src/defaults/gjc/skills/deep-interview/lateral-review-panel.md +49 -0
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +30 -8
- package/src/defaults/gjc-defaults.ts +7 -0
- package/src/defaults/gjc-grok-cli.ts +22 -0
- package/src/extensibility/extensions/index.ts +1 -0
- package/src/extensibility/extensions/prefix-command-bridge.ts +128 -0
- package/src/gjc-runtime/deep-interview-recorder.ts +457 -0
- package/src/gjc-runtime/deep-interview-runtime.ts +18 -26
- package/src/gjc-runtime/deep-interview-state.ts +324 -0
- package/src/gjc-runtime/gc-render.ts +70 -0
- package/src/gjc-runtime/gc-runtime.ts +403 -0
- package/src/gjc-runtime/launch-tmux.ts +3 -4
- package/src/gjc-runtime/ledger-event-renderer.ts +164 -0
- package/src/gjc-runtime/ralplan-runtime.ts +232 -19
- package/src/gjc-runtime/state-renderer.ts +12 -3
- package/src/gjc-runtime/state-runtime.ts +48 -30
- package/src/gjc-runtime/state-writer.ts +254 -7
- package/src/gjc-runtime/team-gc.ts +49 -0
- package/src/gjc-runtime/team-runtime.ts +179 -2
- package/src/gjc-runtime/tmux-common.ts +14 -0
- package/src/gjc-runtime/tmux-gc.ts +177 -0
- package/src/gjc-runtime/tmux-sessions.ts +49 -1
- package/src/gjc-runtime/ultragoal-guard.ts +155 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +1239 -31
- package/src/gjc-runtime/workflow-manifest.generated.json +44 -0
- package/src/gjc-runtime/workflow-manifest.ts +12 -0
- package/src/harness-control-plane/gc-adapter.ts +184 -0
- package/src/harness-control-plane/owner.ts +14 -2
- package/src/harness-control-plane/rpc-adapter.ts +1 -1
- package/src/harness-control-plane/storage.ts +70 -0
- package/src/hooks/skill-state.ts +121 -2
- package/src/internal-urls/docs-index.generated.ts +22 -12
- package/src/lsp/defaults.json +1 -0
- package/src/main.ts +18 -3
- package/src/modes/acp/acp-agent.ts +4 -2
- package/src/modes/bridge/bridge-mode.ts +2 -1
- package/src/modes/components/history-search.ts +5 -2
- package/src/modes/components/hook-selector.ts +19 -0
- package/src/modes/components/model-selector.ts +51 -8
- package/src/modes/components/provider-onboarding-selector.ts +6 -1
- package/src/modes/components/status-line/segments.ts +1 -1
- package/src/modes/controllers/command-controller.ts +25 -6
- package/src/modes/controllers/extension-ui-controller.ts +3 -0
- package/src/modes/controllers/selector-controller.ts +81 -1
- package/src/modes/interactive-mode.ts +11 -1
- package/src/modes/rpc/rpc-mode.ts +266 -34
- package/src/modes/shared/agent-wire/command-dispatch.ts +281 -261
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +30 -1
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +3 -0
- package/src/modes/shared/agent-wire/session-registry.ts +109 -0
- package/src/modes/shared/agent-wire/unattended-action-policy.ts +24 -0
- package/src/modes/shared/agent-wire/unattended-run-controller.ts +23 -3
- package/src/modes/shared/agent-wire/unattended-session.ts +32 -2
- package/src/modes/theme/defaults/claude-code.json +100 -0
- package/src/modes/theme/defaults/codex.json +100 -0
- package/src/modes/theme/defaults/index.ts +6 -0
- package/src/modes/theme/defaults/opencode.json +102 -0
- package/src/modes/theme/theme.ts +2 -2
- package/src/modes/types.ts +1 -1
- package/src/prompts/agents/executor.md +5 -2
- package/src/sdk.ts +29 -4
- package/src/session/agent-session.ts +99 -19
- package/src/session/blob-store.ts +59 -3
- package/src/session/history-storage.ts +32 -11
- package/src/session/session-manager.ts +72 -20
- package/src/setup/credential-import.ts +429 -0
- package/src/setup/hermes/templates/operator-instructions.v1.md +7 -1
- package/src/skill-state/deep-interview-mutation-guard.ts +2 -1
- package/src/skill-state/workflow-hud.ts +106 -10
- package/src/slash-commands/builtin-registry.ts +3 -2
- package/src/task/executor.ts +16 -1
- package/src/task/render.ts +18 -7
- package/src/tools/ask.ts +59 -2
- package/src/tools/cron.ts +1 -1
- package/src/tools/job.ts +3 -2
- package/src/tools/monitor.ts +36 -1
- package/src/tools/subagent-render.ts +128 -29
- package/src/tools/subagent.ts +173 -9
- package/src/tools/ultragoal-ask-guard.ts +39 -0
- package/src/web/search/index.ts +25 -25
- package/src/web/search/provider.ts +178 -87
- package/src/web/search/providers/base.ts +2 -1
- package/src/web/search/providers/openai-compatible.ts +151 -0
- package/src/web/search/types.ts +47 -22
package/src/config/file-lock.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
|
-
import { isEnoent } from "@gajae-code/utils";
|
|
2
|
+
import { isEnoent } from "@gajae-code/utils/fs-error";
|
|
3
3
|
|
|
4
4
|
export interface FileLockOptions {
|
|
5
5
|
staleMs?: number;
|
|
@@ -36,12 +36,66 @@ async function readLockInfo(lockPath: string): Promise<LockInfo | null> {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
/** @internal */
|
|
40
|
+
export async function readFileLockInfoForGc(lockDir: string): Promise<{ pid: number; timestamp: number } | null> {
|
|
41
|
+
const info = await readLockInfo(lockDir);
|
|
42
|
+
if (!info) return null;
|
|
43
|
+
if (!Number.isFinite(info.pid) || info.pid <= 0) return null;
|
|
44
|
+
if (!Number.isFinite(info.timestamp)) return null;
|
|
45
|
+
return info;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Owner identity stamped into a `<file>.lock/info` record. */
|
|
49
|
+
export interface FileLockOwnerToken {
|
|
50
|
+
pid: number;
|
|
51
|
+
timestamp: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Outcome of a guarded GC removal attempt (`removeFileLockDirForGc`). */
|
|
55
|
+
export type FileLockGcRemoval = "removed" | "owner_changed" | "missing";
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @internal
|
|
59
|
+
* Fail-closed removal of a dead lock dir for GC. Re-reads the on-disk owner
|
|
60
|
+
* token as close to the unlink as possible and only deletes the dir when it
|
|
61
|
+
* STILL holds the exact `{pid, timestamp}` identity the caller observed dead.
|
|
62
|
+
*
|
|
63
|
+
* Closes the prune-time TOCTOU window (#606): between GC's dead re-read/probe
|
|
64
|
+
* and the unlink, a live process can reclaim a stale lock at the same path
|
|
65
|
+
* (`acquireLock` rms the stale dir, then re-`mkdir`s and rewrites `info` with a
|
|
66
|
+
* fresh pid+timestamp). Deleting by path alone would reap that LIVE lock. Any
|
|
67
|
+
* mismatch (`owner_changed`) or absent/unreadable info (`missing` — e.g. a
|
|
68
|
+
* fresh acquirer between `mkdir` and `writeLockInfo`) refuses the delete and
|
|
69
|
+
* leaves the dir intact. POSIX has no atomic compare-and-delete for a
|
|
70
|
+
* directory, so the residual read->unlink window cannot be fully eliminated,
|
|
71
|
+
* but the reclaim-after-stale scenario the issue describes is now guarded.
|
|
72
|
+
*/
|
|
73
|
+
export async function removeFileLockDirForGc(
|
|
74
|
+
lockDir: string,
|
|
75
|
+
expected: FileLockOwnerToken,
|
|
76
|
+
): Promise<FileLockGcRemoval> {
|
|
77
|
+
const current = await readLockInfo(lockDir);
|
|
78
|
+
if (!current) return "missing";
|
|
79
|
+
if (current.pid !== expected.pid || current.timestamp !== expected.timestamp) {
|
|
80
|
+
return "owner_changed";
|
|
81
|
+
}
|
|
82
|
+
await fs.rm(lockDir, { recursive: true, force: true });
|
|
83
|
+
return "removed";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
type OwnerLiveness = "alive" | "dead" | "unknown";
|
|
87
|
+
|
|
88
|
+
function ownerLiveness(pid: number): OwnerLiveness {
|
|
89
|
+
if (!Number.isFinite(pid) || pid <= 0) return "unknown";
|
|
40
90
|
try {
|
|
41
91
|
process.kill(pid, 0);
|
|
42
|
-
return
|
|
43
|
-
} catch {
|
|
44
|
-
|
|
92
|
+
return "alive";
|
|
93
|
+
} catch (error) {
|
|
94
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
95
|
+
if (code === "ESRCH") return "dead";
|
|
96
|
+
// EPERM means the process exists but we may not signal it; treat as alive.
|
|
97
|
+
// Anything else is indeterminate.
|
|
98
|
+
return code === "EPERM" ? "alive" : "unknown";
|
|
45
99
|
}
|
|
46
100
|
}
|
|
47
101
|
|
|
@@ -49,11 +103,13 @@ async function isLockStale(lockPath: string, staleMs: number): Promise<boolean>
|
|
|
49
103
|
const info = await readLockInfo(lockPath);
|
|
50
104
|
if (!info) return true;
|
|
51
105
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return
|
|
106
|
+
// Never reap a live owner by elapsed time: a long legitimate critical section must
|
|
107
|
+
// not have its lock stolen (#652). Reclaim a dead owner immediately. Only when owner
|
|
108
|
+
// liveness is indeterminate do we fall back to the staleMs elapsed-time heuristic.
|
|
109
|
+
const liveness = ownerLiveness(info.pid);
|
|
110
|
+
if (liveness === "dead") return true;
|
|
111
|
+
if (liveness === "alive") return false;
|
|
112
|
+
return Date.now() - info.timestamp > staleMs;
|
|
57
113
|
}
|
|
58
114
|
|
|
59
115
|
async function tryAcquireLock(lockPath: string): Promise<boolean> {
|
|
@@ -11,6 +11,8 @@ import { type GjcModelAssignmentTargetId, isAuthenticated, type ModelRegistry }
|
|
|
11
11
|
import { resolveModelRoleValue } from "./model-resolver";
|
|
12
12
|
import type { Settings } from "./settings";
|
|
13
13
|
|
|
14
|
+
const LEGACY_MODEL_PROFILE_ALIASES: ReadonlyMap<string, string> = new Map([["codex-standard", "codex-medium"]]);
|
|
15
|
+
|
|
14
16
|
type ModelProfileActivationSession = Pick<AgentSession, "model" | "thinkingLevel" | "sessionId"> & {
|
|
15
17
|
setModelTemporary?: AgentSession["setModelTemporary"];
|
|
16
18
|
setActiveModelProfile?: (name: string | undefined) => void;
|
|
@@ -51,12 +53,22 @@ export function formatModelProfileCredentialError(profileName: string, providers
|
|
|
51
53
|
return `Model profile "${profileName}" requires credentials for: ${providers.join(", ")}. Run /login and configure the missing provider(s), then retry.`;
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
function resolveModelProfileName(profileName: string, profiles: ReadonlyMap<string, unknown>): string {
|
|
57
|
+
// A retired-name alias is fallback-only: never shadow a profile that actually
|
|
58
|
+
// exists under the requested name (e.g. a user-defined `codex-standard`).
|
|
59
|
+
if (profiles.has(profileName)) return profileName;
|
|
60
|
+
const replacement = LEGACY_MODEL_PROFILE_ALIASES.get(profileName);
|
|
61
|
+
return replacement && profiles.has(replacement) ? replacement : profileName;
|
|
62
|
+
}
|
|
63
|
+
|
|
54
64
|
export async function prepareModelProfileActivation(
|
|
55
65
|
options: PrepareModelProfileActivationOptions,
|
|
56
66
|
): Promise<PreparedModelProfileActivation> {
|
|
57
|
-
const
|
|
67
|
+
const profiles = options.modelRegistry.getModelProfiles();
|
|
68
|
+
const profileName = resolveModelProfileName(options.profileName, profiles);
|
|
69
|
+
const profile = profiles.get(profileName) ?? options.modelRegistry.getModelProfile(profileName);
|
|
58
70
|
if (!profile) {
|
|
59
|
-
const available = formatAvailableProfileNames(
|
|
71
|
+
const available = formatAvailableProfileNames(profiles);
|
|
60
72
|
throw new Error(`Unknown model profile "${options.profileName}". Available profiles: ${available}`);
|
|
61
73
|
}
|
|
62
74
|
|
|
@@ -101,7 +113,7 @@ export async function prepareModelProfileActivation(
|
|
|
101
113
|
}
|
|
102
114
|
|
|
103
115
|
return {
|
|
104
|
-
profileName
|
|
116
|
+
profileName,
|
|
105
117
|
session: options.session as PreparedModelProfileActivation["session"],
|
|
106
118
|
settings: options.settings as PreparedModelProfileActivation["settings"],
|
|
107
119
|
previousModel: options.session.model,
|
|
@@ -90,25 +90,25 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
90
90
|
architect: "anthropic/claude-opus-4-8:xhigh",
|
|
91
91
|
}),
|
|
92
92
|
profile("glm-eco", ["zai"], {
|
|
93
|
-
default: "zai/glm-5.
|
|
94
|
-
executor: "zai/glm-5.
|
|
95
|
-
planner: "zai/glm-5.
|
|
96
|
-
critic: "zai/glm-5.
|
|
97
|
-
architect: "zai/glm-5.
|
|
93
|
+
default: "zai/glm-5.2:low",
|
|
94
|
+
executor: "zai/glm-5.2:minimal",
|
|
95
|
+
planner: "zai/glm-5.2:low",
|
|
96
|
+
critic: "zai/glm-5.2:medium",
|
|
97
|
+
architect: "zai/glm-5.2:high",
|
|
98
98
|
}),
|
|
99
99
|
profile("glm-medium", ["zai"], {
|
|
100
|
-
default: "zai/glm-5.
|
|
101
|
-
executor: "zai/glm-5.
|
|
102
|
-
planner: "zai/glm-5.
|
|
103
|
-
critic: "zai/glm-5.
|
|
104
|
-
architect: "zai/glm-5.
|
|
100
|
+
default: "zai/glm-5.2:medium",
|
|
101
|
+
executor: "zai/glm-5.2:low",
|
|
102
|
+
planner: "zai/glm-5.2:medium",
|
|
103
|
+
critic: "zai/glm-5.2:high",
|
|
104
|
+
architect: "zai/glm-5.2:xhigh",
|
|
105
105
|
}),
|
|
106
106
|
profile("glm-pro", ["zai"], {
|
|
107
|
-
default: "zai/glm-5.
|
|
108
|
-
executor: "zai/glm-5.
|
|
109
|
-
planner: "zai/glm-5.
|
|
110
|
-
critic: "zai/glm-5.
|
|
111
|
-
architect: "zai/glm-5.
|
|
107
|
+
default: "zai/glm-5.2:xhigh",
|
|
108
|
+
executor: "zai/glm-5.2:medium",
|
|
109
|
+
planner: "zai/glm-5.2:high",
|
|
110
|
+
critic: "zai/glm-5.2:xhigh",
|
|
111
|
+
architect: "zai/glm-5.2:xhigh",
|
|
112
112
|
}),
|
|
113
113
|
profile("kimi-coding-plan-eco", ["kimi-code"], {
|
|
114
114
|
default: "kimi-code/kimi-k2.7-code:low",
|
|
@@ -173,6 +173,13 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
173
173
|
critic: "xai/grok-4.3:xhigh",
|
|
174
174
|
architect: "xai/grok-4.3:xhigh",
|
|
175
175
|
}),
|
|
176
|
+
profile("grok-build-pro", ["grok-build"], {
|
|
177
|
+
default: "grok-build/grok-composer-2.5-fast",
|
|
178
|
+
executor: "grok-build/grok-build",
|
|
179
|
+
planner: "grok-build/grok-composer-2.5-fast",
|
|
180
|
+
critic: "grok-build/grok-composer-2.5-fast",
|
|
181
|
+
architect: "grok-build/grok-build",
|
|
182
|
+
}),
|
|
176
183
|
profile("cursor-eco", ["cursor"], {
|
|
177
184
|
default: "cursor/composer-1.5:low",
|
|
178
185
|
executor: "cursor/composer-1.5:minimal",
|
|
@@ -195,25 +202,25 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
195
202
|
architect: "cursor/composer-1.5:xhigh",
|
|
196
203
|
}),
|
|
197
204
|
profile("minimax-eco", ["minimax-code"], {
|
|
198
|
-
default: "minimax-code/minimax-
|
|
199
|
-
executor: "minimax-code/minimax-
|
|
200
|
-
planner: "minimax-code/minimax-
|
|
201
|
-
critic: "minimax-code/minimax-
|
|
202
|
-
architect: "minimax-code/minimax-
|
|
205
|
+
default: "minimax-code/minimax-m3:low",
|
|
206
|
+
executor: "minimax-code/minimax-m3:minimal",
|
|
207
|
+
planner: "minimax-code/minimax-m3:low",
|
|
208
|
+
critic: "minimax-code/minimax-m3:medium",
|
|
209
|
+
architect: "minimax-code/minimax-m3:high",
|
|
203
210
|
}),
|
|
204
211
|
profile("minimax-medium", ["minimax-code"], {
|
|
205
|
-
default: "minimax-code/minimax-
|
|
206
|
-
executor: "minimax-code/minimax-
|
|
207
|
-
planner: "minimax-code/minimax-
|
|
208
|
-
critic: "minimax-code/minimax-
|
|
209
|
-
architect: "minimax-code/minimax-
|
|
212
|
+
default: "minimax-code/minimax-m3:medium",
|
|
213
|
+
executor: "minimax-code/minimax-m3:low",
|
|
214
|
+
planner: "minimax-code/minimax-m3:medium",
|
|
215
|
+
critic: "minimax-code/minimax-m3:high",
|
|
216
|
+
architect: "minimax-code/minimax-m3:xhigh",
|
|
210
217
|
}),
|
|
211
218
|
profile("minimax-pro", ["minimax-code"], {
|
|
212
|
-
default: "minimax-code/minimax-
|
|
213
|
-
executor: "minimax-code/minimax-
|
|
214
|
-
planner: "minimax-code/minimax-
|
|
215
|
-
critic: "minimax-code/minimax-
|
|
216
|
-
architect: "minimax-code/minimax-
|
|
219
|
+
default: "minimax-code/minimax-m3:xhigh",
|
|
220
|
+
executor: "minimax-code/minimax-m3:medium",
|
|
221
|
+
planner: "minimax-code/minimax-m3:high",
|
|
222
|
+
critic: "minimax-code/minimax-m3:xhigh",
|
|
223
|
+
architect: "minimax-code/minimax-m3:xhigh",
|
|
217
224
|
}),
|
|
218
225
|
profile("opus-codex", ["anthropic", "openai-codex"], {
|
|
219
226
|
default: "anthropic/claude-opus-4-8:xhigh",
|
|
@@ -254,6 +261,7 @@ const PROFILE_PRESENTATION: Record<string, ModelProfilePresentation> = {
|
|
|
254
261
|
"grok-eco": { displayName: "Grok Eco", providerGroup: "GROK" },
|
|
255
262
|
"grok-medium": { displayName: "Grok Medium", providerGroup: "GROK" },
|
|
256
263
|
"grok-pro": { displayName: "Grok Pro", providerGroup: "GROK" },
|
|
264
|
+
"grok-build-pro": { displayName: "Grok Build Pro", providerGroup: "GROK" },
|
|
257
265
|
"cursor-eco": { displayName: "Cursor Eco", providerGroup: "CURSOR" },
|
|
258
266
|
"cursor-medium": { displayName: "Cursor Medium", providerGroup: "CURSOR" },
|
|
259
267
|
"cursor-pro": { displayName: "Cursor Pro", providerGroup: "CURSOR" },
|
|
@@ -285,6 +293,7 @@ const PROFILE_RECOMMENDATIONS: Record<string, string> = {
|
|
|
285
293
|
"kimi-code": "kimi-coding-plan-medium",
|
|
286
294
|
xiaomi: "mimo-medium",
|
|
287
295
|
xai: "grok-medium",
|
|
296
|
+
"grok-build": "grok-build-pro",
|
|
288
297
|
cursor: "cursor-medium",
|
|
289
298
|
"minimax-code": "minimax-medium",
|
|
290
299
|
};
|
|
@@ -35,6 +35,7 @@ import { $pickenv, isRecord, logger } from "@gajae-code/utils";
|
|
|
35
35
|
import { parseModelString, resolveProviderModelReference } from "../config/model-resolver";
|
|
36
36
|
import { isValidThemeColor, type ThemeColor } from "../modes/theme/theme";
|
|
37
37
|
import type { AuthStorage, OAuthCredential } from "../session/auth-storage";
|
|
38
|
+
import type { ActiveSearchModelContext, WebSearchMode } from "../web/search/types";
|
|
38
39
|
import { type ConfigError, ConfigFile } from "./config-file";
|
|
39
40
|
import {
|
|
40
41
|
buildCanonicalModelIndex,
|
|
@@ -910,7 +911,7 @@ function finalizeCustomModel(model: CustomModelOverlay, options: CustomModelBuil
|
|
|
910
911
|
const output = resolvedModel.output ?? reference?.output;
|
|
911
912
|
return enrichModelThinking({
|
|
912
913
|
id: resolvedModel.id,
|
|
913
|
-
name: resolvedModel.name ?? (options.useDefaults ? resolvedModel.id : undefined),
|
|
914
|
+
name: resolvedModel.name ?? reference?.name ?? (options.useDefaults ? resolvedModel.id : undefined),
|
|
914
915
|
api: resolvedModel.api,
|
|
915
916
|
provider: resolvedModel.provider,
|
|
916
917
|
baseUrl: resolvedModel.baseUrl,
|
|
@@ -964,6 +965,7 @@ export class ModelRegistry {
|
|
|
964
965
|
#models: Model<Api>[] = [];
|
|
965
966
|
#canonicalIndex: CanonicalModelIndex = { records: [], byId: new Map(), bySelector: new Map() };
|
|
966
967
|
#customProviderApiKeys: Map<string, string> = new Map();
|
|
968
|
+
#providerWebSearchModes: Map<string, WebSearchMode> = new Map();
|
|
967
969
|
#keylessProviders: Set<string> = new Set();
|
|
968
970
|
#discoverableProviders: DiscoveryProviderConfig[] = [];
|
|
969
971
|
#customModelOverlays: CustomModelOverlay[] = [];
|
|
@@ -1073,6 +1075,7 @@ export class ModelRegistry {
|
|
|
1073
1075
|
}
|
|
1074
1076
|
this.#modelsConfigFile.invalidate();
|
|
1075
1077
|
this.#customProviderApiKeys.clear();
|
|
1078
|
+
this.#providerWebSearchModes.clear();
|
|
1076
1079
|
this.#keylessProviders.clear();
|
|
1077
1080
|
this.#discoverableProviders = [];
|
|
1078
1081
|
// Drop config-sourced apiKeys from AuthStorage before reload; entries
|
|
@@ -1390,6 +1393,7 @@ export class ModelRegistry {
|
|
|
1390
1393
|
const configuredProviders = new Set(Object.keys(value.providers ?? {}));
|
|
1391
1394
|
|
|
1392
1395
|
for (const [providerName, providerConfig] of providerEntries) {
|
|
1396
|
+
if (providerConfig.webSearch) this.#providerWebSearchModes.set(providerName, providerConfig.webSearch);
|
|
1393
1397
|
const providerApiKeyConfig = providerConfig.apiKey ?? resolveApiKeyEnvConfig(providerConfig.apiKeyEnv);
|
|
1394
1398
|
// Always set overrides when baseUrl/headers/apiKey/authHeader/compat/disableStrictTools/transport are present
|
|
1395
1399
|
if (
|
|
@@ -2441,6 +2445,22 @@ export class ModelRegistry {
|
|
|
2441
2445
|
);
|
|
2442
2446
|
}
|
|
2443
2447
|
|
|
2448
|
+
getProviderWebSearchMode(provider: string): WebSearchMode | undefined {
|
|
2449
|
+
return this.#providerWebSearchModes.get(provider);
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
getActiveSearchModelContext(model: Model<Api>): ActiveSearchModelContext {
|
|
2453
|
+
return {
|
|
2454
|
+
provider: model.provider,
|
|
2455
|
+
modelId: model.id,
|
|
2456
|
+
wireModelId: model.wireModelId,
|
|
2457
|
+
api: model.api,
|
|
2458
|
+
baseUrl: model.baseUrl,
|
|
2459
|
+
headers: model.headers,
|
|
2460
|
+
webSearch: this.getProviderWebSearchMode(model.provider),
|
|
2461
|
+
};
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2444
2464
|
/**
|
|
2445
2465
|
* Get API key for a model.
|
|
2446
2466
|
*/
|
|
@@ -218,6 +218,7 @@ const ProviderConfigSchema = z
|
|
|
218
218
|
.optional(),
|
|
219
219
|
headers: z.record(z.string(), z.string()).optional(),
|
|
220
220
|
compat: OpenAICompatSchema.optional(),
|
|
221
|
+
webSearch: z.enum(["on", "off", "auto"]).optional(),
|
|
221
222
|
authHeader: z.boolean().optional(),
|
|
222
223
|
auth: ProviderAuthSchema.optional(),
|
|
223
224
|
discovery: ProviderDiscoverySchema.optional(),
|
|
@@ -2,6 +2,7 @@ import type { Effort } from "@gajae-code/ai/model-thinking";
|
|
|
2
2
|
import { TASK_SIMPLE_MODES } from "../task/simple-mode";
|
|
3
3
|
import { getThinkingLevelMetadata } from "../thinking-metadata";
|
|
4
4
|
import { EDIT_MODES } from "../utils/edit-mode";
|
|
5
|
+
import { CONFIGURABLE_SEARCH_PROVIDER_IDS } from "../web/search/types";
|
|
5
6
|
|
|
6
7
|
const THINKING_EFFORTS = ["minimal", "low", "medium", "high", "xhigh", "max"] as readonly Effort[];
|
|
7
8
|
|
|
@@ -164,6 +165,7 @@ interface EnumDef<T extends readonly string[]> {
|
|
|
164
165
|
interface ArrayDef<T> {
|
|
165
166
|
type: "array";
|
|
166
167
|
default: T[];
|
|
168
|
+
items?: { enum: readonly string[] };
|
|
167
169
|
ui?: UiBase;
|
|
168
170
|
}
|
|
169
171
|
|
|
@@ -832,6 +834,55 @@ export const SETTINGS_SCHEMA = {
|
|
|
832
834
|
},
|
|
833
835
|
},
|
|
834
836
|
|
|
837
|
+
"task.serviceTier": {
|
|
838
|
+
type: "enum",
|
|
839
|
+
values: [
|
|
840
|
+
"inherit",
|
|
841
|
+
"none",
|
|
842
|
+
"auto",
|
|
843
|
+
"default",
|
|
844
|
+
"flex",
|
|
845
|
+
"scale",
|
|
846
|
+
"priority",
|
|
847
|
+
"openai-only",
|
|
848
|
+
"claude-only",
|
|
849
|
+
] as const,
|
|
850
|
+
default: "inherit",
|
|
851
|
+
ui: {
|
|
852
|
+
tab: "tasks",
|
|
853
|
+
label: "Subagent Service Tier",
|
|
854
|
+
description:
|
|
855
|
+
'Service tier applied to task-tool subagents only. "inherit" copies the main session tier; any explicit value overrides it for subagents without touching the main session.',
|
|
856
|
+
options: [
|
|
857
|
+
{
|
|
858
|
+
value: "inherit",
|
|
859
|
+
label: "Inherit",
|
|
860
|
+
description: "Use the main session's service tier (default)",
|
|
861
|
+
},
|
|
862
|
+
{ value: "none", label: "None", description: "Omit service_tier for subagents" },
|
|
863
|
+
{ value: "auto", label: "Auto", description: "Use provider default tier selection (OpenAI)" },
|
|
864
|
+
{ value: "default", label: "Default", description: "Standard priority processing (OpenAI)" },
|
|
865
|
+
{ value: "flex", label: "Flex", description: "Flexible capacity tier when available (OpenAI)" },
|
|
866
|
+
{ value: "scale", label: "Scale", description: "Scale Tier credits when available (OpenAI)" },
|
|
867
|
+
{
|
|
868
|
+
value: "priority",
|
|
869
|
+
label: "Priority",
|
|
870
|
+
description: "Priority on every supported provider (OpenAI `service_tier`, Anthropic fast mode)",
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
value: "openai-only",
|
|
874
|
+
label: "Priority (OpenAI only)",
|
|
875
|
+
description: "Priority on OpenAI/OpenAI-Codex requests; ignored elsewhere",
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
value: "claude-only",
|
|
879
|
+
label: "Priority (Claude only)",
|
|
880
|
+
description: "Anthropic fast mode on direct Claude requests; ignored elsewhere (incl. Bedrock/Vertex)",
|
|
881
|
+
},
|
|
882
|
+
],
|
|
883
|
+
},
|
|
884
|
+
},
|
|
885
|
+
|
|
835
886
|
// Retries
|
|
836
887
|
"retry.enabled": { type: "boolean", default: true },
|
|
837
888
|
|
|
@@ -2068,6 +2119,17 @@ export const SETTINGS_SCHEMA = {
|
|
|
2068
2119
|
ui: { tab: "tools", label: "Web Search", description: "Enable the web_search tool for web searching" },
|
|
2069
2120
|
},
|
|
2070
2121
|
|
|
2122
|
+
"web_search.fallback": {
|
|
2123
|
+
type: "array",
|
|
2124
|
+
default: EMPTY_STRING_ARRAY,
|
|
2125
|
+
items: { enum: CONFIGURABLE_SEARCH_PROVIDER_IDS },
|
|
2126
|
+
ui: {
|
|
2127
|
+
tab: "tools",
|
|
2128
|
+
label: "Web Search Fallback",
|
|
2129
|
+
description: "Ordered fallback web search providers after the active model native provider",
|
|
2130
|
+
},
|
|
2131
|
+
},
|
|
2132
|
+
|
|
2071
2133
|
"browser.enabled": {
|
|
2072
2134
|
type: "boolean",
|
|
2073
2135
|
default: true,
|
|
@@ -9,6 +9,7 @@ export const COORDINATOR_MCP_TOOL_NAMES = [
|
|
|
9
9
|
"gjc_coordinator_list_artifacts",
|
|
10
10
|
"gjc_coordinator_read_artifact",
|
|
11
11
|
"gjc_coordinator_read_coordination_status",
|
|
12
|
+
"gjc_coordinator_watch_events",
|
|
12
13
|
"gjc_coordinator_register_session",
|
|
13
14
|
"gjc_coordinator_start_session",
|
|
14
15
|
"gjc_coordinator_send_prompt",
|