@caupulican/pi-adaptative 0.80.66 → 0.80.68
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 +12 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +31 -17
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/catalog-manager.d.ts +50 -0
- package/dist/core/catalog-manager.d.ts.map +1 -0
- package/dist/core/catalog-manager.js +0 -0
- package/dist/core/catalog-manager.js.map +1 -0
- package/dist/core/security/untrusted-boundary.d.ts +31 -0
- package/dist/core/security/untrusted-boundary.d.ts.map +1 -0
- package/dist/core/security/untrusted-boundary.js +60 -0
- package/dist/core/security/untrusted-boundary.js.map +1 -0
- package/dist/core/settings-manager.d.ts +5 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +14 -0
- package/dist/core/settings-manager.js.map +1 -1
- 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/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -41,6 +41,7 @@ import { compactToolResultDetailsForRetention } from "./message-retention.js";
|
|
|
41
41
|
import { resolveProfileModelSettings } from "./model-resolver.js";
|
|
42
42
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
43
43
|
import { stripResourceProfileBlocks } from "./resource-profile-blocks.js";
|
|
44
|
+
import { classifyToolTrust, UNTRUSTED_BOUNDARY_SYSTEM_RULE, wrapUntrustedText } from "./security/untrusted-boundary.js";
|
|
44
45
|
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
45
46
|
import { matchesResourceProfilePattern, } from "./settings-manager.js";
|
|
46
47
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
@@ -353,26 +354,37 @@ export class AgentSession {
|
|
|
353
354
|
};
|
|
354
355
|
this.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {
|
|
355
356
|
const runner = this._extensionRunner;
|
|
356
|
-
|
|
357
|
-
|
|
357
|
+
let content = result.content;
|
|
358
|
+
let details = result.details;
|
|
359
|
+
let resolvedIsError = isError;
|
|
360
|
+
if (runner.hasHandlers("tool_result")) {
|
|
361
|
+
const hookResult = await runner.emitToolResult({
|
|
362
|
+
type: "tool_result",
|
|
363
|
+
toolName: toolCall.name,
|
|
364
|
+
toolCallId: toolCall.id,
|
|
365
|
+
input: args,
|
|
366
|
+
content,
|
|
367
|
+
details,
|
|
368
|
+
isError,
|
|
369
|
+
});
|
|
370
|
+
if (hookResult) {
|
|
371
|
+
content = hookResult.content ?? content;
|
|
372
|
+
details = hookResult.details;
|
|
373
|
+
resolvedIsError = hookResult.isError ?? isError;
|
|
374
|
+
}
|
|
358
375
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
content:
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (!hookResult) {
|
|
376
|
+
// Untrusted-content boundary: structurally fence output from attacker-controllable sources
|
|
377
|
+
// (web/search, subagents, recall, third-party tools) so injection payloads are framed as data.
|
|
378
|
+
// First-party tools (read/grep/find/ls/edit/write/bash) are trusted and pass through unchanged.
|
|
379
|
+
if (classifyToolTrust(toolCall.name) === "untrusted") {
|
|
380
|
+
const source = `tool:${toolCall.name}`;
|
|
381
|
+
const wrapped = content.map((block) => block.type === "text" ? { ...block, text: wrapUntrustedText(block.text, source) } : block);
|
|
382
|
+
content = wrapped;
|
|
383
|
+
}
|
|
384
|
+
if (content === result.content && details === result.details && resolvedIsError === isError) {
|
|
369
385
|
return undefined;
|
|
370
386
|
}
|
|
371
|
-
return {
|
|
372
|
-
content: hookResult.content,
|
|
373
|
-
details: hookResult.details,
|
|
374
|
-
isError: hookResult.isError ?? isError,
|
|
375
|
-
};
|
|
387
|
+
return { content, details, isError: resolvedIsError };
|
|
376
388
|
};
|
|
377
389
|
}
|
|
378
390
|
// =========================================================================
|
|
@@ -901,6 +913,8 @@ export class AgentSession {
|
|
|
901
913
|
// R6: situational soul — the active profile's identity prefix, switched atomically with the
|
|
902
914
|
// profile's capabilities/model. Most prominent, so it comes first.
|
|
903
915
|
this._buildSituationSoulPrompt(),
|
|
916
|
+
// Always-on untrusted-content boundary contract (gives the <untrusted_content> fences meaning).
|
|
917
|
+
UNTRUSTED_BOUNDARY_SYSTEM_RULE,
|
|
904
918
|
this._buildSelfModificationPrompt(),
|
|
905
919
|
this._buildAutonomyPrompt(),
|
|
906
920
|
// Memory subsystem: static, frozen-per-session block (e.g. file-store MEMORY.md/USER.md).
|