@nathapp/nax 0.82.0 → 0.82.1
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/README.md +4 -3
- package/dist/nax.js +352 -88
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -145,7 +145,7 @@ For full flag details, see the [CLI Reference](docs/guides/cli-reference.md).
|
|
|
145
145
|
|
|
146
146
|
`execution.commandInterceptor` rewrites the `Git` tool's argv through `rtk` so `log` and `diff` output reaches the model compressed. It is confined to the Git site: user-authored `quality.commands` and `acceptance.command` are never wrapped. It fails open — if the `rtk` binary is missing the call runs as plain git.
|
|
147
147
|
|
|
148
|
-
**Both features are native-agent only.** An ACP agent (`claude`, `codex`, `opencode`, `gemini`) brings its own tools, so nax's `Git` tool is never invoked and no MCP tool is advertised. A project on `"protocol": "acp"` can hold a complete, valid config for both and get zero effect, with no error.
|
|
148
|
+
**Both features are native-agent only.** An ACP agent (`claude`, `codex`, `opencode`, `gemini`) brings its own tools, so nax's `Git` tool is never invoked and no MCP tool is advertised. A project on `"protocol": "acp"` can hold a complete, valid config for both and get zero effect, with no error. The built-in defaults (`agent.protocol: "hybrid"`, `agent.default: "native"`) enable both; a config that switches to an acpx agent does not.
|
|
149
149
|
|
|
150
150
|
See [MCP & Command Interception](docs/guides/mcp-and-interception.md) for setup, verification and troubleshooting, and the [Configuration Guide](docs/guides/configuration.md) for the full schema.
|
|
151
151
|
|
|
@@ -209,11 +209,12 @@ See [Plugins Guide](docs/guides/agents.md#plugins).
|
|
|
209
209
|
|
|
210
210
|
## Agents
|
|
211
211
|
|
|
212
|
-
nax
|
|
212
|
+
The default agent is `native`: nax drives the model in-process over `@nathapp/nax-ai` (no CLI binary), using the built-in `models.native` Anthropic tier map, so it needs Anthropic credentials (`nax auth` or the provider's environment variable) unless you override the map. Every other agent is reached via [ACP](https://github.com/openclaw/acpx) (Agent Client Protocol) — a JSON-RPC protocol that provides persistent sessions, exact token/cost reporting, and multi-turn session continuity.
|
|
213
213
|
|
|
214
214
|
| Agent | Binary | Notes |
|
|
215
215
|
|:------|:-------|:------|
|
|
216
|
-
|
|
|
216
|
+
| Native (nax-ai) | — (in-process) | Default. `agent.default: "native"` |
|
|
217
|
+
| Claude Code | `claude` | Set `agent.default: "claude"` |
|
|
217
218
|
| OpenCode | `opencode` | Set `agent.default: "opencode"` |
|
|
218
219
|
| Codex | `codex` | Set `agent.default: "codex"` |
|
|
219
220
|
| Gemini CLI | `gemini` | Set `agent.default: "gemini"` |
|
package/dist/nax.js
CHANGED
|
@@ -2668,7 +2668,7 @@ var package_default;
|
|
|
2668
2668
|
var init_package = __esm(() => {
|
|
2669
2669
|
package_default = {
|
|
2670
2670
|
name: "@nathapp/nax",
|
|
2671
|
-
version: "0.82.
|
|
2671
|
+
version: "0.82.1",
|
|
2672
2672
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
2673
2673
|
type: "module",
|
|
2674
2674
|
bin: {
|
|
@@ -4047,6 +4047,26 @@ var init_types2 = __esm(() => {
|
|
|
4047
4047
|
};
|
|
4048
4048
|
});
|
|
4049
4049
|
|
|
4050
|
+
// src/config/agent-defaults.ts
|
|
4051
|
+
function isBuiltInModelMap(agent, entry) {
|
|
4052
|
+
if (!Object.hasOwn(DEFAULT_MODEL_MAPS, agent) || typeof entry !== "object" || entry === null)
|
|
4053
|
+
return false;
|
|
4054
|
+
const builtIn = DEFAULT_MODEL_MAPS[agent];
|
|
4055
|
+
const tiers = Object.entries(entry);
|
|
4056
|
+
return tiers.length === Object.keys(builtIn).length && tiers.every(([tier, value]) => Object.hasOwn(builtIn, tier) && builtIn[tier] === value);
|
|
4057
|
+
}
|
|
4058
|
+
var DEFAULT_AGENT_PROTOCOL = "hybrid", DEFAULT_AGENT_NAME = "native", NATIVE_AGENT_NAME = "native", DEFAULT_MODEL_MAPS;
|
|
4059
|
+
var init_agent_defaults = __esm(() => {
|
|
4060
|
+
DEFAULT_MODEL_MAPS = {
|
|
4061
|
+
claude: { fast: "haiku", balanced: "sonnet", powerful: "opus" },
|
|
4062
|
+
native: {
|
|
4063
|
+
fast: "anthropic/claude-haiku-4-5",
|
|
4064
|
+
balanced: "anthropic/claude-sonnet-5",
|
|
4065
|
+
powerful: "anthropic/claude-opus-5-5"
|
|
4066
|
+
}
|
|
4067
|
+
};
|
|
4068
|
+
});
|
|
4069
|
+
|
|
4050
4070
|
// node_modules/zod/v4/core/core.js
|
|
4051
4071
|
function $constructor(name, initializer, params) {
|
|
4052
4072
|
function init(inst, def) {
|
|
@@ -17936,7 +17956,7 @@ var init_schemas_sandbox = __esm(() => {
|
|
|
17936
17956
|
SANDBOX_GLOB_CHARS = /[*?[\]{}]/;
|
|
17937
17957
|
literalPath = exports_external.string().refine((p) => !SANDBOX_GLOB_CHARS.test(p), "sandbox paths must be literal: no * ? [ ] { } (spec F1)");
|
|
17938
17958
|
SandboxConfigSchema = exports_external.object({
|
|
17939
|
-
enabled: exports_external.boolean().default(
|
|
17959
|
+
enabled: exports_external.boolean().default(true),
|
|
17940
17960
|
backend: exports_external.enum(["srt"]).default("srt"),
|
|
17941
17961
|
filesystem: exports_external.object({
|
|
17942
17962
|
allowWrite: exports_external.array(literalPath).default([]),
|
|
@@ -18184,7 +18204,7 @@ async function runArgv(options) {
|
|
|
18184
18204
|
stdoutController.abort();
|
|
18185
18205
|
stderrController.abort();
|
|
18186
18206
|
};
|
|
18187
|
-
const timerId = setTimeout(() => {
|
|
18207
|
+
const timerId = _argvExecDeps.setTimeout(() => {
|
|
18188
18208
|
timedOut = true;
|
|
18189
18209
|
killGroup();
|
|
18190
18210
|
stopReaders();
|
|
@@ -18201,7 +18221,7 @@ async function runArgv(options) {
|
|
|
18201
18221
|
const graceMs = _argvExecDeps.drainGraceMs;
|
|
18202
18222
|
let graceTimerId;
|
|
18203
18223
|
const gracePromise = new Promise((resolve3) => {
|
|
18204
|
-
graceTimerId = setTimeout(() => resolve3("expired"), graceMs);
|
|
18224
|
+
graceTimerId = _argvExecDeps.setTimeout(() => resolve3("expired"), graceMs);
|
|
18205
18225
|
});
|
|
18206
18226
|
const stdoutSettled = await Promise.race([
|
|
18207
18227
|
stdoutPromise,
|
|
@@ -18212,7 +18232,7 @@ async function runArgv(options) {
|
|
|
18212
18232
|
gracePromise.then(() => "expired")
|
|
18213
18233
|
]);
|
|
18214
18234
|
if (graceTimerId !== undefined)
|
|
18215
|
-
clearTimeout(graceTimerId);
|
|
18235
|
+
_argvExecDeps.clearTimeout(graceTimerId);
|
|
18216
18236
|
const stdoutClosed = stdoutSettled !== "expired";
|
|
18217
18237
|
const stderrClosed = stderrSettled !== "expired";
|
|
18218
18238
|
if (!stdoutClosed || !stderrClosed) {
|
|
@@ -18225,7 +18245,7 @@ async function runArgv(options) {
|
|
|
18225
18245
|
}
|
|
18226
18246
|
const stdoutFinal = stdoutClosed ? stdoutSettled : await stdoutPromise;
|
|
18227
18247
|
const stderrFinal = stderrClosed ? stderrSettled : await stderrPromise;
|
|
18228
|
-
clearTimeout(timerId);
|
|
18248
|
+
_argvExecDeps.clearTimeout(timerId);
|
|
18229
18249
|
signal?.removeEventListener("abort", onAbort);
|
|
18230
18250
|
return {
|
|
18231
18251
|
exitCode,
|
|
@@ -18242,7 +18262,9 @@ var init_argv_exec = __esm(() => {
|
|
|
18242
18262
|
_argvExecDeps = {
|
|
18243
18263
|
spawn,
|
|
18244
18264
|
killProcessGroup,
|
|
18245
|
-
drainGraceMs: DRAIN_GRACE_MS
|
|
18265
|
+
drainGraceMs: DRAIN_GRACE_MS,
|
|
18266
|
+
setTimeout: (fn, ms) => setTimeout(fn, ms),
|
|
18267
|
+
clearTimeout: (id) => clearTimeout(id)
|
|
18246
18268
|
};
|
|
18247
18269
|
});
|
|
18248
18270
|
|
|
@@ -19638,7 +19660,8 @@ ${launched.stderr}`;
|
|
|
19638
19660
|
isError: launched.timedOut || launched.exitCode !== 0 || launched.aborted === true,
|
|
19639
19661
|
audit: {
|
|
19640
19662
|
executed: launched.executed,
|
|
19641
|
-
...launched.sandbox !== undefined ? { sandbox: launched.sandbox } : {}
|
|
19663
|
+
...launched.sandbox !== undefined ? { sandbox: launched.sandbox } : {},
|
|
19664
|
+
...!launched.timedOut && launched.aborted !== true ? { exitCode: launched.exitCode } : {}
|
|
19642
19665
|
},
|
|
19643
19666
|
resultBytesPreTruncation: Buffer.byteLength(body, "utf8")
|
|
19644
19667
|
};
|
|
@@ -23563,15 +23586,36 @@ var init_types3 = __esm(() => {
|
|
|
23563
23586
|
});
|
|
23564
23587
|
|
|
23565
23588
|
// src/command-safety/rule-scorer.ts
|
|
23566
|
-
|
|
23589
|
+
import { posix } from "path";
|
|
23590
|
+
function escapeRegExp(text) {
|
|
23591
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
23592
|
+
}
|
|
23593
|
+
function usableRoot(root) {
|
|
23594
|
+
if (root === undefined || !root.startsWith("/"))
|
|
23595
|
+
return;
|
|
23596
|
+
const normalized = posix.normalize(root).replace(/\/+$/, "");
|
|
23597
|
+
return normalized.split("/").filter(Boolean).length >= MIN_ROOT_SEGMENTS ? normalized : undefined;
|
|
23598
|
+
}
|
|
23599
|
+
function maskProjectRoot(command, root) {
|
|
23600
|
+
const usable = usableRoot(root);
|
|
23601
|
+
if (usable === undefined)
|
|
23602
|
+
return command;
|
|
23603
|
+
const underRoot = new RegExp(`(?<=^|[${PATH_END}=:])${escapeRegExp(usable)}((?:/[^${PATH_END}]*)?)(?=$|[${PATH_END}])`, "g");
|
|
23604
|
+
return command.replace(underRoot, (match, rest, offset) => {
|
|
23605
|
+
CLEAN_TAIL.lastIndex = offset + match.length;
|
|
23606
|
+
return /\.\.|\\|,/.test(rest) || !CLEAN_TAIL.test(command) ? match : `.${rest}`;
|
|
23607
|
+
});
|
|
23608
|
+
}
|
|
23609
|
+
function scoreRules(command, context = {}) {
|
|
23567
23610
|
try {
|
|
23568
|
-
const
|
|
23611
|
+
const masked = maskProjectRoot(command, context.root);
|
|
23612
|
+
const hits = Object.fromEntries(QUESTION_IDS.map((id) => [id, RULES[id].some((re) => re.test(id === "outside_project" ? masked : command))]));
|
|
23569
23613
|
return { version: RULE_SET_VERSION, hits };
|
|
23570
23614
|
} catch (err) {
|
|
23571
23615
|
return { version: RULE_SET_VERSION, hits: NO_HITS, error: errorMessage(err) };
|
|
23572
23616
|
}
|
|
23573
23617
|
}
|
|
23574
|
-
var RULE_SET_VERSION =
|
|
23618
|
+
var RULE_SET_VERSION = 2, RULES, NO_HITS, PATH_END, CLEAN_TAIL, MIN_ROOT_SEGMENTS = 2;
|
|
23575
23619
|
var init_rule_scorer = __esm(() => {
|
|
23576
23620
|
init_types3();
|
|
23577
23621
|
RULES = {
|
|
@@ -23617,6 +23661,8 @@ var init_rule_scorer = __esm(() => {
|
|
|
23617
23661
|
privilege: [/(?:^|[\s;&|(])(?:sudo|doas)\s/, /\b(?:chmod|chown|chgrp)\b/]
|
|
23618
23662
|
};
|
|
23619
23663
|
NO_HITS = Object.freeze(Object.fromEntries(QUESTION_IDS.map((id) => [id, false])));
|
|
23664
|
+
PATH_END = String.raw`\s'"\`;&|<>()`;
|
|
23665
|
+
CLEAN_TAIL = /['")]*(?=$|[\s;&|<>])/y;
|
|
23620
23666
|
});
|
|
23621
23667
|
|
|
23622
23668
|
// src/command-safety/shadow.ts
|
|
@@ -23664,6 +23710,7 @@ function createCommandShadow(opts) {
|
|
|
23664
23710
|
const { obs } = entry;
|
|
23665
23711
|
const r = model.result;
|
|
23666
23712
|
const cwd = entry.run?.cwd ?? obs.cwd;
|
|
23713
|
+
const rules = cwd !== obs.cwd ? scoreRules(obs.command, { root: cwd }) : entry.rules;
|
|
23667
23714
|
return {
|
|
23668
23715
|
at: _commandShadowDeps.now(),
|
|
23669
23716
|
runId: opts.runId,
|
|
@@ -23676,7 +23723,7 @@ function createCommandShadow(opts) {
|
|
|
23676
23723
|
...cwd !== undefined ? { cwd } : {},
|
|
23677
23724
|
mechanical: obs.mechanical,
|
|
23678
23725
|
outcome,
|
|
23679
|
-
rules
|
|
23726
|
+
rules,
|
|
23680
23727
|
...callIdentifiers(obs),
|
|
23681
23728
|
model: {
|
|
23682
23729
|
status: model.cached && r.status === "answered" ? "cached" : r.status,
|
|
@@ -23694,7 +23741,7 @@ function createCommandShadow(opts) {
|
|
|
23694
23741
|
try {
|
|
23695
23742
|
if (entries.has(key))
|
|
23696
23743
|
return;
|
|
23697
|
-
const entry = { obs, rules: scoreRules(obs.command), written: false };
|
|
23744
|
+
const entry = { obs, rules: scoreRules(obs.command, { root: obs.cwd }), written: false };
|
|
23698
23745
|
entries.set(key, entry);
|
|
23699
23746
|
const { promise: promise2, cached: cached2 } = classifyCached(obs.command);
|
|
23700
23747
|
track(inFlight2, promise2.then((result) => {
|
|
@@ -24524,6 +24571,7 @@ function createCodingToolRuntime(opts) {
|
|
|
24524
24571
|
...audit?.target !== undefined ? { target: audit.target } : {},
|
|
24525
24572
|
...audit?.approval !== undefined ? { approval: audit.approval } : {},
|
|
24526
24573
|
...audit?.sandbox !== undefined ? { sandbox: audit.sandbox } : {},
|
|
24574
|
+
...audit?.exitCode !== undefined ? { exitCode: audit.exitCode } : {},
|
|
24527
24575
|
...provider !== undefined ? { provider } : {},
|
|
24528
24576
|
...resultBytesPreTruncation !== undefined ? { resultBytesPreTruncation } : {},
|
|
24529
24577
|
...opts.callId !== undefined ? { callId: opts.callId } : {},
|
|
@@ -26802,6 +26850,7 @@ var init_schemas_execution = __esm(() => {
|
|
|
26802
26850
|
var PlanConfigSchema, AcceptanceFixConfigSchema, AcceptanceConfigSchema, LlmRoutingConfigSchema, AgentRoutingProfileSchema, AgentRoutingConfigSchema, RoutingConfigSchema, OptimizerConfigSchema, PluginConfigEntrySchema, HooksConfigSchema, InteractionConfigSchema, StorySizeGateConfigSchema, PromptAuditConfigSchema, UsageAuditConfigSchema, FallbackTargetSchema, AgentFallbackConfigSchema, DEFAULT_AGENT_IDLE_WATCHDOG_CONFIG, AgentIdleWatchdogConfigSchema, DEFAULT_AGENT_SPIN_BREAKER_CONFIG, AgentSpinBreakerConfigSchema, AgentAcpConfigSchema, AgentNativeTransportRetryConfigSchema, AgentNativeConfigSchema, AgentTimeoutRetryConfigSchema, DEFAULT_AGENT_TIMEOUT_RETRY_CONFIG, AgentConfigSchema, PrecheckConfigSchema, PromptsConfigSchema, ProjectProfileSchema, VALID_AGENT_TYPES, GenerateConfigSchema, CuratorThresholdsSchema, CuratorRetentionConfigSchema, CuratorConfigSchema;
|
|
26803
26851
|
var init_schemas_infra = __esm(() => {
|
|
26804
26852
|
init_zod();
|
|
26853
|
+
init_agent_defaults();
|
|
26805
26854
|
init_schemas_model();
|
|
26806
26855
|
PlanConfigSchema = exports_external.object({
|
|
26807
26856
|
model: ConfiguredModelSchema,
|
|
@@ -27021,8 +27070,8 @@ var init_schemas_infra = __esm(() => {
|
|
|
27021
27070
|
budgetMultiplier: 0.5
|
|
27022
27071
|
};
|
|
27023
27072
|
AgentConfigSchema = exports_external.object({
|
|
27024
|
-
protocol: exports_external.enum(["acp", "native", "hybrid"]).default(
|
|
27025
|
-
default: exports_external.string().trim().min(1, "agent.default must be non-empty").default(
|
|
27073
|
+
protocol: exports_external.enum(["acp", "native", "hybrid"]).default(DEFAULT_AGENT_PROTOCOL),
|
|
27074
|
+
default: exports_external.string().trim().min(1, "agent.default must be non-empty").default(DEFAULT_AGENT_NAME),
|
|
27026
27075
|
maxInteractionTurns: exports_external.number().int().min(1).max(100).default(20),
|
|
27027
27076
|
promptAudit: PromptAuditConfigSchema.default({ enabled: false }),
|
|
27028
27077
|
usageAudit: UsageAuditConfigSchema.default({ enabled: false }),
|
|
@@ -27101,19 +27150,29 @@ var init_schemas_infra = __esm(() => {
|
|
|
27101
27150
|
function asModelDef(entry) {
|
|
27102
27151
|
return typeof entry === "object" && entry !== null ? entry : null;
|
|
27103
27152
|
}
|
|
27153
|
+
function declaredModelAgents(models) {
|
|
27154
|
+
return Object.entries(models ?? {}).filter(([agent, entry]) => !isBuiltInModelMap(agent, entry)).map(([agent]) => agent);
|
|
27155
|
+
}
|
|
27104
27156
|
function validateProtocolGate(data, ctx) {
|
|
27105
|
-
const protocol = data.agent?.protocol ??
|
|
27106
|
-
const modelAgents =
|
|
27107
|
-
if (protocol ===
|
|
27157
|
+
const protocol = data.agent?.protocol ?? DEFAULT_AGENT_PROTOCOL;
|
|
27158
|
+
const modelAgents = declaredModelAgents(data.models);
|
|
27159
|
+
if (protocol === "acp" && (data.agent?.default ?? DEFAULT_AGENT_NAME) === NATIVE_AGENT_NAME) {
|
|
27160
|
+
ctx.addIssue({
|
|
27161
|
+
code: "custom",
|
|
27162
|
+
path: ["agent", "default"],
|
|
27163
|
+
message: 'agent.protocol "acp" cannot reach agent.default "native", which is also the built-in default when agent.default is unset. Set agent.default to an acpx agent such as "claude", or use agent.protocol "hybrid".'
|
|
27164
|
+
});
|
|
27165
|
+
}
|
|
27166
|
+
if (protocol === "acp" && modelAgents.includes(NATIVE_AGENT_NAME)) {
|
|
27108
27167
|
ctx.addIssue({
|
|
27109
27168
|
code: "custom",
|
|
27110
|
-
path: ["models",
|
|
27169
|
+
path: ["models", NATIVE_AGENT_NAME],
|
|
27111
27170
|
message: 'models.native requires agent.protocol "hybrid" or "native" (it is "acp"). Set agent.protocol, or remove the native entry.'
|
|
27112
27171
|
});
|
|
27113
27172
|
}
|
|
27114
|
-
if (protocol ===
|
|
27173
|
+
if (protocol === NATIVE_AGENT_NAME) {
|
|
27115
27174
|
for (const agent of modelAgents) {
|
|
27116
|
-
if (agent ===
|
|
27175
|
+
if (agent === NATIVE_AGENT_NAME)
|
|
27117
27176
|
continue;
|
|
27118
27177
|
ctx.addIssue({
|
|
27119
27178
|
code: "custom",
|
|
@@ -27121,7 +27180,7 @@ function validateProtocolGate(data, ctx) {
|
|
|
27121
27180
|
message: `agent.protocol "native" permits only models.native; "${agent}" is an acpx agent. Use "hybrid" to run both.`
|
|
27122
27181
|
});
|
|
27123
27182
|
}
|
|
27124
|
-
if ((data.agent?.default ??
|
|
27183
|
+
if ((data.agent?.default ?? DEFAULT_AGENT_NAME) !== NATIVE_AGENT_NAME) {
|
|
27125
27184
|
ctx.addIssue({
|
|
27126
27185
|
code: "custom",
|
|
27127
27186
|
path: ["agent", "default"],
|
|
@@ -27133,7 +27192,7 @@ function validateProtocolGate(data, ctx) {
|
|
|
27133
27192
|
validateFallbackLadderAgents(data, ctx);
|
|
27134
27193
|
}
|
|
27135
27194
|
function validateNativeModelIds(data, ctx) {
|
|
27136
|
-
for (const [tier, entry] of Object.entries(data.models?.[
|
|
27195
|
+
for (const [tier, entry] of Object.entries(data.models?.[NATIVE_AGENT_NAME] ?? {})) {
|
|
27137
27196
|
if (entry === undefined)
|
|
27138
27197
|
continue;
|
|
27139
27198
|
const def = asModelDef(entry);
|
|
@@ -27145,8 +27204,8 @@ function validateNativeModelIds(data, ctx) {
|
|
|
27145
27204
|
const sibling = def && typeof def.provider === "string" ? def.provider.trim() : "";
|
|
27146
27205
|
ctx.addIssue({
|
|
27147
27206
|
code: "custom",
|
|
27148
|
-
path: ["models",
|
|
27149
|
-
message: sibling.length > 0 ? `models.${
|
|
27207
|
+
path: ["models", NATIVE_AGENT_NAME, tier, ...def ? ["model"] : []],
|
|
27208
|
+
message: sibling.length > 0 ? `models.${NATIVE_AGENT_NAME}.${tier}.model "${modelId}" must be written "provider/model". The sibling "provider" field is not used on the native path \u2014 put it in the model id: "${sibling}/${modelId}".` : `models.${NATIVE_AGENT_NAME}.${tier} "${modelId}" must be written "provider/model" (e.g. "openai/gpt-5.4-mini"). There is no default provider.`
|
|
27150
27209
|
});
|
|
27151
27210
|
}
|
|
27152
27211
|
}
|
|
@@ -27161,12 +27220,12 @@ function rungAgent(value) {
|
|
|
27161
27220
|
return;
|
|
27162
27221
|
}
|
|
27163
27222
|
function validateFallbackLadderAgents(data, ctx) {
|
|
27164
|
-
const protocol = data.agent?.protocol ??
|
|
27223
|
+
const protocol = data.agent?.protocol ?? DEFAULT_AGENT_PROTOCOL;
|
|
27165
27224
|
if (protocol === "hybrid")
|
|
27166
27225
|
return;
|
|
27167
27226
|
const map2 = data.agent?.fallback?.map ?? {};
|
|
27168
27227
|
const reject = (agent, path) => {
|
|
27169
|
-
const permitted = protocol ===
|
|
27228
|
+
const permitted = protocol === NATIVE_AGENT_NAME ? `only "${NATIVE_AGENT_NAME}"` : `no native agent`;
|
|
27170
27229
|
ctx.addIssue({
|
|
27171
27230
|
code: "custom",
|
|
27172
27231
|
path,
|
|
@@ -27174,7 +27233,7 @@ function validateFallbackLadderAgents(data, ctx) {
|
|
|
27174
27233
|
});
|
|
27175
27234
|
};
|
|
27176
27235
|
for (const [from, rungs] of Object.entries(map2)) {
|
|
27177
|
-
const offending = (agent) => protocol ===
|
|
27236
|
+
const offending = (agent) => protocol === NATIVE_AGENT_NAME ? agent !== NATIVE_AGENT_NAME : agent === NATIVE_AGENT_NAME;
|
|
27178
27237
|
if (offending(from))
|
|
27179
27238
|
reject(from, ["agent", "fallback", "map", from]);
|
|
27180
27239
|
(rungs ?? []).forEach((rung, index) => {
|
|
@@ -27184,9 +27243,9 @@ function validateFallbackLadderAgents(data, ctx) {
|
|
|
27184
27243
|
});
|
|
27185
27244
|
}
|
|
27186
27245
|
}
|
|
27187
|
-
var NATIVE = "native", DEFAULT_PROTOCOL = "acp", DEFAULT_AGENT = "claude";
|
|
27188
27246
|
var init_schemas_protocol_gate = __esm(() => {
|
|
27189
27247
|
init_model_spec();
|
|
27248
|
+
init_agent_defaults();
|
|
27190
27249
|
});
|
|
27191
27250
|
|
|
27192
27251
|
// src/config/schemas-reporters.ts
|
|
@@ -27350,6 +27409,7 @@ var init_schemas_review = __esm(() => {
|
|
|
27350
27409
|
var NaxConfigSchema;
|
|
27351
27410
|
var init_schemas3 = __esm(() => {
|
|
27352
27411
|
init_zod();
|
|
27412
|
+
init_agent_defaults();
|
|
27353
27413
|
init_bash_approval();
|
|
27354
27414
|
init_schema_types();
|
|
27355
27415
|
init_schemas_context();
|
|
@@ -27379,13 +27439,7 @@ var init_schemas3 = __esm(() => {
|
|
|
27379
27439
|
message: "outputDir must be absolute or start with ~/"
|
|
27380
27440
|
}),
|
|
27381
27441
|
version: exports_external.number().default(1),
|
|
27382
|
-
models: ModelMapSchema.default(
|
|
27383
|
-
claude: {
|
|
27384
|
-
fast: "haiku",
|
|
27385
|
-
balanced: "sonnet",
|
|
27386
|
-
powerful: "opus"
|
|
27387
|
-
}
|
|
27388
|
-
}),
|
|
27442
|
+
models: ModelMapSchema.default(structuredClone(DEFAULT_MODEL_MAPS)),
|
|
27389
27443
|
autoMode: AutoModeConfigSchema.default({
|
|
27390
27444
|
enabled: true,
|
|
27391
27445
|
complexityRouting: {
|
|
@@ -27596,8 +27650,8 @@ var init_schemas3 = __esm(() => {
|
|
|
27596
27650
|
}
|
|
27597
27651
|
}),
|
|
27598
27652
|
agent: AgentConfigSchema.optional().default({
|
|
27599
|
-
protocol:
|
|
27600
|
-
default:
|
|
27653
|
+
protocol: DEFAULT_AGENT_PROTOCOL,
|
|
27654
|
+
default: DEFAULT_AGENT_NAME,
|
|
27601
27655
|
maxInteractionTurns: 20,
|
|
27602
27656
|
promptAudit: { enabled: false },
|
|
27603
27657
|
usageAudit: { enabled: false },
|
|
@@ -27699,7 +27753,7 @@ var init_schemas3 = __esm(() => {
|
|
|
27699
27753
|
for (const [pi, profile] of profiles.entries()) {
|
|
27700
27754
|
const { agent: pAgent, model: pModel } = profile.target;
|
|
27701
27755
|
const targetTier = MODEL_SHORTHAND_TIERS[pModel.toLowerCase()] ?? pModel;
|
|
27702
|
-
const namesTier = resolveTierMembership(data.models ?? {}, pAgent, targetTier, data.agent?.default ??
|
|
27756
|
+
const namesTier = resolveTierMembership(data.models ?? {}, pAgent, targetTier, data.agent?.default ?? DEFAULT_AGENT_NAME).isTier;
|
|
27703
27757
|
const hasMatchingRung = tierOrder.some((r) => r.tier === targetTier && r.agent === pAgent);
|
|
27704
27758
|
if (namesTier && !hasMatchingRung) {
|
|
27705
27759
|
ctx.addIssue({
|
|
@@ -28312,6 +28366,57 @@ function trackedSpawnDeadlines(config2) {
|
|
|
28312
28366
|
};
|
|
28313
28367
|
}
|
|
28314
28368
|
|
|
28369
|
+
// src/config/unreferenced-agent-models.ts
|
|
28370
|
+
function isPin(value) {
|
|
28371
|
+
return typeof value.agent === "string" && (("model" in value) || ("tier" in value));
|
|
28372
|
+
}
|
|
28373
|
+
function pinAgents(value, found) {
|
|
28374
|
+
if (Array.isArray(value)) {
|
|
28375
|
+
for (const item of value)
|
|
28376
|
+
pinAgents(item, found);
|
|
28377
|
+
return;
|
|
28378
|
+
}
|
|
28379
|
+
if (typeof value !== "object" || value === null)
|
|
28380
|
+
return;
|
|
28381
|
+
const record3 = value;
|
|
28382
|
+
if (isPin(record3))
|
|
28383
|
+
found.add(record3.agent);
|
|
28384
|
+
for (const child of Object.values(record3))
|
|
28385
|
+
pinAgents(child, found);
|
|
28386
|
+
}
|
|
28387
|
+
function fallbackAgents(config2) {
|
|
28388
|
+
const fallback = config2.agent?.fallback;
|
|
28389
|
+
if (fallback?.enabled !== true)
|
|
28390
|
+
return [];
|
|
28391
|
+
return Object.values(fallback.map ?? {}).flatMap((rungs) => (rungs ?? []).map((rung) => typeof rung === "string" ? rung : rung.agent));
|
|
28392
|
+
}
|
|
28393
|
+
function findUnreferencedAgentModels(config2, storyAgents = []) {
|
|
28394
|
+
const reached = new Set([
|
|
28395
|
+
config2.agent?.default ?? DEFAULT_AGENT_NAME,
|
|
28396
|
+
...fallbackAgents(config2),
|
|
28397
|
+
...storyAgents
|
|
28398
|
+
]);
|
|
28399
|
+
for (const [key, value] of Object.entries(config2)) {
|
|
28400
|
+
if (!SKIPPED_ROOT_KEYS.has(key))
|
|
28401
|
+
pinAgents(value, reached);
|
|
28402
|
+
}
|
|
28403
|
+
return Object.entries(config2.models ?? {}).filter(([agent, map2]) => agent !== NATIVE_AGENT_NAME && !isBuiltInModelMap(agent, map2) && !reached.has(agent)).map(([agent]) => agent);
|
|
28404
|
+
}
|
|
28405
|
+
function describeUnreferencedAgentModels(agents, config2) {
|
|
28406
|
+
const maps = agents.map((agent) => `models.${agent}`).join(", ");
|
|
28407
|
+
const head = `${maps} is declared but nothing dispatches to it: no agent.default, enabled fallback rung, pin, escalation rung, ` + `complexity route, routing profile or PRD story names ${agents.join(", ")}.`;
|
|
28408
|
+
if (config2.agent?.protocol === "native") {
|
|
28409
|
+
return `${head} Under agent.protocol "native" acpx agents cannot run; remove the map or use protocol "hybrid".`;
|
|
28410
|
+
}
|
|
28411
|
+
const defaultAgent = config2.agent?.default ?? DEFAULT_AGENT_NAME;
|
|
28412
|
+
return `${head} Unassigned work runs on agent.default "${defaultAgent}". ` + `Set agent.default "${agents[0]}" to run it, or reference it from a pin or fallback rung.`;
|
|
28413
|
+
}
|
|
28414
|
+
var SKIPPED_ROOT_KEYS;
|
|
28415
|
+
var init_unreferenced_agent_models = __esm(() => {
|
|
28416
|
+
init_agent_defaults();
|
|
28417
|
+
SKIPPED_ROOT_KEYS = new Set(["models", "agent"]);
|
|
28418
|
+
});
|
|
28419
|
+
|
|
28315
28420
|
// src/config/validate.ts
|
|
28316
28421
|
function validateConfig(config2) {
|
|
28317
28422
|
const errors3 = [];
|
|
@@ -28322,7 +28427,7 @@ function validateConfig(config2) {
|
|
|
28322
28427
|
if (!config2.models) {
|
|
28323
28428
|
errors3.push("models mapping is required");
|
|
28324
28429
|
} else {
|
|
28325
|
-
const defaultAgent = config2.agent?.default ??
|
|
28430
|
+
const defaultAgent = config2.agent?.default ?? DEFAULT_AGENT_NAME;
|
|
28326
28431
|
const agentModels = config2.models[defaultAgent];
|
|
28327
28432
|
if (!agentModels) {
|
|
28328
28433
|
errors3.push(`models.${defaultAgent} is required (default agent has no model map)`);
|
|
@@ -28370,13 +28475,13 @@ function validateConfig(config2) {
|
|
|
28370
28475
|
}
|
|
28371
28476
|
if (config2.models && config2.agent?.fallback?.map) {
|
|
28372
28477
|
const modelKeys = Object.keys(config2.models);
|
|
28373
|
-
const
|
|
28478
|
+
const fallbackAgents2 = new Set;
|
|
28374
28479
|
for (const [primary, candidates] of Object.entries(config2.agent.fallback.map)) {
|
|
28375
|
-
|
|
28480
|
+
fallbackAgents2.add(primary);
|
|
28376
28481
|
for (const c of candidates)
|
|
28377
|
-
|
|
28482
|
+
fallbackAgents2.add(typeof c === "string" ? c : c.agent);
|
|
28378
28483
|
}
|
|
28379
|
-
for (const agent of
|
|
28484
|
+
for (const agent of fallbackAgents2) {
|
|
28380
28485
|
if (!modelKeys.includes(agent)) {
|
|
28381
28486
|
errors3.push(`agent.fallback.map: agent "${agent}" is not a key in models (available: ${modelKeys.join(", ")})`);
|
|
28382
28487
|
} else {
|
|
@@ -28395,7 +28500,7 @@ function validateConfig(config2) {
|
|
|
28395
28500
|
errors3.push(`autoMode.escalation.tierOrder: tier "${tc.tier}" agent "${tc.agent}" is not a key in models (available: ${modelKeys.join(", ")})`);
|
|
28396
28501
|
}
|
|
28397
28502
|
if (tc.agent === undefined) {
|
|
28398
|
-
const owner = config2.agent?.default ??
|
|
28503
|
+
const owner = config2.agent?.default ?? DEFAULT_AGENT_NAME;
|
|
28399
28504
|
const ownerMap = config2.models[owner];
|
|
28400
28505
|
if (ownerMap && ownerMap[tc.tier] === undefined) {
|
|
28401
28506
|
errors3.push(`autoMode.escalation.tierOrder: tier "${tc.tier}" does not resolve under agent "${owner}" (the default agent)`);
|
|
@@ -28403,7 +28508,7 @@ function validateConfig(config2) {
|
|
|
28403
28508
|
}
|
|
28404
28509
|
}
|
|
28405
28510
|
}
|
|
28406
|
-
const defaultAgentKey = config2.agent?.default ??
|
|
28511
|
+
const defaultAgentKey = config2.agent?.default ?? DEFAULT_AGENT_NAME;
|
|
28407
28512
|
const complexities = ["simple", "medium", "complex", "expert"];
|
|
28408
28513
|
for (const complexity of complexities) {
|
|
28409
28514
|
const entry = config2.autoMode.complexityRouting[complexity];
|
|
@@ -28430,6 +28535,9 @@ function validateConfig(config2) {
|
|
|
28430
28535
|
errors: errors3
|
|
28431
28536
|
};
|
|
28432
28537
|
}
|
|
28538
|
+
var init_validate = __esm(() => {
|
|
28539
|
+
init_agent_defaults();
|
|
28540
|
+
});
|
|
28433
28541
|
|
|
28434
28542
|
// src/config/index.ts
|
|
28435
28543
|
var exports_config = {};
|
|
@@ -28448,6 +28556,8 @@ __export(exports_config, {
|
|
|
28448
28556
|
ContextV2ConfigSchema: () => ContextV2ConfigSchema,
|
|
28449
28557
|
CuratorRetentionConfigSchema: () => CuratorRetentionConfigSchema,
|
|
28450
28558
|
DEFAULT_AGENT_IDLE_WATCHDOG_CONFIG: () => DEFAULT_AGENT_IDLE_WATCHDOG_CONFIG,
|
|
28559
|
+
DEFAULT_AGENT_NAME: () => DEFAULT_AGENT_NAME,
|
|
28560
|
+
DEFAULT_AGENT_PROTOCOL: () => DEFAULT_AGENT_PROTOCOL,
|
|
28451
28561
|
DEFAULT_AGENT_SPIN_BREAKER_CONFIG: () => DEFAULT_AGENT_SPIN_BREAKER_CONFIG,
|
|
28452
28562
|
DEFAULT_AGENT_TIMEOUT_RETRY_CONFIG: () => DEFAULT_AGENT_TIMEOUT_RETRY_CONFIG,
|
|
28453
28563
|
DEFAULT_CONFIG: () => DEFAULT_CONFIG,
|
|
@@ -28460,6 +28570,7 @@ __export(exports_config, {
|
|
|
28460
28570
|
MODEL_SHORTHAND_TIERS: () => MODEL_SHORTHAND_TIERS,
|
|
28461
28571
|
McpConfigSchema: () => McpConfigSchema,
|
|
28462
28572
|
ModelTierSchema: () => ModelTierSchema,
|
|
28573
|
+
NATIVE_AGENT_NAME: () => NATIVE_AGENT_NAME,
|
|
28463
28574
|
NaxConfigSchema: () => NaxConfigSchema,
|
|
28464
28575
|
PROJECT_FEATURES_DIR: () => PROJECT_FEATURES_DIR,
|
|
28465
28576
|
PROJECT_NAX_DIR: () => PROJECT_NAX_DIR,
|
|
@@ -28489,17 +28600,20 @@ __export(exports_config, {
|
|
|
28489
28600
|
createConfigLoader: () => createConfigLoader,
|
|
28490
28601
|
decomposeConfigSelector: () => decomposeConfigSelector,
|
|
28491
28602
|
deepMergeConfig: () => deepMergeConfig,
|
|
28603
|
+
describeUnreferencedAgentModels: () => describeUnreferencedAgentModels,
|
|
28492
28604
|
executionGatesConfigSelector: () => executionGatesConfigSelector,
|
|
28493
28605
|
featureDir: () => featureDir,
|
|
28494
28606
|
featuresDir: () => featuresDir,
|
|
28495
28607
|
findInertBashStages: () => findInertBashStages,
|
|
28496
28608
|
findProjectDir: () => findProjectDir,
|
|
28609
|
+
findUnreferencedAgentModels: () => findUnreferencedAgentModels,
|
|
28497
28610
|
finishConfigSelector: () => finishConfigSelector,
|
|
28498
28611
|
getAcQualityRules: () => getAcQualityRules,
|
|
28499
28612
|
getProjectKey: () => getProjectKey,
|
|
28500
28613
|
globalConfigDir: () => globalConfigDir,
|
|
28501
28614
|
globalConfigPath: () => globalConfigPath,
|
|
28502
28615
|
interactionConfigSelector: () => interactionConfigSelector,
|
|
28616
|
+
isBuiltInModelMap: () => isBuiltInModelMap,
|
|
28503
28617
|
isSingleSessionTestOwningStrategy: () => isSingleSessionTestOwningStrategy,
|
|
28504
28618
|
isThreeSessionStrategy: () => isThreeSessionStrategy,
|
|
28505
28619
|
isUnrecognizedLiteralModel: () => isUnrecognizedLiteralModel,
|
|
@@ -28549,6 +28663,7 @@ __export(exports_config, {
|
|
|
28549
28663
|
verifyConfigSelector: () => verifyConfigSelector
|
|
28550
28664
|
});
|
|
28551
28665
|
var init_config = __esm(() => {
|
|
28666
|
+
init_agent_defaults();
|
|
28552
28667
|
init_bash_approval();
|
|
28553
28668
|
init_inert_bash_stages();
|
|
28554
28669
|
init_loader();
|
|
@@ -28570,6 +28685,8 @@ var init_config = __esm(() => {
|
|
|
28570
28685
|
init_schemas_sandbox();
|
|
28571
28686
|
init_selectors();
|
|
28572
28687
|
init_test_strategy();
|
|
28688
|
+
init_unreferenced_agent_models();
|
|
28689
|
+
init_validate();
|
|
28573
28690
|
});
|
|
28574
28691
|
|
|
28575
28692
|
// src/agents/native/credentials.ts
|
|
@@ -28744,6 +28861,32 @@ async function ambientShadows(providerIds) {
|
|
|
28744
28861
|
}));
|
|
28745
28862
|
return checked.filter((id) => id !== undefined);
|
|
28746
28863
|
}
|
|
28864
|
+
async function providersWithoutCredentials(providerIds) {
|
|
28865
|
+
const unique = [...new Set(providerIds)];
|
|
28866
|
+
let stored;
|
|
28867
|
+
try {
|
|
28868
|
+
stored = new Set((await listStoredProviders()).map((entry) => entry.providerId));
|
|
28869
|
+
} catch {
|
|
28870
|
+
return [];
|
|
28871
|
+
}
|
|
28872
|
+
const sweep = Promise.all(unique.filter((providerId) => !stored.has(providerId)).map(async (providerId) => {
|
|
28873
|
+
try {
|
|
28874
|
+
return await _authDeps.ambientAuthAvailable(providerId) ? undefined : providerId;
|
|
28875
|
+
} catch {
|
|
28876
|
+
return;
|
|
28877
|
+
}
|
|
28878
|
+
})).then((missing) => missing.filter((id) => id !== undefined));
|
|
28879
|
+
let timer;
|
|
28880
|
+
const expiry = new Promise((resolve15) => {
|
|
28881
|
+
timer = setTimeout(() => resolve15([]), AMBIENT_PROBE_TIMEOUT_MS);
|
|
28882
|
+
});
|
|
28883
|
+
try {
|
|
28884
|
+
return await Promise.race([sweep, expiry]);
|
|
28885
|
+
} finally {
|
|
28886
|
+
if (timer !== undefined)
|
|
28887
|
+
clearTimeout(timer);
|
|
28888
|
+
}
|
|
28889
|
+
}
|
|
28747
28890
|
async function anyAmbientCredential() {
|
|
28748
28891
|
let timer;
|
|
28749
28892
|
const sweep = (async () => {
|
|
@@ -28764,13 +28907,13 @@ async function anyAmbientCredential() {
|
|
|
28764
28907
|
});
|
|
28765
28908
|
})();
|
|
28766
28909
|
const expiry = new Promise((resolve15) => {
|
|
28767
|
-
timer = setTimeout(() => resolve15(true), AMBIENT_PROBE_TIMEOUT_MS);
|
|
28910
|
+
timer = _authDeps.setTimeout(() => resolve15(true), AMBIENT_PROBE_TIMEOUT_MS);
|
|
28768
28911
|
});
|
|
28769
28912
|
try {
|
|
28770
28913
|
return await Promise.race([sweep, expiry]);
|
|
28771
28914
|
} finally {
|
|
28772
28915
|
if (timer !== undefined)
|
|
28773
|
-
clearTimeout(timer);
|
|
28916
|
+
_authDeps.clearTimeout(timer);
|
|
28774
28917
|
}
|
|
28775
28918
|
}
|
|
28776
28919
|
var AuthCancelledError, _authDeps, DEFAULT_PI_AUTH_PATH, AMBIENT_PROBE_TIMEOUT_MS = 2000;
|
|
@@ -28788,7 +28931,9 @@ var init_auth = __esm(() => {
|
|
|
28788
28931
|
_authDeps = {
|
|
28789
28932
|
login,
|
|
28790
28933
|
ambientAuthAvailable,
|
|
28791
|
-
providerIds: async () => (await defaultProviders2()).map((provider) => provider.id)
|
|
28934
|
+
providerIds: async () => (await defaultProviders2()).map((provider) => provider.id),
|
|
28935
|
+
setTimeout: (fn, ms) => setTimeout(fn, ms),
|
|
28936
|
+
clearTimeout: (id) => clearTimeout(id)
|
|
28792
28937
|
};
|
|
28793
28938
|
DEFAULT_PI_AUTH_PATH = join20(homedir3(), ".pi", "agent", "auth.json");
|
|
28794
28939
|
});
|
|
@@ -28874,11 +29019,12 @@ function resolveContextWindow(override, realWindow) {
|
|
|
28874
29019
|
}
|
|
28875
29020
|
return override;
|
|
28876
29021
|
}
|
|
28877
|
-
var
|
|
29022
|
+
var THINKING_LEVELS;
|
|
28878
29023
|
var init_models = __esm(() => {
|
|
28879
29024
|
init_errors();
|
|
28880
29025
|
init_logger2();
|
|
28881
29026
|
init_model_spec();
|
|
29027
|
+
init_config();
|
|
28882
29028
|
THINKING_LEVELS = {
|
|
28883
29029
|
off: true,
|
|
28884
29030
|
minimal: true,
|
|
@@ -28892,7 +29038,7 @@ var init_models = __esm(() => {
|
|
|
28892
29038
|
|
|
28893
29039
|
// src/agents/native/client.ts
|
|
28894
29040
|
import { createClient, defaultProtocols, defaultProviders as defaultProviders3 } from "@nathapp/nax-ai";
|
|
28895
|
-
async function buildNativeClient(catalogOverrides = []) {
|
|
29041
|
+
async function buildNativeClient(catalogOverrides = [], options = {}) {
|
|
28896
29042
|
return createClient({
|
|
28897
29043
|
providers: await defaultProviders3(),
|
|
28898
29044
|
protocols: ({ providerOverrides }) => _clientDeps.defaultProtocols({
|
|
@@ -28900,7 +29046,8 @@ async function buildNativeClient(catalogOverrides = []) {
|
|
|
28900
29046
|
clientApp: NAX_CLIENT_APP,
|
|
28901
29047
|
providerOverrides
|
|
28902
29048
|
}),
|
|
28903
|
-
...catalogOverrides.length > 0 ? { providerOverrides: toProviderOverrides(catalogOverrides) } : {}
|
|
29049
|
+
...catalogOverrides.length > 0 ? { providerOverrides: toProviderOverrides(catalogOverrides) } : {},
|
|
29050
|
+
...options.transportRetries !== undefined ? { transportRetries: options.transportRetries } : {}
|
|
28904
29051
|
});
|
|
28905
29052
|
}
|
|
28906
29053
|
function canonicalise(value) {
|
|
@@ -29358,7 +29505,7 @@ async function openNativeSession(name, opts) {
|
|
|
29358
29505
|
});
|
|
29359
29506
|
return {
|
|
29360
29507
|
id: name,
|
|
29361
|
-
agentName:
|
|
29508
|
+
agentName: NATIVE_AGENT_NAME,
|
|
29362
29509
|
protocolIds: { recordId: nativeSessionId(name), sessionId: nativeSessionId(name) },
|
|
29363
29510
|
...opts.modelDef !== undefined ? { modelDef: opts.modelDef } : {},
|
|
29364
29511
|
...opts.modelTier !== undefined ? { modelTier: opts.modelTier } : {}
|
|
@@ -31030,7 +31177,7 @@ ${previousSummary}`;
|
|
|
31030
31177
|
|
|
31031
31178
|
class NativeAgentAdapter {
|
|
31032
31179
|
catalogOverrides;
|
|
31033
|
-
name =
|
|
31180
|
+
name = NATIVE_AGENT_NAME;
|
|
31034
31181
|
displayName = "Native (nax-ai)";
|
|
31035
31182
|
binary = "";
|
|
31036
31183
|
capabilities;
|
|
@@ -31064,7 +31211,7 @@ class NativeAgentAdapter {
|
|
|
31064
31211
|
const client = await getNativeClient(this.catalogOverrides);
|
|
31065
31212
|
const resolved = await client.model(provider, model);
|
|
31066
31213
|
const controller = new AbortController;
|
|
31067
|
-
const timer = options.timeoutMs !== undefined ? setTimeout(() => controller.abort(), options.timeoutMs) : undefined;
|
|
31214
|
+
const timer = options.timeoutMs !== undefined ? _adapterDeps.setTimeout(() => controller.abort(), options.timeoutMs) : undefined;
|
|
31068
31215
|
try {
|
|
31069
31216
|
const sessionId = nativeSessionId(this.oneShotKey);
|
|
31070
31217
|
const result = await client.complete(resolved, {
|
|
@@ -31098,7 +31245,7 @@ class NativeAgentAdapter {
|
|
|
31098
31245
|
throw err;
|
|
31099
31246
|
} finally {
|
|
31100
31247
|
if (timer !== undefined)
|
|
31101
|
-
clearTimeout(timer);
|
|
31248
|
+
_adapterDeps.clearTimeout(timer);
|
|
31102
31249
|
}
|
|
31103
31250
|
}
|
|
31104
31251
|
openSession(name, opts) {
|
|
@@ -31142,7 +31289,7 @@ class NativeAgentAdapter {
|
|
|
31142
31289
|
});
|
|
31143
31290
|
const deadlineController = new AbortController;
|
|
31144
31291
|
const deadlineMs = deadline.remainingMs();
|
|
31145
|
-
const deadlineTimer = deadlineMs !== undefined ? setTimeout(() => deadlineController.abort(), deadlineMs) : undefined;
|
|
31292
|
+
const deadlineTimer = deadlineMs !== undefined ? _adapterDeps.setTimeout(() => deadlineController.abort(), deadlineMs) : undefined;
|
|
31146
31293
|
const turnSignals = [turnController.signal, deadlineController.signal];
|
|
31147
31294
|
if (opts.signal !== undefined)
|
|
31148
31295
|
turnSignals.unshift(opts.signal);
|
|
@@ -31165,7 +31312,7 @@ class NativeAgentAdapter {
|
|
|
31165
31312
|
summarize: async (span, previousSummary) => {
|
|
31166
31313
|
const remainingMs = deadline.remainingMs();
|
|
31167
31314
|
const controller = new AbortController;
|
|
31168
|
-
const timer = remainingMs !== undefined ? setTimeout(() => controller.abort(), remainingMs) : undefined;
|
|
31315
|
+
const timer = remainingMs !== undefined ? _adapterDeps.setTimeout(() => controller.abort(), remainingMs) : undefined;
|
|
31169
31316
|
const signal = AbortSignal.any(opts.signal !== undefined ? [opts.signal, controller.signal, turnController.signal, deadlineController.signal] : [controller.signal, turnController.signal, deadlineController.signal]);
|
|
31170
31317
|
try {
|
|
31171
31318
|
const res = await client.complete(resolved, {
|
|
@@ -31178,13 +31325,13 @@ class NativeAgentAdapter {
|
|
|
31178
31325
|
return { text: res.text, usage: summaryUsage, costUsd, rates: resolvedRates };
|
|
31179
31326
|
} finally {
|
|
31180
31327
|
if (timer !== undefined)
|
|
31181
|
-
clearTimeout(timer);
|
|
31328
|
+
_adapterDeps.clearTimeout(timer);
|
|
31182
31329
|
}
|
|
31183
31330
|
},
|
|
31184
31331
|
complete: async (messages, tools, requestOptions) => {
|
|
31185
31332
|
const remainingMs = deadline.remainingMs();
|
|
31186
31333
|
const controller = new AbortController;
|
|
31187
|
-
const timer = remainingMs !== undefined ? setTimeout(() => controller.abort(), remainingMs) : undefined;
|
|
31334
|
+
const timer = remainingMs !== undefined ? _adapterDeps.setTimeout(() => controller.abort(), remainingMs) : undefined;
|
|
31188
31335
|
const signal = AbortSignal.any(opts.signal !== undefined ? [opts.signal, controller.signal, turnController.signal, deadlineController.signal] : [controller.signal, turnController.signal, deadlineController.signal]);
|
|
31189
31336
|
const requestThinking = requestOptions?.thinking === false ? undefined : thinking;
|
|
31190
31337
|
try {
|
|
@@ -31209,7 +31356,7 @@ class NativeAgentAdapter {
|
|
|
31209
31356
|
};
|
|
31210
31357
|
} finally {
|
|
31211
31358
|
if (timer !== undefined)
|
|
31212
|
-
clearTimeout(timer);
|
|
31359
|
+
_adapterDeps.clearTimeout(timer);
|
|
31213
31360
|
}
|
|
31214
31361
|
}
|
|
31215
31362
|
});
|
|
@@ -31229,7 +31376,7 @@ class NativeAgentAdapter {
|
|
|
31229
31376
|
throw err;
|
|
31230
31377
|
} finally {
|
|
31231
31378
|
if (deadlineTimer !== undefined)
|
|
31232
|
-
clearTimeout(deadlineTimer);
|
|
31379
|
+
_adapterDeps.clearTimeout(deadlineTimer);
|
|
31233
31380
|
}
|
|
31234
31381
|
hooks?.onStreamActivity?.({
|
|
31235
31382
|
...eventBase,
|
|
@@ -31244,7 +31391,7 @@ class NativeAgentAdapter {
|
|
|
31244
31391
|
return closeNativeSession(handle);
|
|
31245
31392
|
}
|
|
31246
31393
|
async closePhysicalSession(handle, _workdir, _options) {
|
|
31247
|
-
return closeNativeSession({ id: handle, agentName:
|
|
31394
|
+
return closeNativeSession({ id: handle, agentName: NATIVE_AGENT_NAME });
|
|
31248
31395
|
}
|
|
31249
31396
|
}
|
|
31250
31397
|
var CONSERVATIVE_CONTEXT_TOKENS = 128000, FALLBACK_TURN_TIMEOUT_SECONDS = 3600, DEFAULT_TIERS, _adapterDeps;
|
|
@@ -31262,7 +31409,12 @@ var init_adapter = __esm(() => {
|
|
|
31262
31409
|
init_turn_types();
|
|
31263
31410
|
init_session_affinity();
|
|
31264
31411
|
DEFAULT_TIERS = ["fast", "balanced", "powerful"];
|
|
31265
|
-
_adapterDeps = {
|
|
31412
|
+
_adapterDeps = {
|
|
31413
|
+
listStoredProviders,
|
|
31414
|
+
anyAmbientCredential,
|
|
31415
|
+
setTimeout: (fn, ms) => setTimeout(fn, ms),
|
|
31416
|
+
clearTimeout: (id) => clearTimeout(id)
|
|
31417
|
+
};
|
|
31266
31418
|
});
|
|
31267
31419
|
|
|
31268
31420
|
// src/agents/native/model-resolver.ts
|
|
@@ -31807,7 +31959,7 @@ async function assertPrdCommitted(prdPath, projectRoot) {
|
|
|
31807
31959
|
});
|
|
31808
31960
|
}
|
|
31809
31961
|
}
|
|
31810
|
-
var
|
|
31962
|
+
var init_validate2 = __esm(() => {
|
|
31811
31963
|
init_errors();
|
|
31812
31964
|
init_git();
|
|
31813
31965
|
});
|
|
@@ -31906,7 +32058,7 @@ function validateInjectedStory(raw, existingIds) {
|
|
|
31906
32058
|
var STORY_ID_PREFIX = "US";
|
|
31907
32059
|
var init_inject = __esm(() => {
|
|
31908
32060
|
init_errors();
|
|
31909
|
-
|
|
32061
|
+
init_validate2();
|
|
31910
32062
|
});
|
|
31911
32063
|
|
|
31912
32064
|
// src/prd/modifies-extract.ts
|
|
@@ -33002,7 +33154,7 @@ var init_schema_story = __esm(() => {
|
|
|
33002
33154
|
init_test_strategy();
|
|
33003
33155
|
init_errors();
|
|
33004
33156
|
init_out_of_scope();
|
|
33005
|
-
|
|
33157
|
+
init_validate2();
|
|
33006
33158
|
VALID_COMPLEXITY = ["simple", "medium", "complex", "expert"];
|
|
33007
33159
|
WORKDIR_SOURCES = ["stated", "derived", "defaulted"];
|
|
33008
33160
|
STORY_ID_NO_SEPARATOR = /^([A-Za-z]+)(\d+)$/;
|
|
@@ -33357,7 +33509,7 @@ var init_prd = __esm(() => {
|
|
|
33357
33509
|
init_out_of_scope_extract();
|
|
33358
33510
|
init_spec_drift();
|
|
33359
33511
|
init_spec_lint();
|
|
33360
|
-
|
|
33512
|
+
init_validate2();
|
|
33361
33513
|
init_workdir_canonical();
|
|
33362
33514
|
init_schema2();
|
|
33363
33515
|
PRD_MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
@@ -53052,8 +53204,8 @@ var init_version = __esm(() => {
|
|
|
53052
53204
|
NAX_AI_VERSION = CATALOG_VERSION;
|
|
53053
53205
|
NAX_COMMIT = (() => {
|
|
53054
53206
|
try {
|
|
53055
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
53056
|
-
return "
|
|
53207
|
+
if (/^[0-9a-f]{6,10}$/.test("3e4ec026"))
|
|
53208
|
+
return "3e4ec026";
|
|
53057
53209
|
} catch {}
|
|
53058
53210
|
try {
|
|
53059
53211
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -65849,7 +66001,7 @@ var init_coding_tool_support = __esm(() => {
|
|
|
65849
66001
|
|
|
65850
66002
|
// src/agents/tool-preamble.ts
|
|
65851
66003
|
function promptWithToolPreamble(agentName, options) {
|
|
65852
|
-
const base = agentName ===
|
|
66004
|
+
const base = agentName === NATIVE_AGENT_NAME ? options.prompt : buildContextToolPreamble(options);
|
|
65853
66005
|
const scope = buildAgentScopeSection(options.codingToolRoot, options.codingToolWorkdirLabel);
|
|
65854
66006
|
return scope === undefined ? base : `${scope}
|
|
65855
66007
|
|
|
@@ -65857,7 +66009,7 @@ ${base}`;
|
|
|
65857
66009
|
}
|
|
65858
66010
|
function applyDiffAccessForAgentProtocol(agentName, prompt, advertisedTools) {
|
|
65859
66011
|
return applyProtocolRegions(prompt, {
|
|
65860
|
-
protocol: agentName ===
|
|
66012
|
+
protocol: agentName === NATIVE_AGENT_NAME ? "native" : "acp",
|
|
65861
66013
|
advertisedTools: new Set(advertisedTools)
|
|
65862
66014
|
});
|
|
65863
66015
|
}
|
|
@@ -76918,7 +77070,7 @@ function buildSessionTurnEvent(input) {
|
|
|
76918
77070
|
...result.pricingSource !== undefined ? { pricingSource: result.pricingSource } : {},
|
|
76919
77071
|
...result.rates !== undefined ? { rates: result.rates } : {},
|
|
76920
77072
|
roundTrips: result.internalRoundTrips ?? 1,
|
|
76921
|
-
roundTripUnit: input.agentName ===
|
|
77073
|
+
roundTripUnit: input.agentName === NATIVE_AGENT_NAME ? "model-call" : "agent-run",
|
|
76922
77074
|
protocolIds: {
|
|
76923
77075
|
sessionId: handle.protocolIds?.sessionId ?? null,
|
|
76924
77076
|
recordId: handle.protocolIds?.recordId ?? null,
|
|
@@ -77475,7 +77627,7 @@ var init_manager_run_fallback = __esm(() => {
|
|
|
77475
77627
|
|
|
77476
77628
|
// src/agents/registry.ts
|
|
77477
77629
|
function adapterFor(name) {
|
|
77478
|
-
return name ===
|
|
77630
|
+
return name === NATIVE_AGENT_NAME ? new NativeAgentAdapter : new AcpAgentAdapter(name);
|
|
77479
77631
|
}
|
|
77480
77632
|
function buildAdapterList() {
|
|
77481
77633
|
return [...Array.from(_registryTestAdapters.values()), ...KNOWN_AGENT_NAMES.map(adapterFor)];
|
|
@@ -77491,12 +77643,12 @@ async function getInstalledAgents() {
|
|
|
77491
77643
|
function createAgentRegistry(config2) {
|
|
77492
77644
|
const logger = getLogger();
|
|
77493
77645
|
const adapterCache = new Map;
|
|
77494
|
-
const protocol = config2.agent?.protocol ??
|
|
77646
|
+
const protocol = config2.agent?.protocol ?? DEFAULT_AGENT_PROTOCOL;
|
|
77495
77647
|
logger?.info("agents", `Agent protocol: ${protocol}`, { protocol, hasConfig: !!config2.agent });
|
|
77496
77648
|
function cachedAdapter(name) {
|
|
77497
77649
|
let adapter = adapterCache.get(name);
|
|
77498
77650
|
if (adapter === undefined) {
|
|
77499
|
-
adapter = name ===
|
|
77651
|
+
adapter = name === NATIVE_AGENT_NAME ? new NativeAgentAdapter(undefined, config2.agent?.native?.catalogOverrides ?? []) : new AcpAgentAdapter(name);
|
|
77500
77652
|
adapterCache.set(name, adapter);
|
|
77501
77653
|
logger?.debug("agents", `Created ${adapter.constructor.name} for ${name}`, { name });
|
|
77502
77654
|
}
|
|
@@ -77530,10 +77682,11 @@ function createAgentRegistry(config2) {
|
|
|
77530
77682
|
}
|
|
77531
77683
|
var KNOWN_AGENT_NAMES, _registryTestAdapters;
|
|
77532
77684
|
var init_registry4 = __esm(() => {
|
|
77685
|
+
init_config();
|
|
77533
77686
|
init_logger2();
|
|
77534
77687
|
init_adapter2();
|
|
77535
77688
|
init_native();
|
|
77536
|
-
KNOWN_AGENT_NAMES = ["claude", "codex", "opencode", "gemini", "aider", "pi",
|
|
77689
|
+
KNOWN_AGENT_NAMES = ["claude", "codex", "opencode", "gemini", "aider", "pi", NATIVE_AGENT_NAME];
|
|
77537
77690
|
_registryTestAdapters = new Map;
|
|
77538
77691
|
});
|
|
77539
77692
|
|
|
@@ -77602,7 +77755,7 @@ class AgentManager {
|
|
|
77602
77755
|
const fromAgent = this._config.agent?.default;
|
|
77603
77756
|
if (typeof fromAgent === "string" && fromAgent.length > 0)
|
|
77604
77757
|
return fromAgent;
|
|
77605
|
-
return
|
|
77758
|
+
return DEFAULT_AGENT_NAME;
|
|
77606
77759
|
}
|
|
77607
77760
|
isUnavailable(agent, tier, model) {
|
|
77608
77761
|
return this._cooldowns.isCooling(agent, tier, this._fallbackIdentity.modelId(agent, tier, model));
|
|
@@ -77992,6 +78145,7 @@ class AgentManager {
|
|
|
77992
78145
|
}
|
|
77993
78146
|
var MAX_EMITTER_LISTENERS = 100, _agentManagerDeps;
|
|
77994
78147
|
var init_manager2 = __esm(() => {
|
|
78148
|
+
init_config();
|
|
77995
78149
|
init_permissions2();
|
|
77996
78150
|
init_errors();
|
|
77997
78151
|
init_logger2();
|
|
@@ -78036,7 +78190,7 @@ function toAssignment(p, models, defaultAgent) {
|
|
|
78036
78190
|
if (!membership.isTier) {
|
|
78037
78191
|
return { agent: p.target.agent, agentProfileId: p.id, profileModelPin: p.target.model };
|
|
78038
78192
|
}
|
|
78039
|
-
if (membership.viaDefaultAgentFallback && p.target.agent ===
|
|
78193
|
+
if (membership.viaDefaultAgentFallback && p.target.agent === NATIVE_AGENT !== (defaultAgent === NATIVE_AGENT)) {
|
|
78040
78194
|
getSafeLogger()?.warn("routing", "Profile tier resolves only via the default agent across a protocol boundary", {
|
|
78041
78195
|
profileId: p.id,
|
|
78042
78196
|
agent: p.target.agent,
|
|
@@ -78046,7 +78200,7 @@ function toAssignment(p, models, defaultAgent) {
|
|
|
78046
78200
|
}
|
|
78047
78201
|
return { agent: p.target.agent, agentProfileId: p.id, profileModelTier: targetModel };
|
|
78048
78202
|
}
|
|
78049
|
-
var
|
|
78203
|
+
var NATIVE_AGENT = "native";
|
|
78050
78204
|
var init_agent_profile_resolver = __esm(() => {
|
|
78051
78205
|
init_config();
|
|
78052
78206
|
init_logger2();
|
|
@@ -78146,7 +78300,11 @@ function resolveDefaultAgent(config2) {
|
|
|
78146
78300
|
return fromAgent;
|
|
78147
78301
|
return FALLBACK_DEFAULT_AGENT;
|
|
78148
78302
|
}
|
|
78149
|
-
var FALLBACK_DEFAULT_AGENT
|
|
78303
|
+
var FALLBACK_DEFAULT_AGENT;
|
|
78304
|
+
var init_utils = __esm(() => {
|
|
78305
|
+
init_config();
|
|
78306
|
+
FALLBACK_DEFAULT_AGENT = DEFAULT_AGENT_NAME;
|
|
78307
|
+
});
|
|
78150
78308
|
|
|
78151
78309
|
// src/agents/index.ts
|
|
78152
78310
|
var init_agents = __esm(() => {
|
|
@@ -78161,20 +78319,24 @@ var init_agents = __esm(() => {
|
|
|
78161
78319
|
init_shared();
|
|
78162
78320
|
init_version_detection();
|
|
78163
78321
|
init_types2();
|
|
78322
|
+
init_utils();
|
|
78164
78323
|
});
|
|
78165
78324
|
|
|
78166
78325
|
// src/cli/agents.ts
|
|
78167
78326
|
async function agentsListCommand(config2, _workdir) {
|
|
78168
|
-
const
|
|
78169
|
-
const
|
|
78327
|
+
const acpReachable = (config2.agent?.protocol ?? DEFAULT_AGENT_PROTOCOL) !== "native";
|
|
78328
|
+
const adapters = acpReachable ? Array.from(ACP_ADAPTER_NAMES).map((name) => new AcpAgentAdapter(name)) : [];
|
|
78329
|
+
const defaultAgent = resolveDefaultAgent(config2);
|
|
78330
|
+
const acpVersions = await Promise.all(adapters.map(async (agent) => ({
|
|
78170
78331
|
name: agent.name,
|
|
78171
78332
|
displayName: agent.displayName,
|
|
78172
78333
|
binary: agent.binary,
|
|
78173
78334
|
version: await _cliAgentsDeps.getAgentVersion(agent.binary),
|
|
78174
78335
|
installed: await agent.isInstalled(),
|
|
78175
78336
|
capabilities: agent.capabilities,
|
|
78176
|
-
isDefault:
|
|
78337
|
+
isDefault: defaultAgent === agent.name
|
|
78177
78338
|
})));
|
|
78339
|
+
const agentVersions = [...nativeListing(config2, defaultAgent), ...acpVersions];
|
|
78178
78340
|
const rows = agentVersions.map((info) => {
|
|
78179
78341
|
const status = info.installed ? "installed" : "unavailable";
|
|
78180
78342
|
const versionStr = info.version || "-";
|
|
@@ -78208,6 +78370,22 @@ Available Agents:
|
|
|
78208
78370
|
}
|
|
78209
78371
|
console.log();
|
|
78210
78372
|
}
|
|
78373
|
+
function nativeListing(config2, defaultAgent) {
|
|
78374
|
+
if ((config2.agent?.protocol ?? DEFAULT_AGENT_PROTOCOL) === "acp")
|
|
78375
|
+
return [];
|
|
78376
|
+
const adapter = new NativeAgentAdapter(Object.keys(config2.models[NATIVE_AGENT_NAME] ?? {}));
|
|
78377
|
+
return [
|
|
78378
|
+
{
|
|
78379
|
+
name: adapter.name,
|
|
78380
|
+
displayName: adapter.displayName,
|
|
78381
|
+
binary: "in-process",
|
|
78382
|
+
version: "",
|
|
78383
|
+
installed: true,
|
|
78384
|
+
capabilities: adapter.capabilities,
|
|
78385
|
+
isDefault: defaultAgent === adapter.name
|
|
78386
|
+
}
|
|
78387
|
+
];
|
|
78388
|
+
}
|
|
78211
78389
|
function pad(str, width) {
|
|
78212
78390
|
return str.padEnd(width);
|
|
78213
78391
|
}
|
|
@@ -78215,7 +78393,9 @@ var _cliAgentsDeps;
|
|
|
78215
78393
|
var init_agents2 = __esm(() => {
|
|
78216
78394
|
init_agents();
|
|
78217
78395
|
init_acp();
|
|
78396
|
+
init_native();
|
|
78218
78397
|
init_version_detection();
|
|
78398
|
+
init_config();
|
|
78219
78399
|
_cliAgentsDeps = { getAgentVersion };
|
|
78220
78400
|
});
|
|
78221
78401
|
|
|
@@ -84723,6 +84903,14 @@ async function checkClaudeCLI() {
|
|
|
84723
84903
|
}
|
|
84724
84904
|
async function checkAgentCLI(config2) {
|
|
84725
84905
|
const agent = resolveDefaultAgent(config2);
|
|
84906
|
+
if (agent === NATIVE_AGENT_NAME) {
|
|
84907
|
+
return {
|
|
84908
|
+
name: "agent-cli-available",
|
|
84909
|
+
tier: "blocker",
|
|
84910
|
+
passed: true,
|
|
84911
|
+
message: "native agent runs in-process; no CLI binary required"
|
|
84912
|
+
};
|
|
84913
|
+
}
|
|
84726
84914
|
try {
|
|
84727
84915
|
const proc = _checkCliDeps.spawn([agent, "--version"], {
|
|
84728
84916
|
stdout: "pipe",
|
|
@@ -84748,6 +84936,7 @@ async function checkAgentCLI(config2) {
|
|
|
84748
84936
|
var _checkCliDeps;
|
|
84749
84937
|
var init_checks_cli = __esm(() => {
|
|
84750
84938
|
init_agents();
|
|
84939
|
+
init_native();
|
|
84751
84940
|
init_bun_deps();
|
|
84752
84941
|
_checkCliDeps = {
|
|
84753
84942
|
spawn
|
|
@@ -99298,8 +99487,26 @@ function warnInertBashStages(config2, logger) {
|
|
|
99298
99487
|
logger?.warn("permissions", `bashApproval "${resolved}" on stage "${stage}" grants no Bash (no Bash(...) allow rule) -- the agent is not offered Bash, so nothing can escalate. Add one rule: "allow": ["Bash(ls *, cat *, git status*)"]`, { storyId: "_setup", stage, bashApproval: resolved });
|
|
99299
99488
|
}
|
|
99300
99489
|
}
|
|
99490
|
+
function warnUnreferencedAgentModels(prd, config2, logger) {
|
|
99491
|
+
const storyAgents = prd.userStories.flatMap((story) => story.routing?.agent ? [story.routing.agent] : []);
|
|
99492
|
+
const agents = findUnreferencedAgentModels(config2, storyAgents);
|
|
99493
|
+
if (agents.length === 0)
|
|
99494
|
+
return;
|
|
99495
|
+
logger?.warn("config", describeUnreferencedAgentModels(agents, config2), { storyId: "_setup", agents });
|
|
99496
|
+
}
|
|
99497
|
+
async function assertDefaultNativeCredentials(config2) {
|
|
99498
|
+
const { describeMissingNativeCredentials, findMissingNativeCredentials } = await Promise.resolve().then(() => (init_precheck2(), exports_precheck));
|
|
99499
|
+
const missing = await findMissingNativeCredentials(config2);
|
|
99500
|
+
if (missing.length === 0)
|
|
99501
|
+
return;
|
|
99502
|
+
throw new NaxError(describeMissingNativeCredentials(missing), "NATIVE_CREDENTIALS_MISSING", {
|
|
99503
|
+
stage: "setup",
|
|
99504
|
+
providers: missing.map(({ provider: provider2 }) => provider2)
|
|
99505
|
+
});
|
|
99506
|
+
}
|
|
99301
99507
|
var init_run_setup_warnings = __esm(() => {
|
|
99302
99508
|
init_config();
|
|
99509
|
+
init_errors();
|
|
99303
99510
|
});
|
|
99304
99511
|
|
|
99305
99512
|
// src/execution/lifecycle/gitignore-reconcile.ts
|
|
@@ -100116,6 +100323,7 @@ async function initializeAfterLock(options) {
|
|
|
100116
100323
|
const prd = initResult.prd;
|
|
100117
100324
|
statusWriter.setPrd(prd);
|
|
100118
100325
|
warnProfileMismatch(prd, config2, logger);
|
|
100326
|
+
warnUnreferencedAgentModels(prd, config2, logger);
|
|
100119
100327
|
let counts = initResult.storyCounts;
|
|
100120
100328
|
if (counts.paused > 0 && interactionChain !== null) {
|
|
100121
100329
|
const { promptForPausedStories: promptForPausedStories2 } = await Promise.resolve().then(() => (init_paused_story_prompts(), exports_paused_story_prompts));
|
|
@@ -102466,6 +102674,9 @@ async function setupRun(options) {
|
|
|
102466
102674
|
if (options.agentManager) {
|
|
102467
102675
|
await options.agentManager.validateCredentials();
|
|
102468
102676
|
}
|
|
102677
|
+
if (!options.dryRun) {
|
|
102678
|
+
await assertDefaultNativeCredentials(options.config);
|
|
102679
|
+
}
|
|
102469
102680
|
const {
|
|
102470
102681
|
prdPath,
|
|
102471
102682
|
workdir,
|
|
@@ -109108,7 +109319,7 @@ function collectConfiguredModelPins(config2) {
|
|
|
109108
109319
|
}
|
|
109109
109320
|
}
|
|
109110
109321
|
const pins = [];
|
|
109111
|
-
const defaultAgent = cfg.agent?.default ??
|
|
109322
|
+
const defaultAgent = cfg.agent?.default ?? DEFAULT_AGENT_NAME;
|
|
109112
109323
|
if (cfg.review?.semantic !== undefined) {
|
|
109113
109324
|
const pin = pinFromConfiguredModel("review.semantic.model", cfg.review.semantic.model, defaultAgent, tierEntries);
|
|
109114
109325
|
if (pin !== undefined)
|
|
@@ -109197,7 +109408,7 @@ var init_checks_model_resolution_walk = __esm(() => {
|
|
|
109197
109408
|
|
|
109198
109409
|
// src/precheck/checks-model-resolution.ts
|
|
109199
109410
|
function isNativeAgent(agent) {
|
|
109200
|
-
return agent ===
|
|
109411
|
+
return agent === NATIVE_AGENT_NAME;
|
|
109201
109412
|
}
|
|
109202
109413
|
async function checkModelResolution(config2) {
|
|
109203
109414
|
const { pins, tierEntries, catalogOverrides } = collectConfiguredModelPins(config2);
|
|
@@ -109306,6 +109517,52 @@ var init_checks_model_resolution = __esm(() => {
|
|
|
109306
109517
|
};
|
|
109307
109518
|
});
|
|
109308
109519
|
|
|
109520
|
+
// src/precheck/checks-native-credentials.ts
|
|
109521
|
+
function providerOf(id) {
|
|
109522
|
+
const slash = id.indexOf("/");
|
|
109523
|
+
return slash > 0 ? id.slice(0, slash) : undefined;
|
|
109524
|
+
}
|
|
109525
|
+
function providerTiers(config2) {
|
|
109526
|
+
const overridden = new Set((config2.agent?.native?.catalogOverrides ?? []).map((override) => override.provider));
|
|
109527
|
+
const byProvider = new Map;
|
|
109528
|
+
for (const [tier, entry] of Object.entries(config2.models?.[NATIVE_AGENT_NAME] ?? {})) {
|
|
109529
|
+
if (entry === undefined)
|
|
109530
|
+
continue;
|
|
109531
|
+
const provider2 = providerOf(typeof entry === "string" ? entry : entry.model);
|
|
109532
|
+
if (provider2 === undefined || overridden.has(provider2))
|
|
109533
|
+
continue;
|
|
109534
|
+
byProvider.set(provider2, [...byProvider.get(provider2) ?? [], tier]);
|
|
109535
|
+
}
|
|
109536
|
+
return byProvider;
|
|
109537
|
+
}
|
|
109538
|
+
async function findMissingNativeCredentials(config2) {
|
|
109539
|
+
if (resolveDefaultAgent(config2) !== NATIVE_AGENT_NAME)
|
|
109540
|
+
return [];
|
|
109541
|
+
const byProvider = providerTiers(config2);
|
|
109542
|
+
if (byProvider.size === 0)
|
|
109543
|
+
return [];
|
|
109544
|
+
const missing = await _nativeCredentialDeps.providersWithoutCredentials([...byProvider.keys()]);
|
|
109545
|
+
return missing.map((provider2) => ({ provider: provider2, tiers: byProvider.get(provider2) ?? [] }));
|
|
109546
|
+
}
|
|
109547
|
+
function describeMissingNativeCredentials(missing) {
|
|
109548
|
+
const uses = missing.map(({ provider: provider2, tiers }) => `${provider2} (${tiers.map((tier) => `models.native.${tier}`).join(", ")})`).join("; ");
|
|
109549
|
+
const logins = missing.map(({ provider: provider2 }) => `nax auth login ${provider2}`).join(" / ");
|
|
109550
|
+
return `The default native agent needs a credential for ${uses}, but none is stored or in the environment. ` + `Run ${logins}, set the provider's API key environment variable, point models.native at a provider you have ` + `credentials for, or set agent.default "claude" to use an acpx agent.`;
|
|
109551
|
+
}
|
|
109552
|
+
async function checkNativeCredentials(config2) {
|
|
109553
|
+
const missing = await findMissingNativeCredentials(config2);
|
|
109554
|
+
if (missing.length === 0) {
|
|
109555
|
+
return { name: CHECK_NAME, tier: "blocker", passed: true, message: "native default agent credentials found" };
|
|
109556
|
+
}
|
|
109557
|
+
return { name: CHECK_NAME, tier: "blocker", passed: false, message: describeMissingNativeCredentials(missing) };
|
|
109558
|
+
}
|
|
109559
|
+
var CHECK_NAME = "native-credentials", _nativeCredentialDeps;
|
|
109560
|
+
var init_checks_native_credentials = __esm(() => {
|
|
109561
|
+
init_agents();
|
|
109562
|
+
init_native();
|
|
109563
|
+
_nativeCredentialDeps = { providersWithoutCredentials };
|
|
109564
|
+
});
|
|
109565
|
+
|
|
109309
109566
|
// src/precheck/checks-warnings.ts
|
|
109310
109567
|
import { existsSync as existsSync37 } from "fs";
|
|
109311
109568
|
import { isAbsolute as isAbsolute22 } from "path";
|
|
@@ -109614,6 +109871,7 @@ var init_checks4 = __esm(() => {
|
|
|
109614
109871
|
init_checks_agents();
|
|
109615
109872
|
init_checks_blockers();
|
|
109616
109873
|
init_checks_model_resolution();
|
|
109874
|
+
init_checks_native_credentials();
|
|
109617
109875
|
init_checks_warnings();
|
|
109618
109876
|
});
|
|
109619
109877
|
|
|
@@ -109742,6 +110000,7 @@ __export(exports_precheck, {
|
|
|
109742
110000
|
EXIT_CODES: () => EXIT_CODES,
|
|
109743
110001
|
_checkDiskSpaceDeps: () => _checkDiskSpaceDeps,
|
|
109744
110002
|
_modelResolutionDeps: () => _modelResolutionDeps,
|
|
110003
|
+
_nativeCredentialDeps: () => _nativeCredentialDeps,
|
|
109745
110004
|
_precheckDeps: () => _precheckDeps,
|
|
109746
110005
|
checkAgentCLI: () => checkAgentCLI,
|
|
109747
110006
|
checkBuildCommandInReviewChecks: () => checkBuildCommandInReviewChecks,
|
|
@@ -109758,6 +110017,7 @@ __export(exports_precheck, {
|
|
|
109758
110017
|
checkLintCommand: () => checkLintCommand,
|
|
109759
110018
|
checkModelResolution: () => checkModelResolution,
|
|
109760
110019
|
checkMultiAgentHealth: () => checkMultiAgentHealth,
|
|
110020
|
+
checkNativeCredentials: () => checkNativeCredentials,
|
|
109761
110021
|
checkOptionalCommands: () => checkOptionalCommands,
|
|
109762
110022
|
checkPRDValid: () => checkPRDValid,
|
|
109763
110023
|
checkPendingStories: () => checkPendingStories,
|
|
@@ -109766,6 +110026,8 @@ __export(exports_precheck, {
|
|
|
109766
110026
|
checkTestCommand: () => checkTestCommand,
|
|
109767
110027
|
checkTypecheckCommand: () => checkTypecheckCommand,
|
|
109768
110028
|
checkWorkingTreeClean: () => checkWorkingTreeClean,
|
|
110029
|
+
describeMissingNativeCredentials: () => describeMissingNativeCredentials,
|
|
110030
|
+
findMissingNativeCredentials: () => findMissingNativeCredentials,
|
|
109769
110031
|
parseDiskSpaceOutput: () => parseDiskSpaceOutput,
|
|
109770
110032
|
runEnvironmentPrecheck: () => runEnvironmentPrecheck,
|
|
109771
110033
|
runPrecheck: () => runPrecheck2
|
|
@@ -109781,6 +110043,7 @@ function getLateEnvironmentBlockers(config2, workdir) {
|
|
|
109781
110043
|
return [
|
|
109782
110044
|
() => checkAgentCLI(config2),
|
|
109783
110045
|
() => checkModelResolution(config2),
|
|
110046
|
+
() => checkNativeCredentials(config2),
|
|
109784
110047
|
() => checkDependenciesInstalled(workdir),
|
|
109785
110048
|
() => checkTestCommand(config2),
|
|
109786
110049
|
() => checkLintCommand(config2),
|
|
@@ -110170,7 +110433,7 @@ ${repairHint}` : codebaseContext;
|
|
|
110170
110433
|
agentRouting: config2.routing?.agents,
|
|
110171
110434
|
profileName: config2.profile,
|
|
110172
110435
|
models: config2.models,
|
|
110173
|
-
defaultAgent: config2.agent?.default ??
|
|
110436
|
+
defaultAgent: config2.agent?.default ?? DEFAULT_AGENT_NAME,
|
|
110174
110437
|
outputPath: prdPath,
|
|
110175
110438
|
repoRoot: workdir,
|
|
110176
110439
|
scope: new Set(subStoriesWithParent.map((s) => s.id)),
|
|
@@ -110494,7 +110757,7 @@ async function persistPrd(ctx, prd) {
|
|
|
110494
110757
|
agentRouting: ctx.config.routing?.agents,
|
|
110495
110758
|
profileName: ctx.profileName,
|
|
110496
110759
|
models: ctx.config.models,
|
|
110497
|
-
defaultAgent: ctx.config.agent?.default ??
|
|
110760
|
+
defaultAgent: ctx.config.agent?.default ?? DEFAULT_AGENT_NAME,
|
|
110498
110761
|
outputPath: ctx.outputPath,
|
|
110499
110762
|
repoRoot: ctx.workdir,
|
|
110500
110763
|
writeFile: ctx.deps.writeFile
|
|
@@ -110502,6 +110765,7 @@ async function persistPrd(ctx, prd) {
|
|
|
110502
110765
|
}
|
|
110503
110766
|
var _persistPrdDeps;
|
|
110504
110767
|
var init_persist_prd = __esm(() => {
|
|
110768
|
+
init_config();
|
|
110505
110769
|
init_generator2();
|
|
110506
110770
|
init_logger2();
|
|
110507
110771
|
init_operations();
|