larkin 0.4.29 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +5 -9
- package/artifacts/release/THIRD_PARTY_NOTICES.txt +751 -4425
- package/dist/app/agent-cli.mjs +14 -2
- package/dist/app/agent-config.mjs +26 -86
- package/dist/app/binary-entry.mjs +0 -20
- package/dist/app/cli.mjs +6 -22
- package/dist/app/internal-command.cjs +0 -2
- package/dist/app/internal-command.mjs +0 -2
- package/dist/app/runtime-model-directory.mjs +2 -16
- package/dist/app/runtime-process.mjs +0 -1
- package/dist/app/setup.mjs +52 -57
- package/dist/dashboard/dashboard-config-controller.mjs +43 -109
- package/dist/dashboard/dashboard-view-model.mjs +4 -7
- package/dist/dashboard/web/assets/dashboard.css +1 -1
- package/dist/dashboard/web/assets/dashboard.js +15 -15
- package/dist/feishu/host-shell.cjs +1 -2
- package/dist/feishu/host-shell.mjs +1 -2
- package/dist/platform/config.cjs +168 -133
- package/dist/platform/config.mjs +168 -133
- package/dist/runtime/pi-artifact-provenance.mjs +3 -3
- package/dist/runtime/pi-bash-timeout-extension.mjs +4 -5
- package/dist/runtime/pi-compaction-recovery.cjs +9 -11
- package/dist/runtime/pi-compaction-recovery.mjs +8 -10
- package/dist/runtime/pi-extension-api.mjs +1 -0
- package/dist/runtime/pi-model-catalog.cjs +7 -8
- package/dist/runtime/pi-model-catalog.mjs +7 -8
- package/dist/runtime/pi-subagent-injection.mjs +17 -4
- package/dist/runtime/runtime-adapters.mjs +26 -43
- package/dist/runtime/runtime-host.cjs +21 -43
- package/dist/runtime/runtime-host.mjs +22 -44
- package/dist/runtime/runtime-model-catalog.cjs +1 -1
- package/dist/runtime/runtime-model-catalog.mjs +1 -1
- package/dist/runtime/runtime-readiness.cjs +42 -99
- package/dist/runtime/runtime-readiness.mjs +40 -98
- package/dist/runtime/user-runtime.cjs +7 -24
- package/dist/runtime/user-runtime.mjs +7 -23
- package/dist/setup/bot-register.mjs +15 -123
- package/dist/setup/setup-agent-choice.mjs +48 -74
- package/dist/setup/setup-bind.mjs +51 -151
- package/dist/setup/setup-binding.mjs +6 -9
- package/package.json +3 -2
- package/dist/app/pi-auth-cli.mjs +0 -277
- package/dist/platform/process-boundary-trace.cjs +0 -108
- package/dist/runtime/builtin-pi-assets.cjs +0 -117
- package/dist/runtime/builtin-pi-assets.mjs +0 -105
- package/dist/runtime/pi-artifact-provenance.cjs +0 -147
- package/dist/runtime/pi-distribution-label.cjs +0 -6
- package/dist/runtime/pi-distribution-label.mjs +0 -3
- package/dist/runtime/pi-inline-extensions.mjs +0 -78
- package/dist/runtime/pi-official-auth.cjs +0 -594
- package/dist/runtime/pi-official-auth.mjs +0 -544
- package/dist/runtime/pi-profile-migration.cjs +0 -764
- package/dist/runtime/pi-profile-migration.mjs +0 -719
- package/dist/runtime/pi-provider-config.cjs +0 -354
- package/dist/runtime/pi-provider-config.mjs +0 -334
- package/dist/runtime/pi-provider-login.mjs +0 -240
|
@@ -41,7 +41,6 @@ exports.findExactPiModel = findExactPiModel;
|
|
|
41
41
|
exports.discoverPiModelCatalog = discoverPiModelCatalog;
|
|
42
42
|
const node_child_process_1 = require("node:child_process");
|
|
43
43
|
const path = __importStar(require("node:path"));
|
|
44
|
-
const builtin_pi_assets_js_1 = require("./builtin-pi-assets.cjs");
|
|
45
44
|
const pi_rpc_client_js_1 = require("./pi-rpc-client.cjs");
|
|
46
45
|
const runtime_readiness_js_1 = require("./runtime-readiness.cjs");
|
|
47
46
|
exports.PI_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
@@ -73,16 +72,16 @@ function findExactPiModel(reference, models) {
|
|
|
73
72
|
const discoveryCache = new Map();
|
|
74
73
|
/** Discover only through Pi's structured RPC protocol; no table parsing or static fallback. */
|
|
75
74
|
function piCatalogChildEnv(options) {
|
|
76
|
-
const
|
|
75
|
+
const env = {
|
|
77
76
|
...process.env,
|
|
78
77
|
...options.env,
|
|
79
|
-
...(options.agentDir ? { PI_CODING_AGENT_DIR: path.resolve(options.agentDir) } : {}),
|
|
80
78
|
NO_COLOR: "1",
|
|
81
79
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
if (options.agentDir)
|
|
81
|
+
env.PI_CODING_AGENT_DIR = path.resolve(options.agentDir);
|
|
82
|
+
else
|
|
83
|
+
delete env.PI_CODING_AGENT_DIR;
|
|
84
|
+
return env;
|
|
86
85
|
}
|
|
87
86
|
async function discoverPiModelCatalog(options) {
|
|
88
87
|
if (!options.spawn) {
|
|
@@ -118,7 +117,7 @@ async function discoverPiModelCatalogUncached(options) {
|
|
|
118
117
|
]);
|
|
119
118
|
const available = [...(availableResponse?.models ?? [])].sort((left, right) => piModelId(left).localeCompare(piModelId(right)));
|
|
120
119
|
if (!available.length)
|
|
121
|
-
throw new Error("Pi has no authenticated available models. Run the official `pi` login flow
|
|
120
|
+
throw new Error("Pi has no authenticated available models. Run the official `pi` login flow; Larkin will not create a fallback session.");
|
|
122
121
|
const effectiveModel = state.model ? piModelId(state.model) : null;
|
|
123
122
|
if (!effectiveModel || !available.some((model) => piModelId(model) === effectiveModel)) {
|
|
124
123
|
throw new Error(`Pi official default resolution returned an unavailable model (${effectiveModel || "none"}); refusing implicit fallback`);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { spawn as nodeSpawn } from "node:child_process";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { applyPiPackageDirForChild, catalogPiChildDistribution } from "./builtin-pi-assets.mjs";
|
|
4
3
|
import { PiRpcClient } from "./pi-rpc-client.mjs";
|
|
5
4
|
import { classifyRuntimePrerequisite, RuntimePrerequisiteError } from "./runtime-readiness.mjs";
|
|
6
5
|
export const PI_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
@@ -32,16 +31,16 @@ export function findExactPiModel(reference, models) {
|
|
|
32
31
|
const discoveryCache = new Map();
|
|
33
32
|
/** Discover only through Pi's structured RPC protocol; no table parsing or static fallback. */
|
|
34
33
|
function piCatalogChildEnv(options) {
|
|
35
|
-
const
|
|
34
|
+
const env = {
|
|
36
35
|
...process.env,
|
|
37
36
|
...options.env,
|
|
38
|
-
...(options.agentDir ? { PI_CODING_AGENT_DIR: path.resolve(options.agentDir) } : {}),
|
|
39
37
|
NO_COLOR: "1",
|
|
40
38
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
if (options.agentDir)
|
|
40
|
+
env.PI_CODING_AGENT_DIR = path.resolve(options.agentDir);
|
|
41
|
+
else
|
|
42
|
+
delete env.PI_CODING_AGENT_DIR;
|
|
43
|
+
return env;
|
|
45
44
|
}
|
|
46
45
|
export async function discoverPiModelCatalog(options) {
|
|
47
46
|
if (!options.spawn) {
|
|
@@ -77,7 +76,7 @@ async function discoverPiModelCatalogUncached(options) {
|
|
|
77
76
|
]);
|
|
78
77
|
const available = [...(availableResponse?.models ?? [])].sort((left, right) => piModelId(left).localeCompare(piModelId(right)));
|
|
79
78
|
if (!available.length)
|
|
80
|
-
throw new Error("Pi has no authenticated available models. Run the official `pi` login flow
|
|
79
|
+
throw new Error("Pi has no authenticated available models. Run the official `pi` login flow; Larkin will not create a fallback session.");
|
|
81
80
|
const effectiveModel = state.model ? piModelId(state.model) : null;
|
|
82
81
|
if (!effectiveModel || !available.some((model) => piModelId(model) === effectiveModel)) {
|
|
83
82
|
throw new Error(`Pi official default resolution returned an unavailable model (${effectiveModel || "none"}); refusing implicit fallback`);
|
|
@@ -160,12 +160,25 @@ export function piVersionSupportsSubagents(version) {
|
|
|
160
160
|
return false;
|
|
161
161
|
return version.major > 0 || (version.major === 0 && version.minor >= 80);
|
|
162
162
|
}
|
|
163
|
-
|
|
163
|
+
const externalPiVersionProbeCache = new Map();
|
|
164
|
+
function externalPiVersionProbeKey(piCommand, env) {
|
|
165
|
+
return JSON.stringify([piCommand, env.PATH ?? ""]);
|
|
166
|
+
}
|
|
167
|
+
/** 测试用:清空进程内 `pi --version` 探测缓存。 */
|
|
168
|
+
export function resetExternalPiVersionProbeCache() {
|
|
169
|
+
externalPiVersionProbeCache.clear();
|
|
170
|
+
}
|
|
171
|
+
/** 解析 external `pi --version`;无法确认版本时视为不支持,不注入。按 piCommand+PATH 缓存。 */
|
|
164
172
|
export function probeExternalPiVersion(piCommand, env) {
|
|
173
|
+
const key = externalPiVersionProbeKey(piCommand, env);
|
|
174
|
+
if (externalPiVersionProbeCache.has(key))
|
|
175
|
+
return externalPiVersionProbeCache.get(key) ?? null;
|
|
165
176
|
const result = spawnSync(piCommand, ["--version"], { env, encoding: "utf8", timeout: 5_000, maxBuffer: 64 * 1024 });
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
177
|
+
const version = result.error || result.status !== 0
|
|
178
|
+
? null
|
|
179
|
+
: parsePiVersion(String(result.stdout || result.stderr || ""));
|
|
180
|
+
externalPiVersionProbeCache.set(key, version);
|
|
181
|
+
return version;
|
|
169
182
|
}
|
|
170
183
|
/**
|
|
171
184
|
* 用户 pi 是否已自行安装 pi-subagents(settings.json packages 或包目录)。
|
|
@@ -3,11 +3,8 @@ import crypto from "node:crypto";
|
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { createInterface } from "node:readline";
|
|
6
|
-
import { applyPiPackageDirForChild, piChildDistributionFromOverrides } from "./builtin-pi-assets.mjs";
|
|
7
6
|
import { isPiThinkingLevel } from "./pi-model-catalog.mjs";
|
|
8
7
|
import { PiRpcClient } from "./pi-rpc-client.mjs";
|
|
9
|
-
import { internalCommandSpec } from "../app/internal-command.mjs";
|
|
10
|
-
import { BUNDLED_PI_VERSION, piAgentDirectory } from "./pi-provider-config.mjs";
|
|
11
8
|
import { recordPiRuntimeArtifactProvenance } from "./pi-artifact-provenance.mjs";
|
|
12
9
|
import { traceProcessBoundary } from "../platform/process-boundary-trace.mjs";
|
|
13
10
|
import { resolvePiSubagentExtensionArg } from "./pi-subagent-injection.mjs";
|
|
@@ -15,9 +12,12 @@ import { extractCanonicalPiSubagentNotification, ledgerStatusFromPiNotificationS
|
|
|
15
12
|
import { resolvePiSubagentRecordWatchdogExtensionArg } from "./pi-subagent-record-watchdog-injection.mjs";
|
|
16
13
|
import { effectivePiStateDir, extractBackgroundPiSubagentDispatch } from "./pi-subagent-ledger.mjs";
|
|
17
14
|
import { resolvePiBashTimeoutExtensionArg } from "./pi-bash-timeout-injection.mjs";
|
|
18
|
-
import { classifyPiMissingCredentialRejection, classifyRuntimePrerequisite,
|
|
15
|
+
import { classifyPiMissingCredentialRejection, classifyRuntimePrerequisite, missingProviderCredentialReadiness, probeNativeRuntimeReadiness, providerAuthenticationFailureReadiness, RuntimePrerequisiteError, } from "./runtime-readiness.mjs";
|
|
19
16
|
import { buildStrictProviderErrorInput, classifyStrictProviderError, INTERNAL_CONTEXT_WINDOW_PROJECTION_REASON, } from "./provider-error-classifier.mjs";
|
|
20
|
-
import { assertEffectivePiCompactionSettings, assertNoProjectPiCompactionOverride, calculatePiCompactionSettings, parsePiExecutableVersion, prepareOwnedPiDirectory, readOwnedPiSettings, verifyPiCapabilities, writeOwnedPiSettings, } from "./pi-compaction-recovery.mjs";
|
|
17
|
+
import { assertEffectivePiCompactionSettings, assertNoProjectPiCompactionOverride, PINNED_PI_VERSION, calculatePiCompactionSettings, parsePiExecutableVersion, prepareOwnedPiDirectory, readOwnedPiSettings, verifyPiCapabilities, writeOwnedPiSettings, } from "./pi-compaction-recovery.mjs";
|
|
18
|
+
function piAgentDirectory(configDir, agentId) {
|
|
19
|
+
return path.join(path.resolve(configDir), "providers", "pi", agentId);
|
|
20
|
+
}
|
|
21
21
|
class EventSession {
|
|
22
22
|
listeners = new Set();
|
|
23
23
|
subscribe(listener) {
|
|
@@ -462,7 +462,7 @@ class PiSession extends EventSession {
|
|
|
462
462
|
firstOutputObserved = false;
|
|
463
463
|
toolCallOpen = false;
|
|
464
464
|
piPolicyManaged;
|
|
465
|
-
constructor(sdk, distribution) {
|
|
465
|
+
constructor(sdk, distribution = "external") {
|
|
466
466
|
super();
|
|
467
467
|
this.sdk = sdk;
|
|
468
468
|
this.distribution = distribution;
|
|
@@ -538,17 +538,16 @@ class PiSession extends EventSession {
|
|
|
538
538
|
this.ownedInputIds.delete(input.inputId);
|
|
539
539
|
this.inputEpochs.delete(input.inputId);
|
|
540
540
|
const rawReason = error instanceof Error ? error.message : String(error);
|
|
541
|
-
const missing =
|
|
542
|
-
? classifyPiMissingCredentialRejection(rawReason)
|
|
543
|
-
: null;
|
|
541
|
+
const missing = classifyPiMissingCredentialRejection(rawReason);
|
|
544
542
|
if (missing) {
|
|
545
|
-
const classified = classifyPiProviderError({ provider: missing.provider, message: missing.diagnostic }
|
|
543
|
+
const classified = classifyPiProviderError({ provider: missing.provider, message: missing.diagnostic });
|
|
546
544
|
this.emit({
|
|
547
545
|
type: "input-error", inputId: input.inputId, retryable: false, willRetry: false,
|
|
548
546
|
message: classified.reason, errorCategory: classified.category, nextAction: classified.nextAction,
|
|
549
547
|
upstream: { provider: missing.provider, message: missing.diagnostic },
|
|
550
548
|
});
|
|
551
|
-
|
|
549
|
+
// 拒绝原因保留 Pi 原文,方便 RuntimeHost 独立分类,不依赖 input-error 事件顺序。
|
|
550
|
+
return { status: "rejected", inputId: input.inputId, retryable: false, reason: rawReason };
|
|
552
551
|
}
|
|
553
552
|
return { status: "rejected", inputId: input.inputId, retryable: true, reason: rawReason };
|
|
554
553
|
}
|
|
@@ -831,9 +830,7 @@ export function classifyPiProviderError(error, scope) {
|
|
|
831
830
|
return {
|
|
832
831
|
category: "rate_limit", reason, nextAction: "Wait for the provider rate-limit window, then retry.",
|
|
833
832
|
};
|
|
834
|
-
const missing =
|
|
835
|
-
? classifyPiMissingCredentialRejection(reason)
|
|
836
|
-
: null;
|
|
833
|
+
const missing = classifyPiMissingCredentialRejection(reason);
|
|
837
834
|
if (missing) {
|
|
838
835
|
const readiness = missingProviderCredentialReadiness("pi", missing.provider);
|
|
839
836
|
return { category: "auth", reason: readiness.reason, nextAction: readiness.nextAction };
|
|
@@ -1003,10 +1000,6 @@ class PiRpcBackend {
|
|
|
1003
1000
|
}
|
|
1004
1001
|
}
|
|
1005
1002
|
export function resolvePiProcessExtensionArgs(input, resolvers = {}) {
|
|
1006
|
-
// Builtin factories are passed directly to Pi main on every platform. The platform
|
|
1007
|
-
// field makes that invariant explicit and testable without changing process.platform.
|
|
1008
|
-
if (input.distribution === "builtin")
|
|
1009
|
-
return [];
|
|
1010
1003
|
const resolverInput = { distribution: "external", piCommand: input.piCommand, env: input.env };
|
|
1011
1004
|
const args = [];
|
|
1012
1005
|
// Watchdog must load before the subagent extension so session_shutdown still
|
|
@@ -1044,31 +1037,23 @@ async function createPiRpcBackend(input, dependencies, spawn, productionSpawn =
|
|
|
1044
1037
|
...(session.sessionFile ? ["--session", session.sessionFile] : []),
|
|
1045
1038
|
...(requestedModel ? ["--model", requestedModel] : []),
|
|
1046
1039
|
...(requestedEffort ? ["--thinking", requestedEffort] : [])];
|
|
1047
|
-
|
|
1048
|
-
if (!builtin && mergedEnv.LARKIN_PI_DISTRIBUTION === "builtin")
|
|
1040
|
+
if (mergedEnv.LARKIN_PI_DISTRIBUTION === "builtin")
|
|
1049
1041
|
delete mergedEnv.LARKIN_PI_DISTRIBUTION;
|
|
1050
|
-
const
|
|
1051
|
-
const
|
|
1052
|
-
const commandPrefix = builtinSpec?.args ?? dependencies.piCommandArgs ?? [];
|
|
1042
|
+
const command = dependencies.piCommand ?? dependencies.env?.LARKIN_PI_COMMAND ?? process.env.LARKIN_PI_COMMAND ?? "pi";
|
|
1043
|
+
const commandPrefix = dependencies.piCommandArgs ?? [];
|
|
1053
1044
|
const commandArgs = [...commandPrefix, ...args];
|
|
1054
1045
|
mergedEnv.PI_CODING_AGENT_DIR = ownedPiDirectory;
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
const childEnv = applyPiPackageDirForChild(mergedEnv, {
|
|
1058
|
-
distribution: builtin ? "builtin" : "external",
|
|
1059
|
-
explicitPackageDir: input.env?.PI_PACKAGE_DIR ?? dependencies.env?.PI_PACKAGE_DIR,
|
|
1060
|
-
});
|
|
1061
|
-
const reportedVersion = productionSpawn && !builtin
|
|
1046
|
+
const childEnv = { ...mergedEnv };
|
|
1047
|
+
const reportedVersion = productionSpawn
|
|
1062
1048
|
? parsePiExecutableVersion(String(spawnSync(command, [...commandPrefix, "--version"], {
|
|
1063
1049
|
cwd: input.workspaceDir, env: childEnv, encoding: "utf8", timeout: 5_000,
|
|
1064
1050
|
}).stdout || ""))
|
|
1065
|
-
:
|
|
1066
|
-
const
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
});
|
|
1051
|
+
: PINNED_PI_VERSION;
|
|
1052
|
+
const extensionInput = { piCommand: command, env: childEnv, platform: process.platform };
|
|
1053
|
+
// 假 spawn 不需要真实 extension 路径;默认 resolver 会 spawnSync(`pi --version`)。
|
|
1054
|
+
const extensionArgs = dependencies.resolvePiProcessExtensionArgs
|
|
1055
|
+
? dependencies.resolvePiProcessExtensionArgs(extensionInput)
|
|
1056
|
+
: productionSpawn ? resolvePiProcessExtensionArgs(extensionInput) : [];
|
|
1072
1057
|
commandArgs.push(...extensionArgs);
|
|
1073
1058
|
let probedModel = null;
|
|
1074
1059
|
if (productionSpawn) {
|
|
@@ -1094,7 +1079,7 @@ async function createPiRpcBackend(input, dependencies, spawn, productionSpawn =
|
|
|
1094
1079
|
client.request("get_available_models"),
|
|
1095
1080
|
]);
|
|
1096
1081
|
if (!available?.models?.length)
|
|
1097
|
-
throw new Error("Pi has no authenticated available models. Run the official `pi` login flow
|
|
1082
|
+
throw new Error("Pi has no authenticated available models. Run the official `pi` login flow; Larkin will not create a fallback session.");
|
|
1098
1083
|
const effectiveModel = state.model?.provider && state.model.id ? `${state.model.provider}/${state.model.id}` : null;
|
|
1099
1084
|
if (productionSpawn) {
|
|
1100
1085
|
if (!effectiveModel || !probedModel || effectiveModel !== probedModel.model
|
|
@@ -1108,11 +1093,10 @@ async function createPiRpcBackend(input, dependencies, spawn, productionSpawn =
|
|
|
1108
1093
|
keepRecentTokens: ownedSettings.compaction?.keepRecentTokens,
|
|
1109
1094
|
} });
|
|
1110
1095
|
const handshake = state.compactionCapabilities;
|
|
1111
|
-
verifyPiCapabilities({ distribution:
|
|
1096
|
+
verifyPiCapabilities({ distribution: "external", version: reportedVersion,
|
|
1112
1097
|
contextWindow: state.model?.contextWindow, autoCompactionEnabled: state.autoCompactionEnabled,
|
|
1113
1098
|
reserveTokens: handshake?.reserveTokens, keepRecentTokens: handshake?.keepRecentTokens,
|
|
1114
|
-
compactRpc: true, events: handshake?.events
|
|
1115
|
-
trustedProtocol: builtin });
|
|
1099
|
+
compactRpc: true, events: handshake?.events });
|
|
1116
1100
|
}
|
|
1117
1101
|
// 严格对账(Owner 决策):模型必须来自 pi 的权威可用列表,不做后缀猜测——
|
|
1118
1102
|
// 配置的模型与 pi 可用列表不符即报错,并在错误里列出可用模型。
|
|
@@ -1247,10 +1231,9 @@ export function createNativeRuntimeAdapter(id, dependencies = {}) {
|
|
|
1247
1231
|
throw new RuntimePrerequisiteError(readiness);
|
|
1248
1232
|
}
|
|
1249
1233
|
if (id === "pi") {
|
|
1250
|
-
const distribution = piChildDistributionFromOverrides(dependencies.env, input.env);
|
|
1251
1234
|
return new PiSession(await (dependencies.createPiSession
|
|
1252
1235
|
? dependencies.createPiSession(input)
|
|
1253
|
-
: createPiRpcBackend(input, { ...dependencies, piCommand: resolvedExecutable }, spawn, productionSpawn))
|
|
1236
|
+
: createPiRpcBackend(input, { ...dependencies, piCommand: resolvedExecutable }, spawn, productionSpawn)));
|
|
1254
1237
|
}
|
|
1255
1238
|
if (id === "codex") {
|
|
1256
1239
|
const codexInput = dependencies.codexModelOverride?.trim()
|
|
@@ -14,7 +14,6 @@ const inbox_projection_js_1 = require("../agent/inbox-projection.cjs");
|
|
|
14
14
|
const api_1 = require("@opentelemetry/api");
|
|
15
15
|
const provider_error_classifier_js_1 = require("./provider-error-classifier.cjs");
|
|
16
16
|
const runtime_readiness_js_1 = require("./runtime-readiness.cjs");
|
|
17
|
-
const pi_official_auth_js_1 = require("./pi-official-auth.cjs");
|
|
18
17
|
const official_lark_cli_js_1 = require("../app/official-lark-cli.cjs");
|
|
19
18
|
const agent_lark_cli_workspace_js_1 = require("../app/agent-lark-cli-workspace.cjs");
|
|
20
19
|
const pi_compaction_recovery_js_1 = require("./pi-compaction-recovery.cjs");
|
|
@@ -103,37 +102,23 @@ function persistPreviousSession(agent, previous) {
|
|
|
103
102
|
// In-memory ref still holds for this process; restart will miss it only if this write failed.
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
|
-
function isBuiltinPiAgent(agent) {
|
|
107
|
-
return agent.adapter.id === "pi"
|
|
108
|
-
&& ((0, runtime_readiness_js_1.isBuiltinPiDistribution)(agent.config.piDistribution) || agent.config.runtime === "builtin-pi");
|
|
109
|
-
}
|
|
110
105
|
function authFailureScopeOf(agent) {
|
|
111
106
|
return {
|
|
112
107
|
runtime: agent.config.runtime,
|
|
113
108
|
model: agent.config.model,
|
|
114
|
-
piDistribution: agent.config.piDistribution,
|
|
115
109
|
adapterId: agent.adapter.id,
|
|
116
110
|
};
|
|
117
111
|
}
|
|
118
112
|
function currentAuthFailure(agent) {
|
|
119
113
|
if (!agent.authFailureActive)
|
|
120
114
|
return null;
|
|
121
|
-
const kind = agent.authFailureKind
|
|
122
|
-
?? (agent.authFailureProvider ? "missing-provider" : "generic");
|
|
123
|
-
if (kind === "missing-provider") {
|
|
124
|
-
if (!agent.authFailureProvider)
|
|
125
|
-
return null;
|
|
126
|
-
return { kind: "missing-provider", runtime: "pi", piDistribution: "builtin", provider: agent.authFailureProvider };
|
|
127
|
-
}
|
|
128
115
|
const runtime = agent.adapter.id === "codex" || agent.adapter.id === "claude" || agent.adapter.id === "pi"
|
|
129
116
|
? agent.adapter.id : null;
|
|
130
117
|
if (!runtime)
|
|
131
118
|
return null;
|
|
132
119
|
return {
|
|
133
|
-
kind: "generic",
|
|
120
|
+
kind: agent.authFailureKind === "missing-provider" ? "missing-provider" : "generic",
|
|
134
121
|
runtime,
|
|
135
|
-
...(runtime === "pi" && (agent.config.piDistribution === "builtin" || agent.config.piDistribution === "external")
|
|
136
|
-
? { piDistribution: agent.config.piDistribution } : {}),
|
|
137
122
|
provider: agent.authFailureProvider,
|
|
138
123
|
};
|
|
139
124
|
}
|
|
@@ -344,7 +329,6 @@ function createRuntimeHost(options) {
|
|
|
344
329
|
} : {}),
|
|
345
330
|
LARKIN_CONFIG_DIR: process.env.LARKIN_CONFIG_DIR,
|
|
346
331
|
LARKIN_HOME: process.env.LARKIN_HOME,
|
|
347
|
-
...(config.piDistribution ? { LARKIN_PI_DISTRIBUTION: config.piDistribution } : {}),
|
|
348
332
|
LARKIN_STATE_DIR: (0, pi_subagent_ledger_js_1.effectivePiStateDir)(config),
|
|
349
333
|
...(process.env.HOME ? { HOME: process.env.HOME } : {}),
|
|
350
334
|
...(process.env.SHELL ? { SHELL: process.env.SHELL } : {}),
|
|
@@ -606,10 +590,6 @@ function createRuntimeHost(options) {
|
|
|
606
590
|
messageId: record.messageId, status: "consumed" });
|
|
607
591
|
}
|
|
608
592
|
};
|
|
609
|
-
const ownedConfigDir = () => {
|
|
610
|
-
const value = process.env.LARKIN_CONFIG_DIR?.trim();
|
|
611
|
-
return value || null;
|
|
612
|
-
};
|
|
613
593
|
const projectAuthFailure = (agent, readiness, failure) => {
|
|
614
594
|
agent.authFailureActive = true;
|
|
615
595
|
agent.authFailureKind = failure.kind;
|
|
@@ -627,12 +607,7 @@ function createRuntimeHost(options) {
|
|
|
627
607
|
if (agent.authFailureKind !== "missing-provider" || !agent.authFailureProvider)
|
|
628
608
|
return true;
|
|
629
609
|
const failure = currentAuthFailure(agent);
|
|
630
|
-
|
|
631
|
-
return false;
|
|
632
|
-
const configDir = ownedConfigDir();
|
|
633
|
-
if (!configDir)
|
|
634
|
-
return false;
|
|
635
|
-
return (0, pi_official_auth_js_1.officialPiHasStoredProvider)(configDir, agent.config.agentId, agent.authFailureProvider);
|
|
610
|
+
return Boolean(failure && (0, runtime_readiness_js_1.authFailureAppliesTo)(authFailureScopeOf(agent), failure));
|
|
636
611
|
};
|
|
637
612
|
const resultFor = (agent, record, result) => {
|
|
638
613
|
if (result.status === "accepted") {
|
|
@@ -647,12 +622,12 @@ function createRuntimeHost(options) {
|
|
|
647
622
|
deliveryId: record.deliveryId, messageId: record.messageId, status: "accepted" });
|
|
648
623
|
return { status: "accepted", deliveryId: record.deliveryId };
|
|
649
624
|
}
|
|
650
|
-
const missing = result.status === "rejected" &&
|
|
625
|
+
const missing = result.status === "rejected" && agent.adapter.id === "pi"
|
|
651
626
|
? (0, runtime_readiness_js_1.classifyPiMissingCredentialRejection)(result.reason)
|
|
652
627
|
: null;
|
|
653
628
|
if (missing) {
|
|
654
629
|
const readiness = (0, runtime_readiness_js_1.missingProviderCredentialReadiness)(agent.adapter.id, missing.provider);
|
|
655
|
-
const reason = readiness.reason ??
|
|
630
|
+
const reason = readiness.reason ?? result.reason;
|
|
656
631
|
if (record.status !== "error") {
|
|
657
632
|
record.reason = reason;
|
|
658
633
|
record.retryable = false;
|
|
@@ -1629,26 +1604,30 @@ function createRuntimeHost(options) {
|
|
|
1629
1604
|
record.errorCategory = classifiedCategory;
|
|
1630
1605
|
else
|
|
1631
1606
|
delete record.errorCategory;
|
|
1632
|
-
const missing =
|
|
1607
|
+
const missing = agent.adapter.id === "pi"
|
|
1633
1608
|
? (0, runtime_readiness_js_1.classifyPiMissingCredentialRejection)(event.upstream?.message)
|
|
1634
1609
|
?? (0, runtime_readiness_js_1.classifyPiMissingCredentialRejection)(event.message)
|
|
1635
1610
|
: null;
|
|
1636
|
-
if (missing)
|
|
1611
|
+
if (missing) {
|
|
1612
|
+
record.retryable = false;
|
|
1613
|
+
record.errorCategory = "auth";
|
|
1637
1614
|
record.authProvider = missing.provider;
|
|
1638
|
-
|
|
1615
|
+
}
|
|
1616
|
+
const terminal = Boolean(missing) || !event.retryable;
|
|
1617
|
+
const finalRecord = setRecord(agent, record, terminal ? "error" : "pending");
|
|
1639
1618
|
if (finalRecord.status !== "consumed")
|
|
1640
1619
|
emit({ type: "delivery", agentId: agent.config.agentId,
|
|
1641
1620
|
deliveryId: record.deliveryId, messageId: record.messageId,
|
|
1642
|
-
status:
|
|
1643
|
-
if (
|
|
1644
|
-
const readiness = missing
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
}
|
|
1651
|
-
if (event.retryable && !agent.busy && !agent.turnInProgress)
|
|
1621
|
+
status: terminal ? "error" : "deferred", reason: event.message });
|
|
1622
|
+
if (missing) {
|
|
1623
|
+
const readiness = (0, runtime_readiness_js_1.missingProviderCredentialReadiness)(agent.adapter.id, missing.provider);
|
|
1624
|
+
projectAuthFailure(agent, readiness, { kind: "missing-provider", provider: missing.provider });
|
|
1625
|
+
}
|
|
1626
|
+
else if (event.errorCategory === "auth" && !event.retryable) {
|
|
1627
|
+
const readiness = (0, runtime_readiness_js_1.providerAuthenticationFailureReadiness)(agent.adapter.id, event.upstream?.provider);
|
|
1628
|
+
projectAuthFailure(agent, readiness, { kind: "generic", provider: genericAuthProvider(agent, event.upstream) });
|
|
1629
|
+
}
|
|
1630
|
+
if (!terminal && event.retryable && !agent.busy && !agent.turnInProgress)
|
|
1652
1631
|
void retryPending(agent);
|
|
1653
1632
|
}
|
|
1654
1633
|
else if (event.type === "configuration-error") {
|
|
@@ -1923,7 +1902,6 @@ function createRuntimeHost(options) {
|
|
|
1923
1902
|
&& (0, runtime_readiness_js_1.authFailureAppliesTo)({
|
|
1924
1903
|
runtime: config.runtime,
|
|
1925
1904
|
model: config.model,
|
|
1926
|
-
piDistribution: config.piDistribution,
|
|
1927
1905
|
adapterId: adapter.id,
|
|
1928
1906
|
}, previousFailure));
|
|
1929
1907
|
const candidate = {
|
|
@@ -6,8 +6,7 @@ import { auditReminderDelivery } from "../agent/reminder-delivery-audit.mjs";
|
|
|
6
6
|
import { isCanonicalInboxTarget, targetKeyOfInboxEnvelope } from "../agent/inbox-projection.mjs";
|
|
7
7
|
import { SpanKind } from "@opentelemetry/api";
|
|
8
8
|
import { buildStrictProviderErrorInput, classifyStrictProviderError } from "./provider-error-classifier.mjs";
|
|
9
|
-
import { authFailureAppliesTo, classifyPiMissingCredentialRejection, classifyRuntimePrerequisite, configuredProviderId,
|
|
10
|
-
import { officialPiHasStoredProvider } from "./pi-official-auth.mjs";
|
|
9
|
+
import { authFailureAppliesTo, classifyPiMissingCredentialRejection, classifyRuntimePrerequisite, configuredProviderId, missingProviderCredentialReadiness, parsePersistedAuthFailure, providerAuthenticationFailureReadiness, readinessForPersistedAuthFailure, safeProviderId, RuntimePrerequisiteError, } from "./runtime-readiness.mjs";
|
|
11
10
|
import { resolveOfficialLarkCli } from "../app/official-lark-cli.mjs";
|
|
12
11
|
import { assertAgentWorkspaceBound, managedLarkCliEnv } from "../app/agent-lark-cli-workspace.mjs";
|
|
13
12
|
import { isPiNativeCompactionRequired, PiCompactionBreaker, PiCompactionRecoveryMachine, } from "./pi-compaction-recovery.mjs";
|
|
@@ -94,37 +93,23 @@ function persistPreviousSession(agent, previous) {
|
|
|
94
93
|
// In-memory ref still holds for this process; restart will miss it only if this write failed.
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
|
-
function isBuiltinPiAgent(agent) {
|
|
98
|
-
return agent.adapter.id === "pi"
|
|
99
|
-
&& (isBuiltinPiDistribution(agent.config.piDistribution) || agent.config.runtime === "builtin-pi");
|
|
100
|
-
}
|
|
101
96
|
function authFailureScopeOf(agent) {
|
|
102
97
|
return {
|
|
103
98
|
runtime: agent.config.runtime,
|
|
104
99
|
model: agent.config.model,
|
|
105
|
-
piDistribution: agent.config.piDistribution,
|
|
106
100
|
adapterId: agent.adapter.id,
|
|
107
101
|
};
|
|
108
102
|
}
|
|
109
103
|
function currentAuthFailure(agent) {
|
|
110
104
|
if (!agent.authFailureActive)
|
|
111
105
|
return null;
|
|
112
|
-
const kind = agent.authFailureKind
|
|
113
|
-
?? (agent.authFailureProvider ? "missing-provider" : "generic");
|
|
114
|
-
if (kind === "missing-provider") {
|
|
115
|
-
if (!agent.authFailureProvider)
|
|
116
|
-
return null;
|
|
117
|
-
return { kind: "missing-provider", runtime: "pi", piDistribution: "builtin", provider: agent.authFailureProvider };
|
|
118
|
-
}
|
|
119
106
|
const runtime = agent.adapter.id === "codex" || agent.adapter.id === "claude" || agent.adapter.id === "pi"
|
|
120
107
|
? agent.adapter.id : null;
|
|
121
108
|
if (!runtime)
|
|
122
109
|
return null;
|
|
123
110
|
return {
|
|
124
|
-
kind: "generic",
|
|
111
|
+
kind: agent.authFailureKind === "missing-provider" ? "missing-provider" : "generic",
|
|
125
112
|
runtime,
|
|
126
|
-
...(runtime === "pi" && (agent.config.piDistribution === "builtin" || agent.config.piDistribution === "external")
|
|
127
|
-
? { piDistribution: agent.config.piDistribution } : {}),
|
|
128
113
|
provider: agent.authFailureProvider,
|
|
129
114
|
};
|
|
130
115
|
}
|
|
@@ -335,7 +320,6 @@ export function createRuntimeHost(options) {
|
|
|
335
320
|
} : {}),
|
|
336
321
|
LARKIN_CONFIG_DIR: process.env.LARKIN_CONFIG_DIR,
|
|
337
322
|
LARKIN_HOME: process.env.LARKIN_HOME,
|
|
338
|
-
...(config.piDistribution ? { LARKIN_PI_DISTRIBUTION: config.piDistribution } : {}),
|
|
339
323
|
LARKIN_STATE_DIR: effectivePiStateDir(config),
|
|
340
324
|
...(process.env.HOME ? { HOME: process.env.HOME } : {}),
|
|
341
325
|
...(process.env.SHELL ? { SHELL: process.env.SHELL } : {}),
|
|
@@ -597,10 +581,6 @@ export function createRuntimeHost(options) {
|
|
|
597
581
|
messageId: record.messageId, status: "consumed" });
|
|
598
582
|
}
|
|
599
583
|
};
|
|
600
|
-
const ownedConfigDir = () => {
|
|
601
|
-
const value = process.env.LARKIN_CONFIG_DIR?.trim();
|
|
602
|
-
return value || null;
|
|
603
|
-
};
|
|
604
584
|
const projectAuthFailure = (agent, readiness, failure) => {
|
|
605
585
|
agent.authFailureActive = true;
|
|
606
586
|
agent.authFailureKind = failure.kind;
|
|
@@ -618,12 +598,7 @@ export function createRuntimeHost(options) {
|
|
|
618
598
|
if (agent.authFailureKind !== "missing-provider" || !agent.authFailureProvider)
|
|
619
599
|
return true;
|
|
620
600
|
const failure = currentAuthFailure(agent);
|
|
621
|
-
|
|
622
|
-
return false;
|
|
623
|
-
const configDir = ownedConfigDir();
|
|
624
|
-
if (!configDir)
|
|
625
|
-
return false;
|
|
626
|
-
return officialPiHasStoredProvider(configDir, agent.config.agentId, agent.authFailureProvider);
|
|
601
|
+
return Boolean(failure && authFailureAppliesTo(authFailureScopeOf(agent), failure));
|
|
627
602
|
};
|
|
628
603
|
const resultFor = (agent, record, result) => {
|
|
629
604
|
if (result.status === "accepted") {
|
|
@@ -638,12 +613,12 @@ export function createRuntimeHost(options) {
|
|
|
638
613
|
deliveryId: record.deliveryId, messageId: record.messageId, status: "accepted" });
|
|
639
614
|
return { status: "accepted", deliveryId: record.deliveryId };
|
|
640
615
|
}
|
|
641
|
-
const missing = result.status === "rejected" &&
|
|
616
|
+
const missing = result.status === "rejected" && agent.adapter.id === "pi"
|
|
642
617
|
? classifyPiMissingCredentialRejection(result.reason)
|
|
643
618
|
: null;
|
|
644
619
|
if (missing) {
|
|
645
620
|
const readiness = missingProviderCredentialReadiness(agent.adapter.id, missing.provider);
|
|
646
|
-
const reason = readiness.reason ??
|
|
621
|
+
const reason = readiness.reason ?? result.reason;
|
|
647
622
|
if (record.status !== "error") {
|
|
648
623
|
record.reason = reason;
|
|
649
624
|
record.retryable = false;
|
|
@@ -1620,26 +1595,30 @@ export function createRuntimeHost(options) {
|
|
|
1620
1595
|
record.errorCategory = classifiedCategory;
|
|
1621
1596
|
else
|
|
1622
1597
|
delete record.errorCategory;
|
|
1623
|
-
const missing =
|
|
1598
|
+
const missing = agent.adapter.id === "pi"
|
|
1624
1599
|
? classifyPiMissingCredentialRejection(event.upstream?.message)
|
|
1625
1600
|
?? classifyPiMissingCredentialRejection(event.message)
|
|
1626
1601
|
: null;
|
|
1627
|
-
if (missing)
|
|
1602
|
+
if (missing) {
|
|
1603
|
+
record.retryable = false;
|
|
1604
|
+
record.errorCategory = "auth";
|
|
1628
1605
|
record.authProvider = missing.provider;
|
|
1629
|
-
|
|
1606
|
+
}
|
|
1607
|
+
const terminal = Boolean(missing) || !event.retryable;
|
|
1608
|
+
const finalRecord = setRecord(agent, record, terminal ? "error" : "pending");
|
|
1630
1609
|
if (finalRecord.status !== "consumed")
|
|
1631
1610
|
emit({ type: "delivery", agentId: agent.config.agentId,
|
|
1632
1611
|
deliveryId: record.deliveryId, messageId: record.messageId,
|
|
1633
|
-
status:
|
|
1634
|
-
if (
|
|
1635
|
-
const readiness = missing
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
}
|
|
1642
|
-
if (event.retryable && !agent.busy && !agent.turnInProgress)
|
|
1612
|
+
status: terminal ? "error" : "deferred", reason: event.message });
|
|
1613
|
+
if (missing) {
|
|
1614
|
+
const readiness = missingProviderCredentialReadiness(agent.adapter.id, missing.provider);
|
|
1615
|
+
projectAuthFailure(agent, readiness, { kind: "missing-provider", provider: missing.provider });
|
|
1616
|
+
}
|
|
1617
|
+
else if (event.errorCategory === "auth" && !event.retryable) {
|
|
1618
|
+
const readiness = providerAuthenticationFailureReadiness(agent.adapter.id, event.upstream?.provider);
|
|
1619
|
+
projectAuthFailure(agent, readiness, { kind: "generic", provider: genericAuthProvider(agent, event.upstream) });
|
|
1620
|
+
}
|
|
1621
|
+
if (!terminal && event.retryable && !agent.busy && !agent.turnInProgress)
|
|
1643
1622
|
void retryPending(agent);
|
|
1644
1623
|
}
|
|
1645
1624
|
else if (event.type === "configuration-error") {
|
|
@@ -1914,7 +1893,6 @@ export function createRuntimeHost(options) {
|
|
|
1914
1893
|
&& authFailureAppliesTo({
|
|
1915
1894
|
runtime: config.runtime,
|
|
1916
1895
|
model: config.model,
|
|
1917
|
-
piDistribution: config.piDistribution,
|
|
1918
1896
|
adapterId: adapter.id,
|
|
1919
1897
|
}, previousFailure));
|
|
1920
1898
|
const candidate = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CURRENT_RUNTIME_MODELS = void 0;
|
|
4
|
-
// Authored catalog keys are adapter ids only.
|
|
4
|
+
// Authored catalog keys are adapter ids only.
|
|
5
5
|
// Pi, Codex and Claude replace these placeholders/fallbacks at runtime with their machine-readable catalogs.
|
|
6
6
|
// Claude's supported stdin control-channel list is the live authority; its entries below
|
|
7
7
|
// remain explicit compatibility candidates for config loading and discovery failures.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Authored catalog keys are adapter ids only.
|
|
1
|
+
// Authored catalog keys are adapter ids only.
|
|
2
2
|
// Pi, Codex and Claude replace these placeholders/fallbacks at runtime with their machine-readable catalogs.
|
|
3
3
|
// Claude's supported stdin control-channel list is the live authority; its entries below
|
|
4
4
|
// remain explicit compatibility candidates for config loading and discovery failures.
|