@codex-infinity/pi-infinity 0.62.3 → 0.63.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/README.md +2 -2
- package/dist/core/agent-session.d.ts +8 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +97 -54
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +3 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +5 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +2 -2
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +3 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +27 -26
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/types.d.ts +7 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts +18 -2
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +83 -69
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +4 -4
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +34 -18
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts +6 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +37 -5
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +13 -22
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/timings.d.ts +1 -0
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +6 -0
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +23 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +150 -57
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +18 -6
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +108 -59
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +4 -4
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/index.d.ts +12 -4
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +24 -9
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +0 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +2 -7
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +0 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +28 -65
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/development.md +3 -1
- package/docs/extensions.md +13 -2
- package/docs/models.md +6 -0
- package/docs/settings.md +12 -0
- package/docs/skills.md +3 -2
- package/examples/extensions/custom-compaction.ts +17 -4
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/handoff.ts +5 -2
- package/examples/extensions/qna.ts +5 -2
- package/examples/extensions/summarize.ts +15 -4
- package/examples/extensions/trigger-compact.ts +11 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +5 -4
|
@@ -134,6 +134,23 @@ export class AgentSession {
|
|
|
134
134
|
get modelRegistry() {
|
|
135
135
|
return this._modelRegistry;
|
|
136
136
|
}
|
|
137
|
+
async _getRequiredRequestAuth(model) {
|
|
138
|
+
const result = await this._modelRegistry.getApiKeyAndHeaders(model);
|
|
139
|
+
if (!result.ok) {
|
|
140
|
+
throw new Error(result.error);
|
|
141
|
+
}
|
|
142
|
+
if (result.apiKey) {
|
|
143
|
+
return { apiKey: result.apiKey, headers: result.headers };
|
|
144
|
+
}
|
|
145
|
+
const isOAuth = this._modelRegistry.isUsingOAuth(model);
|
|
146
|
+
if (isOAuth) {
|
|
147
|
+
throw new Error(`Authentication failed for "${model.provider}". ` +
|
|
148
|
+
`Credentials may have expired or network is unavailable. ` +
|
|
149
|
+
`Run '/login ${model.provider}' to re-authenticate.`);
|
|
150
|
+
}
|
|
151
|
+
throw new Error(`No API key found for ${model.provider}.\n\n` +
|
|
152
|
+
`Use /login or set an API key environment variable. See ${join(getDocsPath(), "providers.md")}`);
|
|
153
|
+
}
|
|
137
154
|
/**
|
|
138
155
|
* Install tool hooks once on the Agent instance.
|
|
139
156
|
*
|
|
@@ -674,9 +691,7 @@ export class AgentSession {
|
|
|
674
691
|
`Use /login or set an API key environment variable. See ${join(getDocsPath(), "providers.md")}\n\n` +
|
|
675
692
|
"Then use /model to select a model.");
|
|
676
693
|
}
|
|
677
|
-
|
|
678
|
-
const apiKey = await this._modelRegistry.getApiKey(this.model);
|
|
679
|
-
if (!apiKey) {
|
|
694
|
+
if (!this._modelRegistry.hasConfiguredAuth(this.model)) {
|
|
680
695
|
const isOAuth = this._modelRegistry.isUsingOAuth(this.model);
|
|
681
696
|
if (isOAuth) {
|
|
682
697
|
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
@@ -1053,12 +1068,11 @@ export class AgentSession {
|
|
|
1053
1068
|
}
|
|
1054
1069
|
/**
|
|
1055
1070
|
* Set model directly.
|
|
1056
|
-
* Validates
|
|
1057
|
-
* @throws Error if no
|
|
1071
|
+
* Validates that auth is configured, saves to session and settings.
|
|
1072
|
+
* @throws Error if no auth is configured for the model
|
|
1058
1073
|
*/
|
|
1059
1074
|
async setModel(model) {
|
|
1060
|
-
|
|
1061
|
-
if (!apiKey) {
|
|
1075
|
+
if (!this._modelRegistry.hasConfiguredAuth(model)) {
|
|
1062
1076
|
throw new Error(`No API key for ${model.provider}/${model.id}`);
|
|
1063
1077
|
}
|
|
1064
1078
|
const previousModel = this.model;
|
|
@@ -1082,27 +1096,11 @@ export class AgentSession {
|
|
|
1082
1096
|
}
|
|
1083
1097
|
return this._cycleAvailableModel(direction);
|
|
1084
1098
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
const result = [];
|
|
1088
|
-
for (const scoped of this._scopedModels) {
|
|
1089
|
-
const provider = scoped.model.provider;
|
|
1090
|
-
let apiKey;
|
|
1091
|
-
if (apiKeysByProvider.has(provider)) {
|
|
1092
|
-
apiKey = apiKeysByProvider.get(provider);
|
|
1093
|
-
}
|
|
1094
|
-
else {
|
|
1095
|
-
apiKey = await this._modelRegistry.getApiKeyForProvider(provider);
|
|
1096
|
-
apiKeysByProvider.set(provider, apiKey);
|
|
1097
|
-
}
|
|
1098
|
-
if (apiKey) {
|
|
1099
|
-
result.push(scoped);
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
return result;
|
|
1099
|
+
_getScopedModelsWithAuth() {
|
|
1100
|
+
return this._scopedModels.filter((scoped) => this._modelRegistry.hasConfiguredAuth(scoped.model));
|
|
1103
1101
|
}
|
|
1104
1102
|
async _cycleScopedModel(direction) {
|
|
1105
|
-
const scopedModels =
|
|
1103
|
+
const scopedModels = this._getScopedModelsWithAuth();
|
|
1106
1104
|
if (scopedModels.length <= 1)
|
|
1107
1105
|
return undefined;
|
|
1108
1106
|
const currentModel = this.model;
|
|
@@ -1136,10 +1134,6 @@ export class AgentSession {
|
|
|
1136
1134
|
const len = availableModels.length;
|
|
1137
1135
|
const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
|
|
1138
1136
|
const nextModel = availableModels[nextIndex];
|
|
1139
|
-
const apiKey = await this._modelRegistry.getApiKey(nextModel);
|
|
1140
|
-
if (!apiKey) {
|
|
1141
|
-
throw new Error(`No API key for ${nextModel.provider}/${nextModel.id}`);
|
|
1142
|
-
}
|
|
1143
1137
|
const thinkingLevel = this._getThinkingLevelForModelSwitch();
|
|
1144
1138
|
this.agent.setModel(nextModel);
|
|
1145
1139
|
this.sessionManager.appendModelChange(nextModel.provider, nextModel.id);
|
|
@@ -1264,14 +1258,12 @@ export class AgentSession {
|
|
|
1264
1258
|
this._disconnectFromAgent();
|
|
1265
1259
|
await this.abort();
|
|
1266
1260
|
this._compactionAbortController = new AbortController();
|
|
1261
|
+
this._emit({ type: "compaction_start", reason: "manual" });
|
|
1267
1262
|
try {
|
|
1268
1263
|
if (!this.model) {
|
|
1269
1264
|
throw new Error("No model selected");
|
|
1270
1265
|
}
|
|
1271
|
-
const apiKey = await this.
|
|
1272
|
-
if (!apiKey) {
|
|
1273
|
-
throw new Error(`No API key for ${this.model.provider}`);
|
|
1274
|
-
}
|
|
1266
|
+
const { apiKey, headers } = await this._getRequiredRequestAuth(this.model);
|
|
1275
1267
|
const pathEntries = this.sessionManager.getBranch();
|
|
1276
1268
|
const settings = this.settingsManager.getCompactionSettings();
|
|
1277
1269
|
const preparation = prepareCompaction(pathEntries, settings);
|
|
@@ -1314,7 +1306,7 @@ export class AgentSession {
|
|
|
1314
1306
|
}
|
|
1315
1307
|
else {
|
|
1316
1308
|
// Generate compaction result
|
|
1317
|
-
const result = await compact(preparation, this.model, apiKey, customInstructions, this._compactionAbortController.signal);
|
|
1309
|
+
const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal);
|
|
1318
1310
|
summary = result.summary;
|
|
1319
1311
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
1320
1312
|
tokensBefore = result.tokensBefore;
|
|
@@ -1336,12 +1328,33 @@ export class AgentSession {
|
|
|
1336
1328
|
fromExtension,
|
|
1337
1329
|
});
|
|
1338
1330
|
}
|
|
1339
|
-
|
|
1331
|
+
const compactionResult = {
|
|
1340
1332
|
summary,
|
|
1341
1333
|
firstKeptEntryId,
|
|
1342
1334
|
tokensBefore,
|
|
1343
1335
|
details,
|
|
1344
1336
|
};
|
|
1337
|
+
this._emit({
|
|
1338
|
+
type: "compaction_end",
|
|
1339
|
+
reason: "manual",
|
|
1340
|
+
result: compactionResult,
|
|
1341
|
+
aborted: false,
|
|
1342
|
+
willRetry: false,
|
|
1343
|
+
});
|
|
1344
|
+
return compactionResult;
|
|
1345
|
+
}
|
|
1346
|
+
catch (error) {
|
|
1347
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1348
|
+
const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
1349
|
+
this._emit({
|
|
1350
|
+
type: "compaction_end",
|
|
1351
|
+
reason: "manual",
|
|
1352
|
+
result: undefined,
|
|
1353
|
+
aborted,
|
|
1354
|
+
willRetry: false,
|
|
1355
|
+
errorMessage: aborted ? undefined : `Compaction failed: ${message}`,
|
|
1356
|
+
});
|
|
1357
|
+
throw error;
|
|
1345
1358
|
}
|
|
1346
1359
|
finally {
|
|
1347
1360
|
this._compactionAbortController = undefined;
|
|
@@ -1397,7 +1410,8 @@ export class AgentSession {
|
|
|
1397
1410
|
if (sameModel && isContextOverflow(assistantMessage, contextWindow)) {
|
|
1398
1411
|
if (this._overflowRecoveryAttempted) {
|
|
1399
1412
|
this._emit({
|
|
1400
|
-
type: "
|
|
1413
|
+
type: "compaction_end",
|
|
1414
|
+
reason: "overflow",
|
|
1401
1415
|
result: undefined,
|
|
1402
1416
|
aborted: false,
|
|
1403
1417
|
willRetry: false,
|
|
@@ -1447,22 +1461,41 @@ export class AgentSession {
|
|
|
1447
1461
|
*/
|
|
1448
1462
|
async _runAutoCompaction(reason, willRetry) {
|
|
1449
1463
|
const settings = this.settingsManager.getCompactionSettings();
|
|
1450
|
-
this._emit({ type: "
|
|
1464
|
+
this._emit({ type: "compaction_start", reason });
|
|
1451
1465
|
this._autoCompactionAbortController = new AbortController();
|
|
1452
1466
|
try {
|
|
1453
1467
|
if (!this.model) {
|
|
1454
|
-
this._emit({
|
|
1468
|
+
this._emit({
|
|
1469
|
+
type: "compaction_end",
|
|
1470
|
+
reason,
|
|
1471
|
+
result: undefined,
|
|
1472
|
+
aborted: false,
|
|
1473
|
+
willRetry: false,
|
|
1474
|
+
});
|
|
1455
1475
|
return;
|
|
1456
1476
|
}
|
|
1457
|
-
const
|
|
1458
|
-
if (!apiKey) {
|
|
1459
|
-
this._emit({
|
|
1477
|
+
const authResult = await this._modelRegistry.getApiKeyAndHeaders(this.model);
|
|
1478
|
+
if (!authResult.ok || !authResult.apiKey) {
|
|
1479
|
+
this._emit({
|
|
1480
|
+
type: "compaction_end",
|
|
1481
|
+
reason,
|
|
1482
|
+
result: undefined,
|
|
1483
|
+
aborted: false,
|
|
1484
|
+
willRetry: false,
|
|
1485
|
+
});
|
|
1460
1486
|
return;
|
|
1461
1487
|
}
|
|
1488
|
+
const { apiKey, headers } = authResult;
|
|
1462
1489
|
const pathEntries = this.sessionManager.getBranch();
|
|
1463
1490
|
const preparation = prepareCompaction(pathEntries, settings);
|
|
1464
1491
|
if (!preparation) {
|
|
1465
|
-
this._emit({
|
|
1492
|
+
this._emit({
|
|
1493
|
+
type: "compaction_end",
|
|
1494
|
+
reason,
|
|
1495
|
+
result: undefined,
|
|
1496
|
+
aborted: false,
|
|
1497
|
+
willRetry: false,
|
|
1498
|
+
});
|
|
1466
1499
|
return;
|
|
1467
1500
|
}
|
|
1468
1501
|
let extensionCompaction;
|
|
@@ -1476,7 +1509,13 @@ export class AgentSession {
|
|
|
1476
1509
|
signal: this._autoCompactionAbortController.signal,
|
|
1477
1510
|
}));
|
|
1478
1511
|
if (extensionResult?.cancel) {
|
|
1479
|
-
this._emit({
|
|
1512
|
+
this._emit({
|
|
1513
|
+
type: "compaction_end",
|
|
1514
|
+
reason,
|
|
1515
|
+
result: undefined,
|
|
1516
|
+
aborted: true,
|
|
1517
|
+
willRetry: false,
|
|
1518
|
+
});
|
|
1480
1519
|
return;
|
|
1481
1520
|
}
|
|
1482
1521
|
if (extensionResult?.compaction) {
|
|
@@ -1497,14 +1536,20 @@ export class AgentSession {
|
|
|
1497
1536
|
}
|
|
1498
1537
|
else {
|
|
1499
1538
|
// Generate compaction result
|
|
1500
|
-
const compactResult = await compact(preparation, this.model, apiKey, undefined, this._autoCompactionAbortController.signal);
|
|
1539
|
+
const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal);
|
|
1501
1540
|
summary = compactResult.summary;
|
|
1502
1541
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
1503
1542
|
tokensBefore = compactResult.tokensBefore;
|
|
1504
1543
|
details = compactResult.details;
|
|
1505
1544
|
}
|
|
1506
1545
|
if (this._autoCompactionAbortController.signal.aborted) {
|
|
1507
|
-
this._emit({
|
|
1546
|
+
this._emit({
|
|
1547
|
+
type: "compaction_end",
|
|
1548
|
+
reason,
|
|
1549
|
+
result: undefined,
|
|
1550
|
+
aborted: true,
|
|
1551
|
+
willRetry: false,
|
|
1552
|
+
});
|
|
1508
1553
|
return;
|
|
1509
1554
|
}
|
|
1510
1555
|
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension);
|
|
@@ -1526,7 +1571,7 @@ export class AgentSession {
|
|
|
1526
1571
|
tokensBefore,
|
|
1527
1572
|
details,
|
|
1528
1573
|
};
|
|
1529
|
-
this._emit({ type: "
|
|
1574
|
+
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry });
|
|
1530
1575
|
if (willRetry) {
|
|
1531
1576
|
const messages = this.agent.state.messages;
|
|
1532
1577
|
const lastMsg = messages[messages.length - 1];
|
|
@@ -1548,7 +1593,8 @@ export class AgentSession {
|
|
|
1548
1593
|
catch (error) {
|
|
1549
1594
|
const errorMessage = error instanceof Error ? error.message : "compaction failed";
|
|
1550
1595
|
this._emit({
|
|
1551
|
-
type: "
|
|
1596
|
+
type: "compaction_end",
|
|
1597
|
+
reason,
|
|
1552
1598
|
result: undefined,
|
|
1553
1599
|
aborted: false,
|
|
1554
1600
|
willRetry: false,
|
|
@@ -1708,8 +1754,7 @@ export class AgentSession {
|
|
|
1708
1754
|
refreshTools: () => this._refreshToolRegistry(),
|
|
1709
1755
|
getCommands,
|
|
1710
1756
|
setModel: async (model) => {
|
|
1711
|
-
|
|
1712
|
-
if (!key)
|
|
1757
|
+
if (!this.modelRegistry.hasConfiguredAuth(model))
|
|
1713
1758
|
return false;
|
|
1714
1759
|
await this.setModel(model);
|
|
1715
1760
|
return true;
|
|
@@ -2328,14 +2373,12 @@ export class AgentSession {
|
|
|
2328
2373
|
let summaryDetails;
|
|
2329
2374
|
if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
|
|
2330
2375
|
const model = this.model;
|
|
2331
|
-
const apiKey = await this.
|
|
2332
|
-
if (!apiKey) {
|
|
2333
|
-
throw new Error(`No API key for ${model.provider}`);
|
|
2334
|
-
}
|
|
2376
|
+
const { apiKey, headers } = await this._getRequiredRequestAuth(model);
|
|
2335
2377
|
const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
|
|
2336
2378
|
const result = await generateBranchSummary(entriesToSummarize, {
|
|
2337
2379
|
model,
|
|
2338
2380
|
apiKey,
|
|
2381
|
+
headers,
|
|
2339
2382
|
signal: this._branchSummaryAbortController.signal,
|
|
2340
2383
|
customInstructions,
|
|
2341
2384
|
replaceInstructions,
|