@zihanw/pi-forge 0.4.0 → 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 +49 -1
- package/README.md +11 -11
- package/README.zh-CN.md +4 -6
- package/SUBAGENT_ADAPTER_CONTRACT.md +3 -1
- package/dist/agent-profile.d.ts +21 -42
- package/dist/agent-profile.d.ts.map +1 -1
- package/dist/agent-profile.js +82 -194
- package/dist/agent-profile.js.map +1 -1
- package/dist/catalog.d.ts +27 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +59 -0
- package/dist/catalog.js.map +1 -0
- package/dist/codecs/agent-profile.d.ts +53 -0
- package/dist/codecs/agent-profile.d.ts.map +1 -0
- package/dist/codecs/agent-profile.js +176 -0
- package/dist/codecs/agent-profile.js.map +1 -0
- package/dist/codecs/index.d.ts +5 -0
- package/dist/codecs/index.d.ts.map +1 -0
- package/dist/codecs/index.js +3 -0
- package/dist/codecs/index.js.map +1 -0
- package/dist/codecs/prompt-stack.d.ts +18 -0
- package/dist/codecs/prompt-stack.d.ts.map +1 -0
- package/dist/codecs/prompt-stack.js +479 -0
- package/dist/codecs/prompt-stack.js.map +1 -0
- package/dist/compile-cycle.d.ts +18 -0
- package/dist/compile-cycle.d.ts.map +1 -0
- package/dist/compile-cycle.js +13 -0
- package/dist/compile-cycle.js.map +1 -0
- package/dist/compiler.d.ts +10 -4
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +53 -19
- package/dist/compiler.js.map +1 -1
- package/dist/extension-registry.d.ts.map +1 -1
- package/dist/extension-registry.js +5 -2
- package/dist/extension-registry.js.map +1 -1
- package/dist/forge-config.d.ts +2 -81
- package/dist/forge-config.d.ts.map +1 -1
- package/dist/forge-config.js +5 -280
- package/dist/forge-config.js.map +1 -1
- package/dist/forge-v1/analyzer.d.ts +3 -0
- package/dist/forge-v1/analyzer.d.ts.map +1 -0
- package/dist/forge-v1/analyzer.js +50 -0
- package/dist/forge-v1/analyzer.js.map +1 -0
- package/dist/forge-v1/index.d.ts +6 -0
- package/dist/forge-v1/index.d.ts.map +1 -0
- package/dist/forge-v1/index.js +13 -0
- package/dist/forge-v1/index.js.map +1 -0
- package/dist/forge-v1/parser.d.ts +3 -0
- package/dist/forge-v1/parser.d.ts.map +1 -0
- package/dist/forge-v1/parser.js +186 -0
- package/dist/forge-v1/parser.js.map +1 -0
- package/dist/forge-v1/renderer.d.ts +9 -0
- package/dist/forge-v1/renderer.d.ts.map +1 -0
- package/dist/forge-v1/renderer.js +181 -0
- package/dist/forge-v1/renderer.js.map +1 -0
- package/dist/forge-v1/types.d.ts +87 -0
- package/dist/forge-v1/types.d.ts.map +1 -0
- package/dist/forge-v1/types.js +4 -0
- package/dist/forge-v1/types.js.map +1 -0
- package/dist/index.d.ts +12 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -59
- package/dist/index.js.map +1 -1
- package/dist/lifecycle.d.ts +7 -5
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +44 -110
- package/dist/lifecycle.js.map +1 -1
- package/dist/loader.d.ts +16 -3
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +42 -440
- package/dist/loader.js.map +1 -1
- package/dist/macro-engine.d.ts +9 -14
- package/dist/macro-engine.d.ts.map +1 -1
- package/dist/macro-engine.js +5 -238
- package/dist/macro-engine.js.map +1 -1
- package/dist/payload-command.d.ts +6 -6
- package/dist/payload-command.d.ts.map +1 -1
- package/dist/payload-command.js.map +1 -1
- package/dist/payload-state.d.ts +16 -0
- package/dist/payload-state.d.ts.map +1 -0
- package/dist/payload-state.js +14 -0
- package/dist/payload-state.js.map +1 -0
- package/dist/preset-command.d.ts +4 -4
- package/dist/preset-command.d.ts.map +1 -1
- package/dist/preset-command.js +55 -98
- package/dist/preset-command.js.map +1 -1
- package/dist/preview.d.ts +4 -4
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +17 -8
- package/dist/preview.js.map +1 -1
- package/dist/profile-command.d.ts +2 -2
- package/dist/profile-command.d.ts.map +1 -1
- package/dist/profile-command.js +52 -26
- package/dist/profile-command.js.map +1 -1
- package/dist/profile-service.d.ts +5 -2
- package/dist/profile-service.d.ts.map +1 -1
- package/dist/profile-service.js +63 -42
- package/dist/profile-service.js.map +1 -1
- package/dist/prompt-analysis.d.ts +24 -0
- package/dist/prompt-analysis.d.ts.map +1 -0
- package/dist/prompt-analysis.js +84 -0
- package/dist/prompt-analysis.js.map +1 -0
- package/dist/prompt-runtime.d.ts +19 -0
- package/dist/prompt-runtime.d.ts.map +1 -0
- package/dist/prompt-runtime.js +30 -0
- package/dist/prompt-runtime.js.map +1 -0
- package/dist/regex.js +6 -12
- package/dist/regex.js.map +1 -1
- package/dist/render-helpers.d.ts +2 -10
- package/dist/render-helpers.d.ts.map +1 -1
- package/dist/render-helpers.js +3 -53
- package/dist/render-helpers.js.map +1 -1
- package/dist/repositories/agent-profile.d.ts +36 -0
- package/dist/repositories/agent-profile.d.ts.map +1 -0
- package/dist/repositories/agent-profile.js +153 -0
- package/dist/repositories/agent-profile.js.map +1 -0
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.d.ts.map +1 -0
- package/dist/repositories/index.js +3 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/repositories/prompt-stack.d.ts +57 -0
- package/dist/repositories/prompt-stack.d.ts.map +1 -0
- package/dist/repositories/prompt-stack.js +175 -0
- package/dist/repositories/prompt-stack.js.map +1 -0
- package/dist/resource-identity.d.ts +33 -0
- package/dist/resource-identity.d.ts.map +1 -0
- package/dist/resource-identity.js +56 -0
- package/dist/resource-identity.js.map +1 -0
- package/dist/runtime/profile-runtime.d.ts +2 -2
- package/dist/runtime/profile-runtime.d.ts.map +1 -1
- package/dist/runtime/profile-runtime.js +18 -10
- package/dist/runtime/profile-runtime.js.map +1 -1
- package/dist/runtime/prompt-stack-runtime.d.ts +5 -4
- package/dist/runtime/prompt-stack-runtime.d.ts.map +1 -1
- package/dist/runtime/prompt-stack-runtime.js +47 -52
- package/dist/runtime/prompt-stack-runtime.js.map +1 -1
- package/dist/runtime/tool-policy-runtime.d.ts +2 -2
- package/dist/runtime/tool-policy-runtime.d.ts.map +1 -1
- package/dist/runtime/tool-policy-runtime.js +3 -3
- package/dist/runtime/tool-policy-runtime.js.map +1 -1
- package/dist/session-adapter.d.ts +17 -0
- package/dist/session-adapter.d.ts.map +1 -0
- package/dist/session-adapter.js +57 -0
- package/dist/session-adapter.js.map +1 -0
- package/dist/slot-renderers.d.ts +16 -3
- package/dist/slot-renderers.d.ts.map +1 -1
- package/dist/slot-renderers.js +15 -63
- package/dist/slot-renderers.js.map +1 -1
- package/dist/stack-migration.d.ts +6 -0
- package/dist/stack-migration.d.ts.map +1 -1
- package/dist/stack-migration.js +49 -52
- package/dist/stack-migration.js.map +1 -1
- package/dist/storage.d.ts +10 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +45 -10
- package/dist/storage.js.map +1 -1
- package/dist/subagent/fingerprints.d.ts +24 -0
- package/dist/subagent/fingerprints.d.ts.map +1 -0
- package/dist/subagent/fingerprints.js +81 -0
- package/dist/subagent/fingerprints.js.map +1 -0
- package/dist/subagent/host-port.d.ts +296 -0
- package/dist/subagent/host-port.d.ts.map +1 -0
- package/dist/subagent/host-port.js +560 -0
- package/dist/subagent/host-port.js.map +1 -0
- package/dist/subagent/index.d.ts +10 -10
- package/dist/subagent/index.d.ts.map +1 -1
- package/dist/subagent/index.js +9 -10
- package/dist/subagent/index.js.map +1 -1
- package/dist/subagent-host.d.ts +99 -18
- package/dist/subagent-host.d.ts.map +1 -1
- package/dist/subagent-host.js +185 -162
- package/dist/subagent-host.js.map +1 -1
- package/dist/template-render.d.ts +18 -0
- package/dist/template-render.d.ts.map +1 -0
- package/dist/template-render.js +232 -0
- package/dist/template-render.js.map +1 -0
- package/dist/types.d.ts +43 -27
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/web-editor/client-script.generated.d.ts.map +1 -1
- package/dist/web-editor/client-script.generated.js +1 -1
- package/dist/web-editor/client-script.generated.js.map +1 -1
- package/dist/web-editor/client-styles.generated.d.ts.map +1 -1
- package/dist/web-editor/client-styles.generated.js +1 -1
- package/dist/web-editor/client-styles.generated.js.map +1 -1
- package/dist/web-editor/server.d.ts.map +1 -1
- package/dist/web-editor/server.js +32 -72
- package/dist/web-editor/server.js.map +1 -1
- package/dist/web-editor/styles.d.ts.map +1 -1
- package/dist/web-editor/styles.js +13 -0
- package/dist/web-editor/styles.js.map +1 -1
- package/dist/web-editor/types.d.ts +10 -37
- package/dist/web-editor/types.d.ts.map +1 -1
- package/dist/web-host.d.ts +4 -2
- package/dist/web-host.d.ts.map +1 -1
- package/dist/web-host.js +110 -138
- package/dist/web-host.js.map +1 -1
- package/dist/workspace.d.ts +74 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +351 -0
- package/dist/workspace.js.map +1 -0
- package/docs/README.md +6 -4
- package/docs/concepts/agent-profiles.md +2 -2
- package/docs/concepts/prompt-stacks.md +12 -7
- package/docs/design/README.md +21 -3
- package/docs/design/architecture-0.5.md +211 -0
- package/docs/design/archive/0.5-full-proposal/0.5-consumer-audit.md +62 -0
- package/docs/design/archive/0.5-full-proposal/0.5-inventory.md +208 -0
- package/docs/design/archive/0.5-full-proposal/0.5-phase0-decision-drafts.md +237 -0
- package/docs/design/archive/0.5-full-proposal/README.md +12 -0
- package/docs/design/archive/0.5-full-proposal/architecture-0.5.md +423 -0
- package/docs/design/archive/0.5-full-proposal/host-discovery-spike.md +103 -0
- package/docs/design/archive/0.5-full-proposal/template-language-spike.md +156 -0
- package/docs/design/context-diff-plan.md +72 -0
- package/docs/design/decision-template.md +33 -0
- package/docs/design/roadmap-0.4-archive.md +1 -1
- package/docs/design/subagents/interface-design.md +1 -1
- package/docs/development/architecture-rules.md +148 -0
- package/docs/development/roadmap.md +39 -13
- package/docs/development/scoped-global-profiles-stacks.md +325 -0
- package/docs/development/setup.md +6 -4
- package/docs/getting-started.md +9 -6
- package/docs/guides/custom-macros-and-slots.md +8 -7
- package/docs/guides/debugging.md +1 -1
- package/docs/guides/delegation.md +25 -21
- package/docs/guides/migrating-to-0.5.md +107 -0
- package/docs/guides/use-cases.md +7 -11
- package/docs/guides/web-editor.md +7 -11
- package/docs/reference/commands.md +4 -3
- package/docs/reference/configuration.md +18 -17
- package/docs/reference/features.md +34 -79
- package/docs/reference/macros-and-slots.md +70 -49
- package/docs/reference/public-api.md +64 -17
- package/docs/reference/stack-schema.md +14 -9
- package/docs/reference/subagent-host-port.md +49 -0
- package/docs/zh-CN/README.md +3 -3
- package/docs/zh-CN/concepts/agent-profiles.md +4 -2
- package/docs/zh-CN/concepts/prompt-stacks.md +9 -7
- package/docs/zh-CN/getting-started.md +10 -7
- package/docs/zh-CN/guides/delegation.md +11 -13
- package/docs/zh-CN/guides/migrating-to-0.5.md +92 -0
- package/docs/zh-CN/guides/web-editor.md +7 -7
- package/docs/zh-CN/reference/commands.md +6 -3
- package/examples/custom-system-status-extension/README.md +3 -3
- package/examples/custom-system-status-extension/index.ts +2 -1
- package/examples/custom-system-status-extension/prompt-stack.json +4 -3
- package/examples/default-prompt-stack.json +9 -4
- package/examples/image-reader-prompt-stack.json +16 -26
- package/examples/reviewer-prompt-stack.json +13 -24
- package/package.json +101 -120
- package/dist/runtime/subagent-runtime.d.ts +0 -45
- package/dist/runtime/subagent-runtime.d.ts.map +0 -1
- package/dist/runtime/subagent-runtime.js +0 -335
- package/dist/runtime/subagent-runtime.js.map +0 -1
- package/dist/runtime-state.d.ts +0 -30
- package/dist/runtime-state.d.ts.map +0 -1
- package/dist/runtime-state.js +0 -17
- package/dist/runtime-state.js.map +0 -1
- package/dist/sillytavern-importer/items.d.ts +0 -3
- package/dist/sillytavern-importer/items.d.ts.map +0 -1
- package/dist/sillytavern-importer/items.js +0 -88
- package/dist/sillytavern-importer/items.js.map +0 -1
- package/dist/sillytavern-importer/macros.d.ts +0 -15
- package/dist/sillytavern-importer/macros.d.ts.map +0 -1
- package/dist/sillytavern-importer/macros.js +0 -141
- package/dist/sillytavern-importer/macros.js.map +0 -1
- package/dist/sillytavern-importer/prompt-order.d.ts +0 -6
- package/dist/sillytavern-importer/prompt-order.d.ts.map +0 -1
- package/dist/sillytavern-importer/prompt-order.js +0 -38
- package/dist/sillytavern-importer/prompt-order.js.map +0 -1
- package/dist/sillytavern-importer/regex.d.ts +0 -3
- package/dist/sillytavern-importer/regex.d.ts.map +0 -1
- package/dist/sillytavern-importer/regex.js +0 -275
- package/dist/sillytavern-importer/regex.js.map +0 -1
- package/dist/sillytavern-importer/report.d.ts +0 -21
- package/dist/sillytavern-importer/report.d.ts.map +0 -1
- package/dist/sillytavern-importer/report.js +0 -166
- package/dist/sillytavern-importer/report.js.map +0 -1
- package/dist/sillytavern-importer/types.d.ts +0 -106
- package/dist/sillytavern-importer/types.d.ts.map +0 -1
- package/dist/sillytavern-importer/types.js +0 -2
- package/dist/sillytavern-importer/types.js.map +0 -1
- package/dist/sillytavern-importer.d.ts +0 -5
- package/dist/sillytavern-importer.d.ts.map +0 -1
- package/dist/sillytavern-importer.js +0 -117
- package/dist/sillytavern-importer.js.map +0 -1
- package/dist/subagent/canonical.d.ts +0 -22
- package/dist/subagent/canonical.d.ts.map +0 -1
- package/dist/subagent/canonical.js +0 -24
- package/dist/subagent/canonical.js.map +0 -1
- package/dist/subagent/context.d.ts +0 -8
- package/dist/subagent/context.d.ts.map +0 -1
- package/dist/subagent/context.js +0 -125
- package/dist/subagent/context.js.map +0 -1
- package/dist/subagent/contract.d.ts +0 -10
- package/dist/subagent/contract.d.ts.map +0 -1
- package/dist/subagent/contract.js +0 -10
- package/dist/subagent/contract.js.map +0 -1
- package/dist/subagent/plan.d.ts +0 -18
- package/dist/subagent/plan.d.ts.map +0 -1
- package/dist/subagent/plan.js +0 -157
- package/dist/subagent/plan.js.map +0 -1
- package/dist/subagent/preflight.d.ts +0 -4
- package/dist/subagent/preflight.d.ts.map +0 -1
- package/dist/subagent/preflight.js +0 -108
- package/dist/subagent/preflight.js.map +0 -1
- package/dist/subagent/request.d.ts +0 -4
- package/dist/subagent/request.d.ts.map +0 -1
- package/dist/subagent/request.js +0 -122
- package/dist/subagent/request.js.map +0 -1
- package/dist/subagent/response.d.ts +0 -8
- package/dist/subagent/response.d.ts.map +0 -1
- package/dist/subagent/response.js +0 -155
- package/dist/subagent/response.js.map +0 -1
- package/dist/subagent/tools.d.ts +0 -4
- package/dist/subagent/tools.d.ts.map +0 -1
- package/dist/subagent/tools.js +0 -42
- package/dist/subagent/tools.js.map +0 -1
- package/dist/subagent/types.d.ts +0 -268
- package/dist/subagent/types.d.ts.map +0 -1
- package/dist/subagent/types.js +0 -3
- package/dist/subagent/types.js.map +0 -1
- package/dist/subagent/validation.d.ts +0 -35
- package/dist/subagent/validation.d.ts.map +0 -1
- package/dist/subagent/validation.js +0 -314
- package/dist/subagent/validation.js.map +0 -1
- package/dist/subagent-command.d.ts +0 -4
- package/dist/subagent-command.d.ts.map +0 -1
- package/dist/subagent-command.js +0 -246
- package/dist/subagent-command.js.map +0 -1
- package/dist/subagent-profile-tool.d.ts +0 -49
- package/dist/subagent-profile-tool.d.ts.map +0 -1
- package/dist/subagent-profile-tool.js +0 -124
- package/dist/subagent-profile-tool.js.map +0 -1
- package/dist/subagent-tool.d.ts +0 -53
- package/dist/subagent-tool.d.ts.map +0 -1
- package/dist/subagent-tool.js +0 -456
- package/dist/subagent-tool.js.map +0 -1
- package/docs/guides/sillytavern-import.md +0 -47
- package/docs/reference/subagent-adapter.md +0 -204
- package/examples/sillytavern-dm-writer-prompt-stack.json +0 -190
package/dist/subagent/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Versioned `/subagent` host port: the minimal Forge DTO host contract.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* the Forge host contracts: profiles, compilation, approval, and reporting.
|
|
4
|
+
* Wire messages, recursive validators, transport, and client/host lifecycle,
|
|
5
|
+
* plus the Forge-owned canonical fingerprint helpers used for host-issued
|
|
6
|
+
* profile snapshots. The main package carries no dependency on
|
|
7
|
+
* `@zihanw/pi-subagent-runtime`; the execution contract (request, preflight,
|
|
8
|
+
* plan, response, context, tool negotiation) lives in the optional
|
|
9
|
+
* `@zihanw/pi-forge-subagents` package, which consumes this port.
|
|
11
10
|
*/
|
|
12
|
-
export
|
|
13
|
-
export {
|
|
11
|
+
export { FORGE_HOST_CHANNEL, FORGE_HOST_PORT_NAMESPACE, FORGE_HOST_PORT_OPERATIONS, FORGE_HOST_PORT_VERSION, ForgeHost, ForgeHostClient, ForgeHostPortError, validateListProfilesRequest, validateListProfilesResponse, validatePrepareRequest, validatePrepareResponse, validateResolveProfileRequest, validateResolveProfileResponse, } from "./host-port.js";
|
|
12
|
+
export { SUBAGENT_FINGERPRINT_PREFIX, canonicalSubagentJson, subagentFingerprint, subagentPromptStackFingerprint, subagentSourceProfileFingerprint, } from "./fingerprints.js";
|
|
14
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/subagent/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/subagent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACN,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAC1B,uBAAuB,EACvB,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,2BAA2B,EAC3B,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,6BAA6B,EAC7B,8BAA8B,GAC9B,MAAM,gBAAgB,CAAC;AA2BxB,OAAO,EACN,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,8BAA8B,EAC9B,gCAAgC,GAEhC,MAAM,mBAAmB,CAAC"}
|
package/dist/subagent-host.d.ts
CHANGED
|
@@ -1,10 +1,61 @@
|
|
|
1
|
-
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
2
1
|
import type { LoadedAgentProfile } from "./agent-profile.ts";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import type { AgentProfile } from "./codecs/agent-profile.ts";
|
|
3
|
+
import { type SubagentFingerprint } from "./subagent/fingerprints.ts";
|
|
4
|
+
import type { ForgeBackendFacts, ForgeBackendTool, ForgePromptAccessFacts } from "./subagent/host-port.ts";
|
|
5
|
+
import type { LoadedPromptStack, PromptResourcePolicy, PromptStack } from "./types.ts";
|
|
6
|
+
/**
|
|
7
|
+
* Host-owned diagnostic shape for delegation resolution and preparation.
|
|
8
|
+
* Structurally compatible with the optional package's contract diagnostics.
|
|
9
|
+
*/
|
|
10
|
+
export interface ForgeDelegationDiagnostic {
|
|
11
|
+
level: "error" | "warning" | "info";
|
|
12
|
+
code: string;
|
|
13
|
+
path?: string;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
export type ForgePromptDependencyKind = "macro" | "slot";
|
|
17
|
+
export interface ForgePromptDependency {
|
|
18
|
+
kind: ForgePromptDependencyKind;
|
|
19
|
+
name: string;
|
|
20
|
+
identity: string;
|
|
21
|
+
source?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Host-owned immutable profile snapshot artifact returned by `resolveProfile`
|
|
25
|
+
* and embedded in `prepare` responses. The optional package validates and
|
|
26
|
+
* binds it into execution plans; the wire schema version is shared with the
|
|
27
|
+
* execution contract by design.
|
|
28
|
+
*/
|
|
29
|
+
export declare const FORGE_PROFILE_SNAPSHOT_VERSION: 1;
|
|
30
|
+
export interface ForgeProfileSnapshot {
|
|
31
|
+
schemaVersion: typeof FORGE_PROFILE_SNAPSHOT_VERSION;
|
|
32
|
+
/** Canonical scoped selector of the resolved profile (`project:<id>` or `global:<id>`). */
|
|
33
|
+
profileId: string;
|
|
34
|
+
profile: AgentProfile;
|
|
35
|
+
/** Canonical scoped selector of the resolved prompt stack, or null. */
|
|
36
|
+
promptStackId: string | null;
|
|
37
|
+
promptStack: PromptStack | null;
|
|
38
|
+
dependencies: ForgePromptDependency[];
|
|
39
|
+
profileFingerprint: SubagentFingerprint;
|
|
40
|
+
promptStackFingerprint: SubagentFingerprint | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Host-compiled delegation message. Text-only on the host side; the optional
|
|
44
|
+
* package projects these onto the runtime's portable prepared messages.
|
|
45
|
+
*/
|
|
46
|
+
export interface ForgeDelegationMessage {
|
|
47
|
+
role: "user" | "assistant" | "custom";
|
|
48
|
+
content: Array<{
|
|
49
|
+
type: "text";
|
|
50
|
+
text: string;
|
|
51
|
+
}>;
|
|
52
|
+
protectedTask?: boolean;
|
|
53
|
+
source?: "prompt-stack" | "delegated-task";
|
|
54
|
+
}
|
|
5
55
|
export interface SubagentPromptRegistration {
|
|
6
56
|
name: string;
|
|
7
57
|
source?: string;
|
|
58
|
+
dependencies?: string[];
|
|
8
59
|
}
|
|
9
60
|
export interface SubagentPromptRegistrationCatalog {
|
|
10
61
|
macros: SubagentPromptRegistration[];
|
|
@@ -12,33 +63,63 @@ export interface SubagentPromptRegistrationCatalog {
|
|
|
12
63
|
}
|
|
13
64
|
export interface SubagentHostResolution {
|
|
14
65
|
profileId: string;
|
|
15
|
-
snapshot?:
|
|
16
|
-
dependencies:
|
|
66
|
+
snapshot?: ForgeProfileSnapshot;
|
|
67
|
+
dependencies: ForgePromptDependency[];
|
|
17
68
|
missingDependencies: Array<{
|
|
18
|
-
kind:
|
|
69
|
+
kind: ForgePromptDependencyKind;
|
|
19
70
|
name: string;
|
|
20
71
|
}>;
|
|
21
|
-
diagnostics:
|
|
72
|
+
diagnostics: ForgeDelegationDiagnostic[];
|
|
73
|
+
}
|
|
74
|
+
export interface ForgeDelegationPreparationInput {
|
|
75
|
+
snapshot: ForgeProfileSnapshot;
|
|
76
|
+
task: {
|
|
77
|
+
text: string;
|
|
78
|
+
};
|
|
79
|
+
access: ForgePromptAccessFacts;
|
|
80
|
+
backend: ForgeBackendFacts;
|
|
81
|
+
cwd: string;
|
|
82
|
+
}
|
|
83
|
+
export interface ForgeDelegationPreparation {
|
|
84
|
+
systemPrompt: string;
|
|
85
|
+
messages: ForgeDelegationMessage[];
|
|
86
|
+
effectiveToolIds: string[];
|
|
87
|
+
effectiveToolNames: string[];
|
|
88
|
+
diagnostics: ForgeDelegationDiagnostic[];
|
|
89
|
+
preparedAt: string;
|
|
22
90
|
}
|
|
23
91
|
export declare function currentSubagentPromptRegistrationCatalog(): SubagentPromptRegistrationCatalog;
|
|
24
92
|
export declare function resolveSubagentHostProfile(loaded: LoadedAgentProfile, resources: {
|
|
25
93
|
promptStacks: readonly LoadedPromptStack[];
|
|
26
94
|
registrations?: SubagentPromptRegistrationCatalog;
|
|
27
95
|
}): SubagentHostResolution;
|
|
28
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Forge-native host-owned preparation: negotiate the client tool catalog
|
|
98
|
+
* against stack policy and access facts, compile the resolved stack through
|
|
99
|
+
* one compilation context, and append the protected delegated task. No
|
|
100
|
+
* execution/runtime material (AgentRequest, preflight, limits, or plan
|
|
101
|
+
* fingerprints) is involved; the optional package owns those.
|
|
102
|
+
*/
|
|
103
|
+
export declare function prepareForgeDelegation(input: ForgeDelegationPreparationInput): ForgeDelegationPreparation;
|
|
104
|
+
interface ForgeToolNegotiation {
|
|
105
|
+
effectiveToolIds: string[];
|
|
106
|
+
effectiveToolNames: string[];
|
|
107
|
+
diagnostics: ForgeDelegationDiagnostic[];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Intersect the client-supplied tool catalog with stack tool policy and the
|
|
111
|
+
* prompt-compilation access facts. Semantics mirror the execution contract's
|
|
112
|
+
* tool negotiation in the optional package, which recomputes them as the
|
|
113
|
+
* plan-creation integrity check.
|
|
114
|
+
*/
|
|
115
|
+
export declare function negotiateForgeDelegationTools(catalog: readonly ForgeBackendTool[], policy: PromptResourcePolicy | undefined, access: ForgePromptAccessFacts): ForgeToolNegotiation;
|
|
29
116
|
export declare function collectSubagentPromptDependencies(stack: PromptStack, registrations?: SubagentPromptRegistrationCatalog): {
|
|
30
|
-
dependencies:
|
|
117
|
+
dependencies: ForgePromptDependency[];
|
|
31
118
|
missingDependencies: Array<{
|
|
32
|
-
kind:
|
|
119
|
+
kind: ForgePromptDependencyKind;
|
|
33
120
|
name: string;
|
|
34
121
|
}>;
|
|
35
|
-
diagnostics:
|
|
36
|
-
};
|
|
37
|
-
export declare function collectMacroCommandNames(text: string): string[];
|
|
38
|
-
export declare function appendProtectedAgentTask(compiledMessages: readonly AgentMessage[], protectedTask: AgentMessage): AgentMessage[];
|
|
39
|
-
export declare function compileProtectedAgentTaskMessages(stack: LoadedPromptStack, runtime: PromptRuntime, originalMessages: readonly AgentMessage[]): {
|
|
40
|
-
messages: AgentMessage[];
|
|
41
|
-
diagnostics: import("./types.ts").PromptStackDiagnostic[];
|
|
122
|
+
diagnostics: ForgeDelegationDiagnostic[];
|
|
42
123
|
};
|
|
43
|
-
export
|
|
124
|
+
export {};
|
|
44
125
|
//# sourceMappingURL=subagent-host.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-host.d.ts","sourceRoot":"","sources":["../src/subagent-host.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"subagent-host.d.ts","sourceRoot":"","sources":["../src/subagent-host.ts"],"names":[],"mappings":"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"}
|
package/dist/subagent-host.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { getRegisteredMacros, } from "./macro-engine.js";
|
|
2
2
|
import { getRegisteredSlots, } from "./slot-renderers.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
import { PromptCompilationContext } from "./compiler.js";
|
|
4
|
+
import { applyResourcePolicy, resourcePatternMatches } from "./policy.js";
|
|
5
|
+
import { subagentPromptStackFingerprint, subagentSourceProfileFingerprint, } from "./subagent/fingerprints.js";
|
|
6
|
+
import { formatResourceKey, parseResourceSelector } from "./resource-identity.js";
|
|
7
|
+
import { analyzePromptStack } from "./prompt-analysis.js";
|
|
8
|
+
/**
|
|
9
|
+
* Host-owned immutable profile snapshot artifact returned by `resolveProfile`
|
|
10
|
+
* and embedded in `prepare` responses. The optional package validates and
|
|
11
|
+
* binds it into execution plans; the wire schema version is shared with the
|
|
12
|
+
* execution contract by design.
|
|
13
|
+
*/
|
|
14
|
+
export const FORGE_PROFILE_SNAPSHOT_VERSION = 1;
|
|
11
15
|
const BUILT_IN_SLOTS = new Set([
|
|
12
16
|
"chat-history", "tools", "tool-guidelines", "skills", "project-context", "append-system-prompt",
|
|
13
|
-
"date", "cwd", "date-cwd", "active-model", "pi-docs",
|
|
17
|
+
"date", "cwd", "date-cwd", "active-model", "pi-docs",
|
|
14
18
|
]);
|
|
15
19
|
export function currentSubagentPromptRegistrationCatalog() {
|
|
16
20
|
return {
|
|
@@ -27,31 +31,54 @@ export function resolveSubagentHostProfile(loaded, resources) {
|
|
|
27
31
|
}));
|
|
28
32
|
const registrations = resources.registrations ?? currentSubagentPromptRegistrationCatalog();
|
|
29
33
|
let promptStack;
|
|
34
|
+
let promptStackId = null;
|
|
30
35
|
if (loaded.profile.promptStack !== null) {
|
|
31
|
-
const
|
|
32
|
-
|
|
36
|
+
const reference = loaded.profile.promptStack;
|
|
37
|
+
const parsed = parseResourceSelector(reference);
|
|
38
|
+
if (!parsed.ok) {
|
|
39
|
+
diagnostics.push({
|
|
40
|
+
level: "error",
|
|
41
|
+
code: "profile.stack-reference",
|
|
42
|
+
path: "profile.promptStack",
|
|
43
|
+
message: parsed.error,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else if (loaded.scope === "global" && parsed.selector.scope === "project") {
|
|
33
47
|
diagnostics.push({
|
|
34
48
|
level: "error",
|
|
35
|
-
code:
|
|
49
|
+
code: "profile.stack-reference",
|
|
36
50
|
path: "profile.promptStack",
|
|
37
|
-
message:
|
|
38
|
-
? `Unknown prompt stack: ${loaded.profile.promptStack}`
|
|
39
|
-
: `Prompt stack id is ambiguous: ${loaded.profile.promptStack}`,
|
|
51
|
+
message: `Global profile ${loaded.profile.id} cannot reference project prompt stack ${parsed.selector.id}.`,
|
|
40
52
|
});
|
|
41
53
|
}
|
|
42
54
|
else {
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
const scope = parsed.selector.scope ?? loaded.scope;
|
|
56
|
+
const matches = resources.promptStacks.filter((candidate) => candidate.scope === scope && candidate.stack.id === parsed.selector.id);
|
|
57
|
+
if (matches.length !== 1) {
|
|
45
58
|
diagnostics.push({
|
|
46
|
-
level:
|
|
47
|
-
code: "profile.stack-
|
|
48
|
-
path:
|
|
49
|
-
message:
|
|
59
|
+
level: "error",
|
|
60
|
+
code: matches.length === 0 ? "profile.stack-missing" : "profile.stack-ambiguous",
|
|
61
|
+
path: "profile.promptStack",
|
|
62
|
+
message: matches.length === 0
|
|
63
|
+
? `Unknown prompt stack: ${reference}`
|
|
64
|
+
: `Prompt stack id is ambiguous: ${reference}`,
|
|
50
65
|
});
|
|
51
66
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
67
|
+
else {
|
|
68
|
+
promptStack = matches[0];
|
|
69
|
+
promptStackId = formatResourceKey({ scope, id: parsed.selector.id });
|
|
70
|
+
for (const diagnostic of promptStack.diagnostics) {
|
|
71
|
+
diagnostics.push({
|
|
72
|
+
level: diagnostic.level,
|
|
73
|
+
code: "profile.stack-validation",
|
|
74
|
+
path: diagnostic.itemId ? `promptStack.items.${diagnostic.itemId}` : "promptStack",
|
|
75
|
+
message: diagnostic.message,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (!promptStack.stack.mode || !["replace", "append", "prepend"].includes(promptStack.stack.mode)) {
|
|
79
|
+
if (promptStack.stack.mode !== undefined)
|
|
80
|
+
diagnostics.push({ level: "error", code: "profile.stack-mode", path: "promptStack.mode", message: `Unsupported prompt stack mode: ${String(promptStack.stack.mode)}` });
|
|
81
|
+
}
|
|
55
82
|
}
|
|
56
83
|
}
|
|
57
84
|
}
|
|
@@ -60,15 +87,17 @@ export function resolveSubagentHostProfile(loaded, resources) {
|
|
|
60
87
|
: { dependencies: [], missingDependencies: [], diagnostics: [] };
|
|
61
88
|
diagnostics.push(...dependencyResult.diagnostics);
|
|
62
89
|
const resolution = {
|
|
63
|
-
profileId: loaded.
|
|
90
|
+
profileId: formatResourceKey(loaded.key),
|
|
64
91
|
dependencies: dependencyResult.dependencies,
|
|
65
92
|
missingDependencies: dependencyResult.missingDependencies,
|
|
66
93
|
diagnostics,
|
|
67
94
|
};
|
|
68
95
|
if (!diagnostics.some((diagnostic) => diagnostic.level === "error")) {
|
|
69
96
|
resolution.snapshot = {
|
|
70
|
-
schemaVersion:
|
|
97
|
+
schemaVersion: FORGE_PROFILE_SNAPSHOT_VERSION,
|
|
98
|
+
profileId: formatResourceKey(loaded.key),
|
|
71
99
|
profile: structuredClone(loaded.profile),
|
|
100
|
+
promptStackId,
|
|
72
101
|
promptStack: promptStack ? structuredClone(promptStack.stack) : null,
|
|
73
102
|
dependencies: structuredClone(dependencyResult.dependencies),
|
|
74
103
|
profileFingerprint: subagentSourceProfileFingerprint(loaded.profile),
|
|
@@ -77,107 +106,171 @@ export function resolveSubagentHostProfile(loaded, resources) {
|
|
|
77
106
|
}
|
|
78
107
|
return resolution;
|
|
79
108
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
skills: structuredClone(input.runtime.options.skills),
|
|
91
|
-
contextFiles: [...input.runtime.options.contextFiles],
|
|
92
|
-
};
|
|
93
|
-
const model = {
|
|
94
|
-
provider: input.runtime.model.provider,
|
|
95
|
-
id: input.runtime.model.id,
|
|
96
|
-
api: "unknown",
|
|
97
|
-
};
|
|
109
|
+
/**
|
|
110
|
+
* Forge-native host-owned preparation: negotiate the client tool catalog
|
|
111
|
+
* against stack policy and access facts, compile the resolved stack through
|
|
112
|
+
* one compilation context, and append the protected delegated task. No
|
|
113
|
+
* execution/runtime material (AgentRequest, preflight, limits, or plan
|
|
114
|
+
* fingerprints) is involved; the optional package owns those.
|
|
115
|
+
*/
|
|
116
|
+
export function prepareForgeDelegation(input) {
|
|
117
|
+
const negotiation = negotiateForgeDelegationTools(input.backend.toolCatalog, input.snapshot.promptStack?.tools, input.access);
|
|
118
|
+
const preparedAt = new Date().toISOString();
|
|
98
119
|
const runtime = {
|
|
99
|
-
options
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
options: {
|
|
121
|
+
cwd: input.cwd,
|
|
122
|
+
selectedTools: negotiation.effectiveToolNames,
|
|
123
|
+
toolSnippets: {},
|
|
124
|
+
promptGuidelines: [],
|
|
125
|
+
contextFiles: [],
|
|
126
|
+
skills: [],
|
|
127
|
+
},
|
|
128
|
+
model: {
|
|
129
|
+
provider: input.backend.model.provider,
|
|
130
|
+
id: input.backend.model.id,
|
|
131
|
+
api: "unknown",
|
|
132
|
+
},
|
|
133
|
+
latestUserMessage: input.task.text,
|
|
134
|
+
now: new Date(preparedAt),
|
|
104
135
|
};
|
|
105
|
-
|
|
136
|
+
const diagnostics = [...negotiation.diagnostics];
|
|
137
|
+
let systemPrompt = "";
|
|
106
138
|
let stackMessages = [];
|
|
107
|
-
const
|
|
108
|
-
if (
|
|
109
|
-
const
|
|
139
|
+
const stack = input.snapshot.promptStack;
|
|
140
|
+
if (stack) {
|
|
141
|
+
const compilation = new PromptCompilationContext(stack, runtime);
|
|
142
|
+
const system = compilation.compileSystemPrompt("");
|
|
110
143
|
systemPrompt = system.systemPrompt;
|
|
111
144
|
diagnostics.push(...system.diagnostics.map((item) => promptDiagnostic("system", item)));
|
|
112
|
-
const messages = compileMessages(
|
|
145
|
+
const messages = compilation.compileMessages([]);
|
|
113
146
|
stackMessages = messages.messages.map(preparedPromptStackMessage);
|
|
114
147
|
diagnostics.push(...messages.diagnostics.map((item) => promptDiagnostic("messages", item)));
|
|
115
148
|
}
|
|
116
|
-
const initial = prepareSubagentInitialMessages(input.request, stackMessages);
|
|
117
149
|
return {
|
|
118
150
|
systemPrompt,
|
|
119
|
-
messages:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
diagnostics
|
|
151
|
+
messages: appendProtectedDelegationTask(stackMessages, input.task),
|
|
152
|
+
effectiveToolIds: negotiation.effectiveToolIds,
|
|
153
|
+
effectiveToolNames: negotiation.effectiveToolNames,
|
|
154
|
+
diagnostics,
|
|
155
|
+
preparedAt,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Intersect the client-supplied tool catalog with stack tool policy and the
|
|
160
|
+
* prompt-compilation access facts. Semantics mirror the execution contract's
|
|
161
|
+
* tool negotiation in the optional package, which recomputes them as the
|
|
162
|
+
* plan-creation integrity check.
|
|
163
|
+
*/
|
|
164
|
+
export function negotiateForgeDelegationTools(catalog, policy, access) {
|
|
165
|
+
const diagnostics = [];
|
|
166
|
+
const tools = catalog.map((tool) => ({
|
|
167
|
+
id: tool.id,
|
|
168
|
+
name: tool.name ?? tool.id,
|
|
169
|
+
effects: [...(tool.effects ?? [])],
|
|
170
|
+
}));
|
|
171
|
+
const names = tools.map((tool) => tool.name);
|
|
172
|
+
const stackSelectedToolNames = applyResourcePolicy(names, policy);
|
|
173
|
+
const selected = new Set(stackSelectedToolNames);
|
|
174
|
+
const effective = tools.filter((tool) => selected.has(tool.name) && toolAllowedByAccess(tool, access));
|
|
175
|
+
const unmatchedAllowPatterns = policy && "allow" in policy
|
|
176
|
+
? (policy.allow ?? []).filter((pattern) => pattern !== "*" && !names.some((name) => resourcePatternMatches(name, pattern)))
|
|
177
|
+
: [];
|
|
178
|
+
for (const pattern of unmatchedAllowPatterns) {
|
|
179
|
+
diagnostics.push({ level: "warning", code: "tools.unmatched-allow", path: "tools.allow", message: `Tool allow pattern matches no backend tools: ${pattern}` });
|
|
180
|
+
}
|
|
181
|
+
for (const tool of tools) {
|
|
182
|
+
if (selected.has(tool.name) && !effective.includes(tool)) {
|
|
183
|
+
diagnostics.push({ level: "info", code: "tools.access-filtered", path: `tools.${tool.name}`, message: `Tool ${tool.name} was removed by request access policy.` });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
effectiveToolIds: effective.map((tool) => tool.id),
|
|
188
|
+
effectiveToolNames: effective.map((tool) => tool.name),
|
|
189
|
+
diagnostics,
|
|
123
190
|
};
|
|
124
191
|
}
|
|
192
|
+
function toolAllowedByAccess(tool, access) {
|
|
193
|
+
for (const effect of tool.effects) {
|
|
194
|
+
if (effect === "network" && access.network !== "allow")
|
|
195
|
+
return false;
|
|
196
|
+
if (effect === "process" && access.allowProcess !== true)
|
|
197
|
+
return false;
|
|
198
|
+
if (effect === "filesystem-read" && access.level === "none")
|
|
199
|
+
return false;
|
|
200
|
+
if (effect === "filesystem-write" && access.level !== "workspace-write")
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
125
205
|
export function collectSubagentPromptDependencies(stack, registrations = currentSubagentPromptRegistrationCatalog()) {
|
|
126
206
|
const diagnostics = [];
|
|
127
207
|
const dependencies = new Map();
|
|
128
208
|
const missing = new Map();
|
|
129
209
|
const macroCatalog = new Map(registrations.macros.map((entry) => [entry.name, entry]));
|
|
130
210
|
const slotCatalog = new Map(registrations.slots.map((entry) => [entry.name, entry]));
|
|
131
|
-
const
|
|
211
|
+
const parameters = new Set([
|
|
212
|
+
...Object.keys(stack.parameters ?? {}),
|
|
213
|
+
...Object.keys(stack.variables ?? {}),
|
|
214
|
+
]);
|
|
215
|
+
const analysis = analyzePromptStack(stack, registrations);
|
|
216
|
+
for (const error of analysis.diagnostics) {
|
|
217
|
+
diagnostics.push({
|
|
218
|
+
level: "error",
|
|
219
|
+
code: "prompt-stack.template-analyze",
|
|
220
|
+
path: "promptStack",
|
|
221
|
+
message: error.message,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
132
224
|
for (const item of stack.items) {
|
|
133
225
|
if (item.kind === "slot") {
|
|
134
226
|
if (BUILT_IN_SLOTS.has(item.slot))
|
|
135
227
|
continue;
|
|
136
228
|
addDependency("slot", item.slot, slotCatalog, dependencies, missing, diagnostics, `promptStack.items.${item.id}`);
|
|
137
|
-
continue;
|
|
138
229
|
}
|
|
139
|
-
|
|
140
|
-
|
|
230
|
+
}
|
|
231
|
+
for (const block of analysis.blocks) {
|
|
232
|
+
for (const dependency of block.dependencies) {
|
|
233
|
+
let name;
|
|
234
|
+
if (dependency.kind === "extensions")
|
|
235
|
+
name = dependency.path?.[1];
|
|
236
|
+
if (dependency.kind === "legacy") {
|
|
237
|
+
const candidate = dependency.path?.[0];
|
|
238
|
+
if (!candidate || parameters.has(candidate) || LEGACY_BUILTIN_RUNTIME.has(candidate))
|
|
239
|
+
continue;
|
|
240
|
+
name = candidate;
|
|
241
|
+
}
|
|
242
|
+
if (!name)
|
|
141
243
|
continue;
|
|
142
|
-
addDependency("macro", name, macroCatalog, dependencies, missing, diagnostics, `promptStack.items.${
|
|
244
|
+
addDependency("macro", name, macroCatalog, dependencies, missing, diagnostics, `promptStack.items.${block.itemId}`);
|
|
143
245
|
}
|
|
144
246
|
}
|
|
247
|
+
for (const name of analysis.transitiveExtensions) {
|
|
248
|
+
if (!name || macroCatalog.has(name))
|
|
249
|
+
continue;
|
|
250
|
+
addDependency("macro", name, macroCatalog, dependencies, missing, diagnostics, "promptStack");
|
|
251
|
+
}
|
|
145
252
|
return {
|
|
146
253
|
dependencies: [...dependencies.values()].sort(compareDependencies),
|
|
147
254
|
missingDependencies: [...missing.values()].sort(compareDependencies),
|
|
148
255
|
diagnostics,
|
|
149
256
|
};
|
|
150
257
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
throw new Error("Delegated context contains no final user task.");
|
|
165
|
-
const protectedTask = structuredClone(originalMessages[taskIndex]);
|
|
166
|
-
const history = originalMessages.filter((_message, index) => index !== taskIndex);
|
|
167
|
-
const compiled = compileMessages(stack.stack, runtime, history);
|
|
168
|
-
return { messages: appendProtectedAgentTask(compiled.messages, protectedTask), diagnostics: compiled.diagnostics };
|
|
169
|
-
}
|
|
170
|
-
export function isProtectedAgentTaskPreserved(messages, task) {
|
|
171
|
-
if (!messages.length || task.role !== "user")
|
|
172
|
-
return false;
|
|
173
|
-
const finalMessage = messages.at(-1);
|
|
174
|
-
if (finalMessage?.role !== "user")
|
|
175
|
-
return false;
|
|
176
|
-
return normalizeUserContent(finalMessage.content)
|
|
177
|
-
=== normalizeUserContent(task.content);
|
|
258
|
+
const LEGACY_BUILTIN_RUNTIME = new Set([
|
|
259
|
+
"cwd", "date", "time", "lastUserMessage", "selectedTools", "tools", "activeModel",
|
|
260
|
+
]);
|
|
261
|
+
function appendProtectedDelegationTask(messages, task) {
|
|
262
|
+
return [
|
|
263
|
+
...structuredClone(messages),
|
|
264
|
+
{
|
|
265
|
+
role: "user",
|
|
266
|
+
content: [{ type: "text", text: task.text }],
|
|
267
|
+
protectedTask: true,
|
|
268
|
+
source: "delegated-task",
|
|
269
|
+
},
|
|
270
|
+
];
|
|
178
271
|
}
|
|
179
272
|
function registrationEntry(definition) {
|
|
180
|
-
return { name: definition.name, source: definition.source };
|
|
273
|
+
return { name: definition.name, source: definition.source, dependencies: definition.dependencies };
|
|
181
274
|
}
|
|
182
275
|
function addDependency(kind, name, catalog, dependencies, missing, diagnostics, path) {
|
|
183
276
|
const key = `${kind}:${name}`;
|
|
@@ -192,76 +285,6 @@ function addDependency(kind, name, catalog, dependencies, missing, diagnostics,
|
|
|
192
285
|
if (!registration.source)
|
|
193
286
|
diagnostics.push({ level: "warning", code: "profile.dependency-anonymous", path, message: `Custom ${kind} ${name} has no stable source identity.` });
|
|
194
287
|
}
|
|
195
|
-
function collectMacroCommandsInto(text, names) {
|
|
196
|
-
let index = 0;
|
|
197
|
-
while (index < text.length) {
|
|
198
|
-
const start = text.indexOf("{{", index);
|
|
199
|
-
if (start === -1)
|
|
200
|
-
return;
|
|
201
|
-
const end = findMacroEnd(text, start + 2);
|
|
202
|
-
if (end === undefined)
|
|
203
|
-
return;
|
|
204
|
-
const expression = text.slice(start + 2, end).trim();
|
|
205
|
-
const parts = splitMacroExpression(expression);
|
|
206
|
-
const command = parts[0]?.trim();
|
|
207
|
-
if (command && /^[A-Za-z][A-Za-z0-9_.-]*$/.test(command))
|
|
208
|
-
names.add(command);
|
|
209
|
-
for (const argument of parts.slice(1))
|
|
210
|
-
collectMacroCommandsInto(argument, names);
|
|
211
|
-
index = end + 2;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
function findMacroEnd(text, start) {
|
|
215
|
-
let depth = 1;
|
|
216
|
-
for (let index = start; index < text.length - 1; index++) {
|
|
217
|
-
const pair = text.slice(index, index + 2);
|
|
218
|
-
if (pair === "{{") {
|
|
219
|
-
depth++;
|
|
220
|
-
index++;
|
|
221
|
-
}
|
|
222
|
-
else if (pair === "}}") {
|
|
223
|
-
depth--;
|
|
224
|
-
if (depth === 0)
|
|
225
|
-
return index;
|
|
226
|
-
index++;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return undefined;
|
|
230
|
-
}
|
|
231
|
-
function splitMacroExpression(expression) {
|
|
232
|
-
const parts = [];
|
|
233
|
-
let start = 0;
|
|
234
|
-
let depth = 0;
|
|
235
|
-
for (let index = 0; index < expression.length - 1; index++) {
|
|
236
|
-
const pair = expression.slice(index, index + 2);
|
|
237
|
-
if (pair === "{{") {
|
|
238
|
-
depth++;
|
|
239
|
-
index++;
|
|
240
|
-
}
|
|
241
|
-
else if (pair === "}}" && depth > 0) {
|
|
242
|
-
depth--;
|
|
243
|
-
index++;
|
|
244
|
-
}
|
|
245
|
-
else if (pair === "::" && depth === 0) {
|
|
246
|
-
parts.push(expression.slice(start, index));
|
|
247
|
-
start = index + 2;
|
|
248
|
-
index++;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
parts.push(expression.slice(start));
|
|
252
|
-
return parts;
|
|
253
|
-
}
|
|
254
|
-
function findLastUserMessageIndex(messages) {
|
|
255
|
-
for (let index = messages.length - 1; index >= 0; index--) {
|
|
256
|
-
if (messages[index]?.role === "user")
|
|
257
|
-
return index;
|
|
258
|
-
}
|
|
259
|
-
return -1;
|
|
260
|
-
}
|
|
261
|
-
function normalizeUserContent(content) {
|
|
262
|
-
const normalized = typeof content === "string" ? [{ type: "text", text: content }] : Array.isArray(content) ? content : [content];
|
|
263
|
-
return JSON.stringify(normalized);
|
|
264
|
-
}
|
|
265
288
|
function preparedPromptStackMessage(message) {
|
|
266
289
|
if (message.role !== "user" && message.role !== "assistant" && message.role !== "custom") {
|
|
267
290
|
throw new Error(`Unsupported prompt-stack message role for subagent preparation: ${message.role}`);
|