pi-sage 0.2.13 → 0.2.14
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/.pi/extensions/sage/index.ts +51 -15
- package/package.json +1 -1
|
@@ -7,14 +7,20 @@ import {
|
|
|
7
7
|
isHardCostCapExceeded,
|
|
8
8
|
makeBlockedResult
|
|
9
9
|
} from "./policy.js";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
isSageRunnerPolicyError,
|
|
12
|
+
runSageSingleShot,
|
|
13
|
+
type SageRunnerInput,
|
|
14
|
+
type SageRunnerOutput
|
|
15
|
+
} from "./runner.js";
|
|
11
16
|
import {
|
|
12
17
|
getSettingsPathForScope,
|
|
13
18
|
loadSettings,
|
|
14
19
|
mergeSettings,
|
|
15
20
|
saveSettings,
|
|
16
21
|
type SageSettings,
|
|
17
|
-
type SettingsScope
|
|
22
|
+
type SettingsScope,
|
|
23
|
+
type ToolPolicySettings
|
|
18
24
|
} from "./settings.js";
|
|
19
25
|
import { checkVolumeCaps, getDisallowedCustomTools, resolveToolPolicy } from "./tool-policy.js";
|
|
20
26
|
import type {
|
|
@@ -232,10 +238,8 @@ export default function registerSageExtension(pi: ExtensionAPI): void {
|
|
|
232
238
|
});
|
|
233
239
|
}
|
|
234
240
|
|
|
235
|
-
const toolPolicy = resolveToolPolicy(settings.toolPolicy);
|
|
236
|
-
|
|
237
241
|
try {
|
|
238
|
-
const
|
|
242
|
+
const runnerInput: Omit<SageRunnerInput, "toolPolicy"> = {
|
|
239
243
|
cwd: ctx.cwd,
|
|
240
244
|
model: resolvedModel,
|
|
241
245
|
reasoningLevel: settings.reasoningLevel,
|
|
@@ -246,11 +250,13 @@ export default function registerSageExtension(pi: ExtensionAPI): void {
|
|
|
246
250
|
evidence: input.evidence,
|
|
247
251
|
objective: input.objective,
|
|
248
252
|
urgency: input.urgency,
|
|
249
|
-
toolPolicy: settings.toolPolicy,
|
|
250
253
|
signal
|
|
251
|
-
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const invocation = await runSageWithFallback(runnerInput, settings.toolPolicy);
|
|
257
|
+
const toolPolicy = resolveToolPolicy(invocation.toolPolicyUsed);
|
|
252
258
|
|
|
253
|
-
const volume = checkVolumeCaps(
|
|
259
|
+
const volume = checkVolumeCaps(invocation.result.toolUsage, toolPolicy);
|
|
254
260
|
if (!volume.ok) {
|
|
255
261
|
return makeBlockedResult({
|
|
256
262
|
mode,
|
|
@@ -266,21 +272,25 @@ export default function registerSageExtension(pi: ExtensionAPI): void {
|
|
|
266
272
|
budgetState.callsThisTurn += 1;
|
|
267
273
|
budgetState.sessionCalls += 1;
|
|
268
274
|
if (mode === "autonomous") budgetState.lastAutoTurn = budgetState.currentTurn;
|
|
269
|
-
if (
|
|
275
|
+
if (invocation.result.usage?.costTotal) budgetState.sessionCostTotal += invocation.result.usage.costTotal;
|
|
276
|
+
|
|
277
|
+
const contextReason = invocation.fallbackReason
|
|
278
|
+
? "eligible; fallback to read-only-lite after blocked bash command"
|
|
279
|
+
: "eligible";
|
|
270
280
|
|
|
271
281
|
return {
|
|
272
|
-
content: [{ type: "text", text:
|
|
282
|
+
content: [{ type: "text", text: invocation.result.text }],
|
|
273
283
|
details: {
|
|
274
284
|
model: resolvedModel,
|
|
275
285
|
reasoningLevel: settings.reasoningLevel,
|
|
276
|
-
latencyMs:
|
|
277
|
-
stopReason:
|
|
278
|
-
usage:
|
|
279
|
-
toolUsage:
|
|
286
|
+
latencyMs: invocation.result.latencyMs,
|
|
287
|
+
stopReason: invocation.result.stopReason,
|
|
288
|
+
usage: invocation.result.usage,
|
|
289
|
+
toolUsage: invocation.result.toolUsage,
|
|
280
290
|
policy: {
|
|
281
291
|
mode,
|
|
282
292
|
allowedByContext: true,
|
|
283
|
-
contextReason
|
|
293
|
+
contextReason,
|
|
284
294
|
allowedByBudget: true,
|
|
285
295
|
budgetReason: softBudget.reason
|
|
286
296
|
}
|
|
@@ -353,6 +363,32 @@ function formatRunnerPolicyReason(blockCode: BlockCode, reason: string): string
|
|
|
353
363
|
return reason;
|
|
354
364
|
}
|
|
355
365
|
|
|
366
|
+
async function runSageWithFallback(
|
|
367
|
+
runnerInput: Omit<SageRunnerInput, "toolPolicy">,
|
|
368
|
+
toolPolicy: ToolPolicySettings
|
|
369
|
+
): Promise<{ result: SageRunnerOutput; toolPolicyUsed: ToolPolicySettings; fallbackReason?: string }> {
|
|
370
|
+
try {
|
|
371
|
+
const result = await runSageSingleShot({ ...runnerInput, toolPolicy });
|
|
372
|
+
return { result, toolPolicyUsed: toolPolicy };
|
|
373
|
+
} catch (error) {
|
|
374
|
+
if (
|
|
375
|
+
isSageRunnerPolicyError(error) &&
|
|
376
|
+
error.blockCode === "tool-disallowed" &&
|
|
377
|
+
toolPolicy.profile === "git-review-readonly"
|
|
378
|
+
) {
|
|
379
|
+
const fallbackPolicy: ToolPolicySettings = {
|
|
380
|
+
...toolPolicy,
|
|
381
|
+
profile: "read-only-lite"
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
const result = await runSageSingleShot({ ...runnerInput, toolPolicy: fallbackPolicy });
|
|
385
|
+
return { result, toolPolicyUsed: fallbackPolicy, fallbackReason: error.message };
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
356
392
|
function buildCallerContext(lastInputSource: InputSource | undefined, hasUI: boolean): CallerContext | null {
|
|
357
393
|
if (!lastInputSource) return null;
|
|
358
394
|
|