larkin 0.4.28 → 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 -84
- package/dist/app/binary-entry.mjs +0 -20
- package/dist/app/cli.mjs +8 -14
- package/dist/app/internal-command.cjs +0 -2
- package/dist/app/internal-command.mjs +0 -2
- package/dist/app/local-control.mjs +16 -3
- package/dist/app/runtime-model-directory.mjs +2 -16
- package/dist/app/runtime-process.mjs +42 -6
- package/dist/app/setup.mjs +52 -57
- package/dist/dashboard/dashboard-config-controller.mjs +83 -24
- package/dist/dashboard/dashboard-view-model.mjs +4 -7
- package/dist/dashboard/web/assets/dashboard.js +1 -1
- package/dist/feishu/host-shell.cjs +68 -17
- package/dist/feishu/host-shell.mjs +69 -18
- package/dist/platform/config.cjs +201 -138
- package/dist/platform/config.mjs +199 -138
- 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 +41 -38
- package/dist/runtime/runtime-host.cjs +197 -20
- package/dist/runtime/runtime-host.mjs +198 -21
- package/dist/runtime/runtime-model-catalog.cjs +1 -1
- package/dist/runtime/runtime-model-catalog.mjs +1 -1
- package/dist/runtime/runtime-readiness.cjs +112 -49
- package/dist/runtime/runtime-readiness.mjs +103 -49
- 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 -67
- 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.mjs +0 -491
- 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 -331
- package/dist/runtime/pi-provider-config.mjs +0 -314
|
@@ -121,7 +121,7 @@ function memberNamesFromPayloads(payloads) {
|
|
|
121
121
|
function errorMessage(error) { return error instanceof Error ? error.message : String(error); }
|
|
122
122
|
function agentConfigSignature(agent) {
|
|
123
123
|
return JSON.stringify({
|
|
124
|
-
agentId: agent.agentId, runtime: agent.runtime, model: agent.model,
|
|
124
|
+
agentId: agent.agentId, runtime: agent.runtime, model: agent.model, effort: agent.effort ?? null,
|
|
125
125
|
feishuAppId: agent.feishuAppId, feishuProfile: agent.feishuProfile,
|
|
126
126
|
larkConfigDir: agent.larkConfigDir, feishuDomain: agent.feishuDomain,
|
|
127
127
|
feishuAppSecret: agent.feishuAppSecret, workspaceDir: agent.workspaceDir, stateDir: agent.stateDir,
|
|
@@ -208,26 +208,71 @@ function createHostShell({ env = process.env, runtimeHost, channelPackage, event
|
|
|
208
208
|
runtimeReadiness: { runtime: agent.runtime, state: "unavailable", reason, nextAction: "Wait for the current daemon epoch to publish Runtime readiness.", observedAt: new Date().toISOString() },
|
|
209
209
|
});
|
|
210
210
|
};
|
|
211
|
+
const unresolvedCurrentAuth = (agent) => {
|
|
212
|
+
try {
|
|
213
|
+
const persisted = (0, runtime_readiness_js_1.parsePersistedAuthFailure)(stateStore(agent).readJson("agentState", {}));
|
|
214
|
+
if (!persisted)
|
|
215
|
+
return null;
|
|
216
|
+
// 只使用当前 agentState 作用域标记,不扫描历史 delivery 的 authProvider。
|
|
217
|
+
return (0, runtime_readiness_js_1.authFailureAppliesTo)({
|
|
218
|
+
runtime: agent.runtime,
|
|
219
|
+
model: agent.model,
|
|
220
|
+
}, persisted) ? persisted : null;
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
const projectReadyUnlessUnresolvedAuth = (agent, observedAt) => {
|
|
227
|
+
const failure = unresolvedCurrentAuth(agent);
|
|
228
|
+
if (failure) {
|
|
229
|
+
hostState.updateStatus(agent, {
|
|
230
|
+
runtimeReadiness: { ...(0, runtime_readiness_js_1.readinessForPersistedAuthFailure)(failure), observedAt },
|
|
231
|
+
});
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
hostState.updateStatus(agent, { runtimeReadiness: { runtime: agent.runtime, state: "ready", observedAt } });
|
|
235
|
+
};
|
|
211
236
|
const recordInboundDeliveryFailure = (agent, code) => {
|
|
212
237
|
const at = new Date().toISOString();
|
|
213
238
|
const reason = "Inbound Runtime delivery failed non-retryably; durable Inbox/ledger state is retained for recovery.";
|
|
214
239
|
const nextAction = "Inspect the delivery/status error, correct the Runtime or canonical Inbox state, then restart to replay safely.";
|
|
240
|
+
const currentReadiness = hostState.readStatus(agent).runtimeReadiness;
|
|
215
241
|
hostState.updateStatus(agent, {
|
|
216
242
|
inboundDeliveryHealth: { state: "error", code, at, reason, nextAction },
|
|
217
|
-
|
|
243
|
+
...(currentReadiness?.state === "unauthenticated" ? {} : {
|
|
244
|
+
runtimeReadiness: { runtime: agent.runtime, state: "incompatible", reason, nextAction },
|
|
245
|
+
}),
|
|
218
246
|
});
|
|
219
247
|
hostState.recordStatusError(agent, `${reason} ${nextAction} code=${code}`);
|
|
220
248
|
};
|
|
221
249
|
const agentStates = new Map();
|
|
250
|
+
const mergePersistedAgentState = (record) => {
|
|
251
|
+
const latest = record.store.readJson("agentState", {});
|
|
252
|
+
if (isRecord(latest.previousSessions)) {
|
|
253
|
+
record.state.previousSessions = {
|
|
254
|
+
...latest.previousSessions,
|
|
255
|
+
...(record.state.previousSessions ?? {}),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
const persisted = (0, runtime_readiness_js_1.parsePersistedAuthFailure)(latest);
|
|
259
|
+
if (persisted) {
|
|
260
|
+
record.state.authFailure = persisted;
|
|
261
|
+
if (persisted.kind === "missing-provider" && persisted.provider) {
|
|
262
|
+
record.state.authFailureProvider = persisted.provider;
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
delete record.state.authFailureProvider;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
delete record.state.authFailure;
|
|
270
|
+
delete record.state.authFailureProvider;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
222
273
|
const saveAgentState = (record) => {
|
|
223
274
|
try {
|
|
224
|
-
|
|
225
|
-
if (isRecord(latest.previousSessions)) {
|
|
226
|
-
record.state.previousSessions = {
|
|
227
|
-
...latest.previousSessions,
|
|
228
|
-
...(record.state.previousSessions ?? {}),
|
|
229
|
-
};
|
|
230
|
-
}
|
|
275
|
+
mergePersistedAgentState(record);
|
|
231
276
|
record.store.writeJson("agentState", record.state);
|
|
232
277
|
}
|
|
233
278
|
catch (error) {
|
|
@@ -1276,12 +1321,16 @@ function createHostShell({ env = process.env, runtimeHost, channelPackage, event
|
|
|
1276
1321
|
observedAt,
|
|
1277
1322
|
},
|
|
1278
1323
|
});
|
|
1279
|
-
else if (message.readiness)
|
|
1280
|
-
|
|
1324
|
+
else if (message.readiness) {
|
|
1325
|
+
if (message.readiness.state === "ready" && unresolvedCurrentAuth(agent)) {
|
|
1326
|
+
projectReadyUnlessUnresolvedAuth(agent, observedAt);
|
|
1327
|
+
}
|
|
1328
|
+
else {
|
|
1329
|
+
hostState.updateStatus(agent, { runtimeReadiness: { ...message.readiness, observedAt } });
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1281
1332
|
else if (message.status === "active")
|
|
1282
|
-
|
|
1283
|
-
runtime: agent.runtime, state: "ready", observedAt,
|
|
1284
|
-
} });
|
|
1333
|
+
projectReadyUnlessUnresolvedAuth(agent, observedAt);
|
|
1285
1334
|
if (message.status === "active") {
|
|
1286
1335
|
const redeliveryTimer = setTimeout(() => {
|
|
1287
1336
|
void reminder.redeliverUnread(agent).catch((error) => log("启动补投失败", errorMessage(error)));
|
|
@@ -1448,6 +1497,7 @@ function createHostShell({ env = process.env, runtimeHost, channelPackage, event
|
|
|
1448
1497
|
record.state.sessions[agent.runtime] = reset.sessionId;
|
|
1449
1498
|
else
|
|
1450
1499
|
delete record.state.sessions[agent.runtime];
|
|
1500
|
+
mergePersistedAgentState(record);
|
|
1451
1501
|
record.store.writeJson("agentState", record.state);
|
|
1452
1502
|
}
|
|
1453
1503
|
if (!reset.sessionId) {
|
|
@@ -1455,11 +1505,11 @@ function createHostShell({ env = process.env, runtimeHost, channelPackage, event
|
|
|
1455
1505
|
hostState.updateStatus(agent, {
|
|
1456
1506
|
session: { runtime: agent.runtime, id: null, launchId: null, startedAt: observedAt,
|
|
1457
1507
|
lastSeenAt: null, lastTurnAt: null, turns: 0 },
|
|
1458
|
-
runtimeReadiness: { runtime: agent.runtime, state: "ready", observedAt },
|
|
1459
1508
|
});
|
|
1509
|
+
projectReadyUnlessUnresolvedAuth(agent, observedAt);
|
|
1460
1510
|
}
|
|
1461
1511
|
else if (reset.runtimeReady) {
|
|
1462
|
-
|
|
1512
|
+
projectReadyUnlessUnresolvedAuth(agent, new Date().toISOString());
|
|
1463
1513
|
}
|
|
1464
1514
|
}
|
|
1465
1515
|
catch (error) {
|
|
@@ -1527,7 +1577,7 @@ function createHostShell({ env = process.env, runtimeHost, channelPackage, event
|
|
|
1527
1577
|
throw Object.assign(error instanceof Error ? error : new Error(String(error)), readinessProjection());
|
|
1528
1578
|
}
|
|
1529
1579
|
if (recovery.runtimeReady) {
|
|
1530
|
-
|
|
1580
|
+
projectReadyUnlessUnresolvedAuth(agent, new Date().toISOString());
|
|
1531
1581
|
}
|
|
1532
1582
|
const record = agentStates.get(agentId);
|
|
1533
1583
|
try {
|
|
@@ -1536,6 +1586,7 @@ function createHostShell({ env = process.env, runtimeHost, channelPackage, event
|
|
|
1536
1586
|
record.state.sessions[agent.runtime] = recovery.sessionId;
|
|
1537
1587
|
else
|
|
1538
1588
|
delete record.state.sessions[agent.runtime];
|
|
1589
|
+
mergePersistedAgentState(record);
|
|
1539
1590
|
record.store.writeJson("agentState", record.state);
|
|
1540
1591
|
}
|
|
1541
1592
|
}
|
|
@@ -16,7 +16,7 @@ import { inboxAuditRegistryFile, observeInboxAuditTarget } from "../agent/missed
|
|
|
16
16
|
import { HostChannelBusiness } from "./host-channel-business.mjs";
|
|
17
17
|
import { HostInteractionOrchestrator } from "./interaction-orchestrator.mjs";
|
|
18
18
|
import { targetFor } from "./message-policy.mjs";
|
|
19
|
-
import { providerAuthenticationFailureReadiness, RuntimePrerequisiteError } from "../runtime/runtime-readiness.mjs";
|
|
19
|
+
import { authFailureAppliesTo, parsePersistedAuthFailure, providerAuthenticationFailureReadiness, readinessForPersistedAuthFailure, RuntimePrerequisiteError, } from "../runtime/runtime-readiness.mjs";
|
|
20
20
|
import { readDocumentCommentSubscription, verifyCallbackProbe } from "../platform/callback-capability.mjs";
|
|
21
21
|
import { loadConfig, resolveMentionPolicy } from "../platform/config.mjs";
|
|
22
22
|
import { processCommandToken } from "../app/internal-command.mjs";
|
|
@@ -81,7 +81,7 @@ export function memberNamesFromPayloads(payloads) {
|
|
|
81
81
|
function errorMessage(error) { return error instanceof Error ? error.message : String(error); }
|
|
82
82
|
function agentConfigSignature(agent) {
|
|
83
83
|
return JSON.stringify({
|
|
84
|
-
agentId: agent.agentId, runtime: agent.runtime, model: agent.model,
|
|
84
|
+
agentId: agent.agentId, runtime: agent.runtime, model: agent.model, effort: agent.effort ?? null,
|
|
85
85
|
feishuAppId: agent.feishuAppId, feishuProfile: agent.feishuProfile,
|
|
86
86
|
larkConfigDir: agent.larkConfigDir, feishuDomain: agent.feishuDomain,
|
|
87
87
|
feishuAppSecret: agent.feishuAppSecret, workspaceDir: agent.workspaceDir, stateDir: agent.stateDir,
|
|
@@ -168,26 +168,71 @@ export function createHostShell({ env = process.env, runtimeHost, channelPackage
|
|
|
168
168
|
runtimeReadiness: { runtime: agent.runtime, state: "unavailable", reason, nextAction: "Wait for the current daemon epoch to publish Runtime readiness.", observedAt: new Date().toISOString() },
|
|
169
169
|
});
|
|
170
170
|
};
|
|
171
|
+
const unresolvedCurrentAuth = (agent) => {
|
|
172
|
+
try {
|
|
173
|
+
const persisted = parsePersistedAuthFailure(stateStore(agent).readJson("agentState", {}));
|
|
174
|
+
if (!persisted)
|
|
175
|
+
return null;
|
|
176
|
+
// 只使用当前 agentState 作用域标记,不扫描历史 delivery 的 authProvider。
|
|
177
|
+
return authFailureAppliesTo({
|
|
178
|
+
runtime: agent.runtime,
|
|
179
|
+
model: agent.model,
|
|
180
|
+
}, persisted) ? persisted : null;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
const projectReadyUnlessUnresolvedAuth = (agent, observedAt) => {
|
|
187
|
+
const failure = unresolvedCurrentAuth(agent);
|
|
188
|
+
if (failure) {
|
|
189
|
+
hostState.updateStatus(agent, {
|
|
190
|
+
runtimeReadiness: { ...readinessForPersistedAuthFailure(failure), observedAt },
|
|
191
|
+
});
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
hostState.updateStatus(agent, { runtimeReadiness: { runtime: agent.runtime, state: "ready", observedAt } });
|
|
195
|
+
};
|
|
171
196
|
const recordInboundDeliveryFailure = (agent, code) => {
|
|
172
197
|
const at = new Date().toISOString();
|
|
173
198
|
const reason = "Inbound Runtime delivery failed non-retryably; durable Inbox/ledger state is retained for recovery.";
|
|
174
199
|
const nextAction = "Inspect the delivery/status error, correct the Runtime or canonical Inbox state, then restart to replay safely.";
|
|
200
|
+
const currentReadiness = hostState.readStatus(agent).runtimeReadiness;
|
|
175
201
|
hostState.updateStatus(agent, {
|
|
176
202
|
inboundDeliveryHealth: { state: "error", code, at, reason, nextAction },
|
|
177
|
-
|
|
203
|
+
...(currentReadiness?.state === "unauthenticated" ? {} : {
|
|
204
|
+
runtimeReadiness: { runtime: agent.runtime, state: "incompatible", reason, nextAction },
|
|
205
|
+
}),
|
|
178
206
|
});
|
|
179
207
|
hostState.recordStatusError(agent, `${reason} ${nextAction} code=${code}`);
|
|
180
208
|
};
|
|
181
209
|
const agentStates = new Map();
|
|
210
|
+
const mergePersistedAgentState = (record) => {
|
|
211
|
+
const latest = record.store.readJson("agentState", {});
|
|
212
|
+
if (isRecord(latest.previousSessions)) {
|
|
213
|
+
record.state.previousSessions = {
|
|
214
|
+
...latest.previousSessions,
|
|
215
|
+
...(record.state.previousSessions ?? {}),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const persisted = parsePersistedAuthFailure(latest);
|
|
219
|
+
if (persisted) {
|
|
220
|
+
record.state.authFailure = persisted;
|
|
221
|
+
if (persisted.kind === "missing-provider" && persisted.provider) {
|
|
222
|
+
record.state.authFailureProvider = persisted.provider;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
delete record.state.authFailureProvider;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
delete record.state.authFailure;
|
|
230
|
+
delete record.state.authFailureProvider;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
182
233
|
const saveAgentState = (record) => {
|
|
183
234
|
try {
|
|
184
|
-
|
|
185
|
-
if (isRecord(latest.previousSessions)) {
|
|
186
|
-
record.state.previousSessions = {
|
|
187
|
-
...latest.previousSessions,
|
|
188
|
-
...(record.state.previousSessions ?? {}),
|
|
189
|
-
};
|
|
190
|
-
}
|
|
235
|
+
mergePersistedAgentState(record);
|
|
191
236
|
record.store.writeJson("agentState", record.state);
|
|
192
237
|
}
|
|
193
238
|
catch (error) {
|
|
@@ -1236,12 +1281,16 @@ export function createHostShell({ env = process.env, runtimeHost, channelPackage
|
|
|
1236
1281
|
observedAt,
|
|
1237
1282
|
},
|
|
1238
1283
|
});
|
|
1239
|
-
else if (message.readiness)
|
|
1240
|
-
|
|
1284
|
+
else if (message.readiness) {
|
|
1285
|
+
if (message.readiness.state === "ready" && unresolvedCurrentAuth(agent)) {
|
|
1286
|
+
projectReadyUnlessUnresolvedAuth(agent, observedAt);
|
|
1287
|
+
}
|
|
1288
|
+
else {
|
|
1289
|
+
hostState.updateStatus(agent, { runtimeReadiness: { ...message.readiness, observedAt } });
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1241
1292
|
else if (message.status === "active")
|
|
1242
|
-
|
|
1243
|
-
runtime: agent.runtime, state: "ready", observedAt,
|
|
1244
|
-
} });
|
|
1293
|
+
projectReadyUnlessUnresolvedAuth(agent, observedAt);
|
|
1245
1294
|
if (message.status === "active") {
|
|
1246
1295
|
const redeliveryTimer = setTimeout(() => {
|
|
1247
1296
|
void reminder.redeliverUnread(agent).catch((error) => log("启动补投失败", errorMessage(error)));
|
|
@@ -1408,6 +1457,7 @@ export function createHostShell({ env = process.env, runtimeHost, channelPackage
|
|
|
1408
1457
|
record.state.sessions[agent.runtime] = reset.sessionId;
|
|
1409
1458
|
else
|
|
1410
1459
|
delete record.state.sessions[agent.runtime];
|
|
1460
|
+
mergePersistedAgentState(record);
|
|
1411
1461
|
record.store.writeJson("agentState", record.state);
|
|
1412
1462
|
}
|
|
1413
1463
|
if (!reset.sessionId) {
|
|
@@ -1415,11 +1465,11 @@ export function createHostShell({ env = process.env, runtimeHost, channelPackage
|
|
|
1415
1465
|
hostState.updateStatus(agent, {
|
|
1416
1466
|
session: { runtime: agent.runtime, id: null, launchId: null, startedAt: observedAt,
|
|
1417
1467
|
lastSeenAt: null, lastTurnAt: null, turns: 0 },
|
|
1418
|
-
runtimeReadiness: { runtime: agent.runtime, state: "ready", observedAt },
|
|
1419
1468
|
});
|
|
1469
|
+
projectReadyUnlessUnresolvedAuth(agent, observedAt);
|
|
1420
1470
|
}
|
|
1421
1471
|
else if (reset.runtimeReady) {
|
|
1422
|
-
|
|
1472
|
+
projectReadyUnlessUnresolvedAuth(agent, new Date().toISOString());
|
|
1423
1473
|
}
|
|
1424
1474
|
}
|
|
1425
1475
|
catch (error) {
|
|
@@ -1487,7 +1537,7 @@ export function createHostShell({ env = process.env, runtimeHost, channelPackage
|
|
|
1487
1537
|
throw Object.assign(error instanceof Error ? error : new Error(String(error)), readinessProjection());
|
|
1488
1538
|
}
|
|
1489
1539
|
if (recovery.runtimeReady) {
|
|
1490
|
-
|
|
1540
|
+
projectReadyUnlessUnresolvedAuth(agent, new Date().toISOString());
|
|
1491
1541
|
}
|
|
1492
1542
|
const record = agentStates.get(agentId);
|
|
1493
1543
|
try {
|
|
@@ -1496,6 +1546,7 @@ export function createHostShell({ env = process.env, runtimeHost, channelPackage
|
|
|
1496
1546
|
record.state.sessions[agent.runtime] = recovery.sessionId;
|
|
1497
1547
|
else
|
|
1498
1548
|
delete record.state.sessions[agent.runtime];
|
|
1549
|
+
mergePersistedAgentState(record);
|
|
1499
1550
|
record.store.writeJson("agentState", record.state);
|
|
1500
1551
|
}
|
|
1501
1552
|
}
|