@piagent/platform 1.6.0 → 1.6.1
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 -0
- package/README.md +17 -14
- package/README.vi.md +26 -1
- package/benchmarks/production-v1/spend-control.v1.json +27 -3
- package/benchmarks/production-v1/suite.json +5 -1
- package/catalog/capabilities.json +16 -16
- package/docs/authority-manifest.md +1 -1
- package/docs/auto-delegation-policy.md +38 -73
- package/docs/command-reference-vietnamese.md +23 -31
- package/docs/context-engine.md +5 -3
- package/docs/context-window-policy.md +37 -1
- package/docs/distribution-standard.md +7 -7
- package/docs/en/architecture.md +26 -13
- package/docs/languages.json +4 -4
- package/docs/operator-manual-vietnamese.md +21 -41
- package/docs/publishing-for-teams.md +5 -0
- package/docs/quality-benchmark.md +179 -23
- package/docs/release-install-policy.md +6 -6
- package/docs/runtime-harness-standard.md +3 -3
- package/docs/security-threat-model.md +1 -1
- package/docs/subagent-orchestration-capabilities.md +19 -51
- package/docs/subagents-and-multiagent.md +21 -47
- package/docs/task-implementation-contract.md +3 -3
- package/docs/task-lifecycle-vietnamese.md +1 -1
- package/docs/team-onboarding.md +2 -2
- package/docs/vi/architecture.md +26 -13
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +89 -95
- package/docs-site/commands.html +1 -1
- package/docs-site/content/benchmark.html +88 -94
- package/docs-site/content/en/benchmark.html +134 -90
- package/docs-site/content/en/index.html +19 -19
- package/docs-site/content/en/runtime.html +4 -4
- package/docs-site/content/en/whats-new.html +12 -1
- package/docs-site/content/en/workflows.html +2 -2
- package/docs-site/content/index.html +19 -19
- package/docs-site/content/runtime.html +4 -4
- package/docs-site/content/whats-new.html +12 -1
- package/docs-site/content/workflows.html +2 -2
- package/docs-site/context-engine.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +135 -91
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/index.html +20 -20
- package/docs-site/en/mcp-approval.html +1 -1
- package/docs-site/en/mcp-auth.html +1 -1
- package/docs-site/en/mcp-servers.html +1 -1
- package/docs-site/en/mcp.html +1 -1
- package/docs-site/en/permissions.html +1 -1
- package/docs-site/en/profiles.html +1 -1
- package/docs-site/en/quickstart.html +1 -1
- package/docs-site/en/runtime.html +5 -5
- package/docs-site/en/scope.html +1 -1
- package/docs-site/en/security.html +1 -1
- package/docs-site/en/team.html +1 -1
- package/docs-site/en/whats-new.html +13 -2
- package/docs-site/en/workflows.html +3 -3
- package/docs-site/index.html +20 -20
- package/docs-site/mcp-approval.html +1 -1
- package/docs-site/mcp-auth.html +1 -1
- package/docs-site/mcp-servers.html +1 -1
- package/docs-site/mcp.html +1 -1
- package/docs-site/permissions.html +1 -1
- package/docs-site/profiles.html +1 -1
- package/docs-site/quickstart.html +1 -1
- package/docs-site/runtime.html +5 -5
- package/docs-site/scope.html +1 -1
- package/docs-site/security.html +1 -1
- package/docs-site/team.html +1 -1
- package/docs-site/whats-new.html +13 -2
- package/docs-site/workflows.html +3 -3
- package/evals/fixtures/benchmark-assurance-evidence.invalid.json +1 -1
- package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
- package/evals/fixtures/codex-relative-efficiency-v1.invalid.json +4 -0
- package/evals/fixtures/codex-relative-efficiency-v1.valid.json +94 -0
- package/evals/fixtures/helper-request.invalid.json +1 -1
- package/evals/fixtures/helper-request.valid.json +1 -1
- package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +7 -0
- package/evals/fixtures/task-authority-snapshot.valid.json +4 -4
- package/evals/fs4-readiness-matrix.v1.json +2 -2
- package/evals/fs5-causal-arm.v1.json +2 -2
- package/evals/fs5-pilot-protocol.v1.json +3 -3
- package/evals/fs5-pilot-protocol.v2.json +8 -8
- package/evals/fs5-pilot-protocol.v3.json +8 -8
- package/evals/fs5-pilot-protocol.v4.json +6 -6
- package/evals/fs5-pilot-protocol.v5.json +7 -6
- package/evals/private-holdout-v1/public-exposure.v1.json +1 -1
- package/evals/runtime-conformance-v1/README.md +43 -0
- package/evals/runtime-conformance-v1/evaluate-paid-canary.mjs +198 -0
- package/evals/runtime-conformance-v1/lane.json +57 -0
- package/evals/runtime-conformance-v1/paid-canary.json +31 -0
- package/evals/runtime-conformance-v1/runner.mjs +456 -0
- package/package.json +1 -1
- package/packages/piagent-core/README.md +13 -4
- package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +698 -0
- package/packages/piagent-core/benchmark/benchmark-core.js +4 -3
- package/packages/piagent-core/benchmark/benchmark-forensics.js +4 -2
- package/packages/piagent-core/benchmark/benchmark-preflight.js +3 -1
- package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +345 -0
- package/packages/piagent-core/benchmark/benchmark-record-validation.js +74 -5
- package/packages/piagent-core/benchmark/benchmark-report.js +15 -1
- package/packages/piagent-core/benchmark/benchmark-runtime-causal.js +244 -0
- package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +201 -4
- package/packages/piagent-core/benchmark/benchmark-suite.js +22 -1
- package/packages/piagent-core/benchmark/benchmark-summary-support.js +4 -0
- package/packages/piagent-core/benchmark/benchmark-usage.js +15 -4
- package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
- package/packages/piagent-core/extensions/acceptance-behavior-proof.js +806 -0
- package/packages/piagent-core/extensions/acceptance-receipt.js +89 -48
- package/packages/piagent-core/extensions/context-engine.js +1 -11
- package/packages/piagent-core/extensions/context-index-policy.js +4 -0
- package/packages/piagent-core/extensions/context-query-paths.js +57 -0
- package/packages/piagent-core/extensions/criterion-context-pack.js +16 -3
- package/packages/piagent-core/extensions/criterion-graph.js +4 -1
- package/packages/piagent-core/extensions/fallback-base-policy.ts +101 -0
- package/packages/piagent-core/extensions/guard-types.ts +4 -0
- package/packages/piagent-core/extensions/piagent-guard.ts +194 -226
- package/packages/piagent-core/extensions/task-lifecycle.js +32 -0
- package/packages/piagent-core/extensions/task-state.js +69 -8
- package/packages/piagent-core/extensions/verification-intelligence.js +49 -12
- package/packages/piagent-core/extensions/workspace-evidence-roots.js +52 -16
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/policies/base-policy.json +42 -2
- package/packages/piagent-core/policy/authority-manifest.v1.json +3 -3
- package/packages/piagent-core/prompts/be-to-fe.md +2 -8
- package/packages/piagent-core/prompts/plan.md +1 -1
- package/packages/piagent-core/prompts/platform-improve.md +2 -6
- package/packages/piagent-core/prompts/review.md +2 -7
- package/packages/piagent-core/prompts/scout.md +1 -1
- package/packages/piagent-core/prompts/task.md +4 -3
- package/packages/piagent-core/runtime/hooks/completion-hook.ts +7 -6
- package/packages/piagent-core/runtime/hooks/input-hook.ts +6 -0
- package/packages/piagent-core/runtime/hooks/session-start-hook.ts +100 -1
- package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +58 -72
- package/packages/piagent-core/runtime/hooks/tool-result-value-helpers.ts +66 -0
- package/packages/piagent-core/runtime/inspection/bounded-emission-guard.ts +286 -0
- package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +37 -7
- package/packages/piagent-core/runtime/inspection/task-subagent-tree.ts +27 -4
- package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +20 -3
- package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +47 -11
- package/packages/piagent-core/runtime/orchestration/helper-lifecycle.ts +16 -12
- package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +71 -0
- package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +28 -20
- package/packages/piagent-core/runtime/orchestration/role-policy.ts +27 -9
- package/packages/piagent-core/runtime/orchestration/subagent-tool-policy.ts +329 -0
- package/packages/piagent-core/runtime/policy/block-remedy.ts +0 -4
- package/packages/piagent-core/runtime/product/efficiency-metrics.ts +3 -0
- package/packages/piagent-core/runtime/quality/edit-freshness-guard.ts +102 -0
- package/packages/piagent-core/runtime/quality/exact-output-contract.ts +20 -10
- package/packages/piagent-core/runtime/quality/performance-assurance.ts +3 -3
- package/packages/piagent-core/runtime/recovery/continuation-budget.ts +1 -1
- package/packages/piagent-core/runtime/recovery/handoff-projection.ts +4 -1
- package/packages/piagent-core/runtime/recovery/pristine-task-policy-refresh.ts +91 -0
- package/packages/piagent-core/runtime/recovery/recovery-policy.ts +7 -4
- package/packages/piagent-core/runtime/recovery/resume-state.ts +112 -14
- package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +7 -13
- package/packages/piagent-core/runtime/recovery/task-evidence-coverage-refresh.ts +217 -0
- package/packages/piagent-core/runtime/registration/context-commands.ts +16 -2
- package/packages/piagent-core/runtime/registration/knowledge-tools.ts +9 -5
- package/packages/piagent-core/runtime/registration/operator-request-intake.ts +49 -0
- package/packages/piagent-core/runtime/registration/policy-tools.ts +4 -4
- package/packages/piagent-core/runtime/registration/session-commands.ts +1 -1
- package/packages/piagent-core/runtime/registration/task-completion-tools.ts +12 -9
- package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +21 -12
- package/packages/piagent-core/runtime/registration/task-start-guidance.ts +19 -13
- package/packages/piagent-core/runtime/registration/task-start-manifest.ts +54 -0
- package/packages/piagent-core/runtime/registration/task-start-tool.ts +57 -57
- package/packages/piagent-core/runtime/runtime-limits.ts +16 -2
- package/packages/piagent-core/runtime/session/adaptive-context-analysis.ts +461 -0
- package/packages/piagent-core/runtime/session/adaptive-context-governor.ts +464 -0
- package/packages/piagent-core/runtime/session/adaptive-context-ledger.ts +265 -0
- package/packages/piagent-core/runtime/session/message-signals.ts +7 -3
- package/packages/piagent-core/runtime/session/operator-request-carry.ts +44 -0
- package/packages/piagent-core/runtime/session/runtime-state.ts +11 -7
- package/packages/piagent-core/runtime/session/source-checkout-read-grants.ts +35 -0
- package/packages/piagent-core/runtime/session/system-prompt.ts +76 -14
- package/packages/piagent-core/runtime/session/task-contract-presentation.ts +39 -0
- package/packages/piagent-core/runtime/tools/phase-tools.ts +8 -8
- package/packages/piagent-core/runtime/tools/tool-groups.ts +12 -2
- package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +101 -0
- package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +164 -0
- package/packages/piagent-core/runtime/workflows/task-intake.ts +167 -39
- package/packages/piagent-core/subagents/piagent-oracle.md +5 -3
- package/packages/piagent-core/subagents/piagent-planner.md +6 -4
- package/packages/piagent-core/subagents/piagent-reviewer.md +5 -3
- package/packages/piagent-core/subagents/piagent-scout.md +4 -2
- package/packages/piagent-core/subagents/piagent-worker.md +6 -4
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-CxeZqTte.js → MarkdownMessage-B4XehTCU.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-DynIMe8I.js → index-CgOEyRPG.js} +4 -4
- package/packages/piagent-webui/dist/client/index.html +1 -1
- package/packages/piagent-webui/extension/piagent-webui.ts +3 -1
- package/packages/piagent-webui/extension/same-session-bridge.ts +1 -1
- package/packages/piagent-webui/extension/session-stream-adapter.ts +33 -10
- package/packages/piagent-webui/gateway/gateway-session-stream.ts +37 -21
- package/packages/piagent-webui/gateway/session-operation-lifecycle.ts +237 -0
- package/packages/piagent-webui/gateway/session-operation-retry-control.ts +38 -0
- package/packages/piagent-webui/gateway/session-operation-watchdog.ts +9 -2
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +8 -7
- package/packages/piagent-webui/ownership/session-lease-store.ts +5 -2
- package/packages/piagent-webui/server/core-inspection-provider.ts +2 -1
- package/packages/piagent-webui/server/transcript-projection.ts +91 -5
- package/schemas/codex-relative-efficiency-v1.schema.json +155 -0
- package/schemas/piagent-webui/runtime-event-v2.schema.json +15 -5
- package/schemas/piagent-webui/subagent-tree-v1.schema.json +11 -1
- package/schemas/project-profile.schema.json +1 -1
- package/schemas/task-contract.schema.json +15 -0
- package/scripts/benchmark-runner-core.mjs +14 -6
- package/scripts/benchmark-runner-finalization.mjs +4 -0
- package/scripts/configure-subagents.sh +42 -34
- package/scripts/helper-evaluation.mjs +1 -1
- package/scripts/team-doctor.sh +1 -1
- package/scripts/verify-local.sh +5 -0
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { exactFinalOutputGuidance } from "../quality/exact-output-contract.ts";
|
|
3
|
-
import { taskPerformanceAssurance } from "../quality/performance-assurance.ts";
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { exactFinalOutputGuidance } from "../quality/exact-output-contract.ts"; import { taskPerformanceAssurance } from "../quality/performance-assurance.ts";
|
|
4
2
|
import { automaticTaskSummary, boundedRuntimeIntakeMessage } from "../workflows/task-intake.ts";
|
|
5
3
|
import { WORKING_TREE_DIGEST_ALGORITHM } from "../../extensions/working-tree-digest.js";
|
|
4
|
+
import { TASK_ACCEPTANCE_CRITERIA_MAX, TASK_ACCEPTANCE_CRITERION_MAX_CHARS, TASK_EXPECTED_OUTPUT_MAX_CHARS, TASK_SUMMARY_MAX_CHARS, operatorRequestDigest } from "../../extensions/task-state.js";
|
|
6
5
|
import { createEnvironmentBoundTaskAuthority } from "../policy/task-authority-runtime.ts";
|
|
7
6
|
import { authorityReplacementState } from "../policy/authority-resume-policy.ts";
|
|
8
7
|
import { compileCriterionGraph, criterionGraphContextSelection, criterionGraphContextSelectionDetails, criterionGraphGuidance, criterionGraphMode } from "../../extensions/criterion-graph.js";
|
|
9
8
|
import { captureTaskStartBaseline } from "../inspection/task-baseline-start-capture.ts";
|
|
10
|
-
import { sameStringRecord, satisfiesAuthorityReplacement } from "./task-start-retry-helpers.ts";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
taskCriticalProofSection
|
|
14
|
-
} from "./task-start-guidance.ts";
|
|
15
|
-
type ExtensionContext = any; type TaskContract = any; type TaskStartParameters = any;
|
|
9
|
+
import { sameStringRecord, satisfiesAuthorityReplacement } from "./task-start-retry-helpers.ts"; import { automaticTaskExecutionGuidance, EXACT_VERIFIER_EXECUTION_GUIDANCE, RUNTIME_SOURCE_REUSE_GUIDANCE, taskCriticalProofSection } from "./task-start-guidance.ts";
|
|
10
|
+
import { resolveTaskStartRepositoryManifestProvider } from "./task-start-manifest.ts"; import { boundedOperatorRequest, latestOperatorRequest } from "./operator-request-intake.ts";
|
|
11
|
+
type ExtensionContext = any; type TaskContract = any; type TaskStartParameters = Record<string, any> & { operatorRequest?: string }; function taskReferenceDetails(task: TaskContract, reasonCode: string): Record<string, unknown> { const scope = Array.isArray(task.scope) ? task.scope.slice(0, 50) : []; return { reasonCode, taskId: task.taskId, taskRunId: task.taskRunId, outcome: task.trace?.outcome, attempt: task.attempt, ...(reasonCode === "task-already-active" ? { scope, scopeTruncated: scope.length < task.scope.length } : {}) }; }
|
|
16
12
|
export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any>): any {
|
|
17
13
|
const {
|
|
18
14
|
DEFAULT_MAX_TASK_ATTEMPTS, ORCHESTRATION_ROLES, REVIEW_LENSES, StringEnum, Type,
|
|
@@ -22,10 +18,11 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
22
18
|
currentSessionName, defaultWorkPlan, effectiveProtectedPaths, hasGitEvidenceRoot, hasOperatorSessionName,
|
|
23
19
|
isAcceptanceTestPath, loadProfileFromContext, matchesProtectedPath, normalizeReviewLenses, normalizeWorkPlanSteps, nowIso, policy,
|
|
24
20
|
priorTaskAttempts, recordTaskStartCheckpoint, redactText, redactTextArray, registerRuntimeTool,
|
|
25
|
-
repositoryFileManifest,
|
|
21
|
+
repositoryFileManifest, resolveOrchestrationPolicy, resolveTaskScopePatterns, runtimeLifecycleMode, runtimeState, safeTaskId, selectVerificationPlan,
|
|
26
22
|
summarizeAttempt, telemetry, validTaskScopePattern, validateNewWorkPlan, verifierCommandInstructions, workingTreeEvidenceDigest, workingTreeSnapshot, workingTreeSnapshotHasUnavailableEvidence,
|
|
27
23
|
writeTask
|
|
28
24
|
} = deps;
|
|
25
|
+
const repositoryManifestProvider = resolveTaskStartRepositoryManifestProvider(deps);
|
|
29
26
|
const taskStartTool = {
|
|
30
27
|
name: "piagent_task_start",
|
|
31
28
|
label: "Piagent Task Start",
|
|
@@ -36,24 +33,24 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
36
33
|
"Use source-change for project verifier execution or edits. For an assessment, report, or plan with no source changes, set mutationPolicy=forbidden; use read-only when no project verifier needs to execute.",
|
|
37
34
|
"Do not call context, status, policy, evidence-recording, trace, or gate tools first; runtime hooks provide those checks automatically.",
|
|
38
35
|
"Use tiny for a bounded low-risk change, normal for ordinary multi-file work, and high-risk for security, data, release, migration, or external-impact work.",
|
|
39
|
-
"Every scope entry must be a project-relative path or glob such as src/file.ts, src/**, or test/**;
|
|
36
|
+
"Every scope entry is an initial retrieval/review focus and must be a project-relative path or glob such as src/file.ts, src/**, or test/**; it is not a source-mutation boundary.",
|
|
40
37
|
"Leave workPlan unset for ordinary tiny/normal tasks so runtime automation stays active; pass a custom workPlan only when the operator explicitly requests custom subagent or checkpoint orchestration.",
|
|
41
38
|
"Tiny tasks use automatic lifecycle evidence; normal tasks retain one explicit review step; high-risk/custom plans keep manual checkpoints."
|
|
42
39
|
],
|
|
43
40
|
parameters: Type.Object({
|
|
44
41
|
taskId: Type.Optional(Type.String({ minLength: 1 })),
|
|
45
|
-
summary: Type.String({ minLength: 10 }),
|
|
42
|
+
summary: Type.String({ minLength: 10, maxLength: TASK_SUMMARY_MAX_CHARS }),
|
|
46
43
|
riskLane: StringEnum(["tiny", "normal", "high-risk"] as const),
|
|
47
44
|
changeMode: Type.Optional(StringEnum(["source-change", "read-only"] as const, {
|
|
48
45
|
description: "Use source-change for project verifier execution or edits; use read-only for bounded inspection."
|
|
49
46
|
})),
|
|
50
47
|
mutationPolicy: Type.Optional(StringEnum(["required", "forbidden"] as const, { description: "Required demands a final diff; forbidden allows exact verification, rejects source mutation, and requires a zero task delta." })),
|
|
51
48
|
maxAttempts: Type.Optional(Type.Number({ minimum: 1, maximum: 10 })),
|
|
52
|
-
expectedOutput: Type.String({ minLength: 10 }),
|
|
53
|
-
acceptanceCriteria: Type.Array(Type.String({ minLength: 1 }), { minItems: 1, maxItems:
|
|
49
|
+
expectedOutput: Type.String({ minLength: 10, maxLength: TASK_EXPECTED_OUTPUT_MAX_CHARS }),
|
|
50
|
+
acceptanceCriteria: Type.Array(Type.String({ minLength: 1, maxLength: TASK_ACCEPTANCE_CRITERION_MAX_CHARS }), { minItems: 1, maxItems: TASK_ACCEPTANCE_CRITERIA_MAX }),
|
|
54
51
|
scope: Type.Array(Type.String({
|
|
55
52
|
minLength: 1,
|
|
56
|
-
description: "
|
|
53
|
+
description: "Advisory retrieval/review focus as a project-relative path or glob (for example src/file.ts, src/**, or test/**); source changes may follow repository evidence beyond it."
|
|
57
54
|
}), { minItems: 1, maxItems: 2000 }),
|
|
58
55
|
outOfScope: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),
|
|
59
56
|
reviewLenses: Type.Optional(Type.Array(StringEnum(REVIEW_LENSES))),
|
|
@@ -74,12 +71,13 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
74
71
|
_onUpdate: ((update: unknown) => void) | undefined,
|
|
75
72
|
ctx: ExtensionContext
|
|
76
73
|
) {
|
|
77
|
-
const profile = loadProfileFromContext(ctx);
|
|
78
|
-
const
|
|
79
|
-
|
|
74
|
+
const profile = loadProfileFromContext(ctx), createdAt = nowIso();
|
|
75
|
+
const operatorRequest = typeof params.operatorRequest === "string"
|
|
76
|
+
? params.operatorRequest
|
|
77
|
+
: latestOperatorRequest(ctx);
|
|
78
|
+
const safeSummary = redactText(params.summary), safeOperatorRequest = boundedOperatorRequest(operatorRequest, redactText);
|
|
80
79
|
const taskId = safeTaskId(redactText(params.taskId ?? params.summary));
|
|
81
|
-
const sessionId = ctx.sessionManager.getSessionId();
|
|
82
|
-
const sessionName = currentSessionName(ctx);
|
|
80
|
+
const sessionId = ctx.sessionManager.getSessionId(), sessionName = currentSessionName(ctx);
|
|
83
81
|
const active = activeSessionTask(ctx.cwd, sessionId) as TaskContract | undefined;
|
|
84
82
|
if (active && active.trace.outcome !== "pending" && runtimeState.taskIdentity(ctx)?.taskRunId === active.taskRunId) {
|
|
85
83
|
runtimeState.clearTaskBoundary(ctx, active.taskRunId);
|
|
@@ -135,12 +133,12 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
135
133
|
}
|
|
136
134
|
return {
|
|
137
135
|
content: [{ type: "text", text: `Task already active in this session: ${active.taskId} (${active.taskRunId}). Reusing it instead of overwriting state.` }],
|
|
138
|
-
details:
|
|
136
|
+
details: taskReferenceDetails(active, "task-already-active")
|
|
139
137
|
};
|
|
140
138
|
}
|
|
141
139
|
return {
|
|
142
140
|
content: [{ type: "text", text: `Session already has pending task ${active.taskId} (${active.taskRunId}). Complete or stop it before starting another task in this conversation.` }],
|
|
143
|
-
details: active,
|
|
141
|
+
details: taskReferenceDetails(active, "session-task-already-pending"),
|
|
144
142
|
isError: true
|
|
145
143
|
};
|
|
146
144
|
}
|
|
@@ -155,24 +153,15 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
155
153
|
};
|
|
156
154
|
}
|
|
157
155
|
const scopeResolution = resolveTaskScopePatterns(params.scope, repositoryFileManifest(ctx.cwd));
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
if (scopeResolution.unmatched.length > 0) {
|
|
169
|
-
return {
|
|
170
|
-
content: [{ type: "text", text: `Task start refused: scope entries do not identify an existing repository path (${scopeResolution.unmatched.join(", ")}). Use an exact project-relative path for a new file, such as src/name.ts, instead of a basename or guessed top-level alias.` }],
|
|
171
|
-
details: scopeResolution,
|
|
172
|
-
isError: true
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
const resolvedScope = scopeResolution.scope;
|
|
156
|
+
// Scope guides context selection and review; it is not filesystem
|
|
157
|
+
// authority. Keep unresolved focus entries instead of preventing work in
|
|
158
|
+
// a parent workspace where several child repositories share names such
|
|
159
|
+
// as src/, app/, tests/, or package.json.
|
|
160
|
+
const unresolvedFocus = [
|
|
161
|
+
...scopeResolution.ambiguous.map((item) => item.input),
|
|
162
|
+
...scopeResolution.unmatched
|
|
163
|
+
];
|
|
164
|
+
const resolvedScope = [...new Set([...scopeResolution.scope, ...unresolvedFocus])];
|
|
176
165
|
const priorAttempts = priorTaskAttempts(ctx.cwd, taskId) as TaskContract[];
|
|
177
166
|
const authorityStates = new Map(priorAttempts.map((task) => [task.taskRunId, authorityReplacementState(ctx.cwd, task)]));
|
|
178
167
|
const unsafeAuthorityState = [...authorityStates.entries()].find(([, state]) => !state.enforcementSafe);
|
|
@@ -189,7 +178,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
189
178
|
if (pendingElsewhere) {
|
|
190
179
|
return {
|
|
191
180
|
content: [{ type: "text", text: `Task ${taskId} is already active in session ${pendingElsewhere.sessionName ?? pendingElsewhere.sessionId} (${pendingElsewhere.taskRunId}).` }],
|
|
192
|
-
details: pendingElsewhere,
|
|
181
|
+
details: taskReferenceDetails(pendingElsewhere, "task-active-in-another-session"),
|
|
193
182
|
isError: true
|
|
194
183
|
};
|
|
195
184
|
}
|
|
@@ -197,7 +186,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
197
186
|
if (latestCompleted) {
|
|
198
187
|
return {
|
|
199
188
|
content: [{ type: "text", text: `Task ${taskId} already completed as ${latestCompleted.taskRunId}. Use a distinct taskId for new work instead of replacing its evidence.` }],
|
|
200
|
-
details: latestCompleted,
|
|
189
|
+
details: taskReferenceDetails(latestCompleted, "task-already-completed"),
|
|
201
190
|
isError: true
|
|
202
191
|
};
|
|
203
192
|
}
|
|
@@ -260,11 +249,11 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
260
249
|
const workPlan = providedWorkPlan.length ? providedWorkPlan : defaultWorkPlan(safeSummary, defaultPlanLane, changeMode, mutationPolicy);
|
|
261
250
|
const workPlanError = validateNewWorkPlan(workPlan);
|
|
262
251
|
if (workPlanError) {
|
|
263
|
-
return { content: [{ type: "text", text: `Task start refused: ${workPlanError}.` }], details:
|
|
252
|
+
return { content: [{ type: "text", text: `Task start refused: ${workPlanError}.` }], details: { reasonCode: "invalid-work-plan" }, isError: true };
|
|
264
253
|
}
|
|
265
254
|
const firstReady = workPlan.find((step) => (step.dependsOn ?? []).length === 0);
|
|
266
255
|
if (!firstReady) {
|
|
267
|
-
return { content: [{ type: "text", text: "Task start refused: work plan has no dependency-ready first step." }], details:
|
|
256
|
+
return { content: [{ type: "text", text: "Task start refused: work plan has no dependency-ready first step." }], details: { reasonCode: "work-plan-has-no-ready-step" }, isError: true };
|
|
268
257
|
}
|
|
269
258
|
firstReady.status = "in-progress";
|
|
270
259
|
firstReady.updatedAt = createdAt;
|
|
@@ -287,12 +276,15 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
287
276
|
expectedOutput: redactText(params.expectedOutput),
|
|
288
277
|
acceptanceCriteria: redactTextArray(params.acceptanceCriteria),
|
|
289
278
|
changeMode,
|
|
279
|
+
mutationPolicy,
|
|
280
|
+
outOfScope: redactTextArray(params.outOfScope),
|
|
281
|
+
protectedPaths: profile.protectedPaths ?? [],
|
|
290
282
|
source: params.intakeMode === "runtime" ? "runtime" : "model",
|
|
291
283
|
generatedAt: createdAt
|
|
292
284
|
});
|
|
293
285
|
const criterionGraph = compileCriterionGraph({ acceptanceCriteria: acceptance.acceptanceCriteria, scope: resolvedScope,
|
|
294
286
|
verifyCommands: verifyPlan.commands, changeMode, mode: criterionGraphMode(), createdAt });
|
|
295
|
-
const projectManifest =
|
|
287
|
+
const projectManifest = repositoryManifestProvider.read(ctx.cwd), projectFiles = projectManifest.files;
|
|
296
288
|
const maxManifestFiles = contextBudgetConfig(policy).maxManifestFiles;
|
|
297
289
|
const plannedSelection = criterionGraphContextSelectionDetails(criterionGraph, projectFiles, [], maxManifestFiles, projectManifest.complete, resolvedScope);
|
|
298
290
|
const plannedContext = plannedSelection.entries;
|
|
@@ -309,6 +301,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
309
301
|
maxAttempts,
|
|
310
302
|
previousAttempts: priorAttempts.filter((task) => task.trace.outcome !== "pending").slice(0, 10).reverse().map(summarizeAttempt),
|
|
311
303
|
summary: safeSummary,
|
|
304
|
+
...(safeOperatorRequest ? { operatorRequest: safeOperatorRequest, operatorRequestDigest: operatorRequestDigest(safeOperatorRequest) } : {}),
|
|
312
305
|
riskLane: params.riskLane,
|
|
313
306
|
intakeMode: params.intakeMode === "runtime" ? "runtime" : "model",
|
|
314
307
|
expectedOutput: redactText(params.expectedOutput),
|
|
@@ -331,7 +324,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
331
324
|
orchestration: {
|
|
332
325
|
mode: orchestration.defaultMode,
|
|
333
326
|
subagents: "not-used",
|
|
334
|
-
reason: "
|
|
327
|
+
reason: "Parent works directly by default. One fresh read-only helper is eligible only with two independent lanes and at least 30% projected net token savings; workers and retries are disabled.",
|
|
335
328
|
fieldGuidePath: orchestration.fieldGuide.enabled ? orchestration.fieldGuide.path : undefined,
|
|
336
329
|
modelRoles: orchestration.roleModelGuidance
|
|
337
330
|
},
|
|
@@ -355,11 +348,11 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
355
348
|
? acceptanceBaselineGuidance(written, { cwd: ctx.cwd })
|
|
356
349
|
: [];
|
|
357
350
|
const exactOutputGuidance = mutationPolicy === "forbidden"
|
|
358
|
-
? exactFinalOutputGuidance(written
|
|
351
|
+
? exactFinalOutputGuidance(written)
|
|
359
352
|
: [];
|
|
360
353
|
const criticalProof = taskCriticalProofSection(
|
|
361
|
-
written, plannedContext, projectFiles, acceptanceProofGuidance, isAcceptanceTestPath, acceptanceLanguageAdapterForPath
|
|
362
|
-
|
|
354
|
+
written, plannedContext, projectFiles, acceptanceProofGuidance, isAcceptanceTestPath, acceptanceLanguageAdapterForPath,
|
|
355
|
+
taskPerformanceAssurance(written).requiresReview);
|
|
363
356
|
bindSessionTask(ctx.cwd, sessionId, sessionName, written);
|
|
364
357
|
runtimeState.cacheTaskIdentity(ctx, written);
|
|
365
358
|
if (written.intakeMode !== "runtime") {
|
|
@@ -370,8 +363,8 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
370
363
|
}
|
|
371
364
|
const lifecycleMode = runtimeLifecycleMode(written);
|
|
372
365
|
const scopeMappings = scopeResolution.mappings.map((item) => `${item.from} -> ${item.to}`);
|
|
373
|
-
appendTrace(ctx.cwd, { taskId, taskRunId, sessionId, sessionName, attempt, event: "task_start", turnId: runtimeState.currentTurn(ctx)?.turnId, summary: task.summary, riskLane: params.riskLane, intakeMode: task.intakeMode, changeMode: task.changeMode, mutationPolicy: task.mutationPolicy, lifecycleMode, criterionGraphMode: written.criterionGraph.mode, criterionGraphDigest: written.criterionGraph.graphDigest, authorityProfile: written.authoritySnapshot.profile, authoritySnapshotDigest: written.authoritySnapshot.snapshotDigest, scopeMappings, plannedContext: plannedContext.map((item) => item.path), plannedContextComplete: plannedSelection.complete, plannedContextCandidateCount: plannedSelection.candidateCount, observedContext: observedContext.map((item) => item.path) });
|
|
374
|
-
appendSessionTrace(pi, { taskId, taskRunId, sessionId, sessionName, attempt, event: "task_start", turnId: runtimeState.currentTurn(ctx)?.turnId, summary: task.summary, riskLane: params.riskLane, intakeMode: task.intakeMode, changeMode: task.changeMode, mutationPolicy: task.mutationPolicy, lifecycleMode, criterionGraphMode: written.criterionGraph.mode, criterionGraphDigest: written.criterionGraph.graphDigest, authorityProfile: written.authoritySnapshot.profile, authoritySnapshotDigest: written.authoritySnapshot.snapshotDigest, scopeMappings, plannedContext: plannedContext.map((item) => item.path), plannedContextComplete: plannedSelection.complete, plannedContextCandidateCount: plannedSelection.candidateCount, observedContext: observedContext.map((item) => item.path) });
|
|
366
|
+
appendTrace(ctx.cwd, { taskId, taskRunId, sessionId, sessionName, attempt, event: "task_start", turnId: runtimeState.currentTurn(ctx)?.turnId, summary: task.summary, riskLane: params.riskLane, intakeMode: task.intakeMode, changeMode: task.changeMode, mutationPolicy: task.mutationPolicy, lifecycleMode, criterionGraphMode: written.criterionGraph.mode, criterionGraphDigest: written.criterionGraph.graphDigest, authorityProfile: written.authoritySnapshot.profile, authoritySnapshotDigest: written.authoritySnapshot.snapshotDigest, scopeMappings, plannedContext: plannedContext.map((item) => item.path), plannedContextComplete: plannedSelection.complete, plannedContextCandidateCount: plannedSelection.candidateCount, repositoryManifestProvider: projectManifest.provider, repositoryManifestCompatibilityReason: projectManifest.compatibilityReason, observedContext: observedContext.map((item) => item.path) });
|
|
367
|
+
appendSessionTrace(pi, { taskId, taskRunId, sessionId, sessionName, attempt, event: "task_start", turnId: runtimeState.currentTurn(ctx)?.turnId, summary: task.summary, riskLane: params.riskLane, intakeMode: task.intakeMode, changeMode: task.changeMode, mutationPolicy: task.mutationPolicy, lifecycleMode, criterionGraphMode: written.criterionGraph.mode, criterionGraphDigest: written.criterionGraph.graphDigest, authorityProfile: written.authoritySnapshot.profile, authoritySnapshotDigest: written.authoritySnapshot.snapshotDigest, scopeMappings, plannedContext: plannedContext.map((item) => item.path), plannedContextComplete: plannedSelection.complete, plannedContextCandidateCount: plannedSelection.candidateCount, repositoryManifestProvider: projectManifest.provider, repositoryManifestCompatibilityReason: projectManifest.compatibilityReason, observedContext: observedContext.map((item) => item.path) });
|
|
375
368
|
telemetry(ctx, { event: "turn_task_bound", turnId: runtimeState.currentTurn(ctx)?.turnId, taskRunId });
|
|
376
369
|
recordTaskStartCheckpoint(ctx, written, firstReady.id, lifecycleMode);
|
|
377
370
|
return {
|
|
@@ -379,7 +372,13 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
379
372
|
type: "text",
|
|
380
373
|
text: [
|
|
381
374
|
`Task ${taskId} started (${params.riskLane}, ${lifecycleMode}; attempt ${attempt}/${maxAttempts}).`,
|
|
382
|
-
...(scopeMappings.length > 0 ? [`
|
|
375
|
+
...(scopeMappings.length > 0 ? [`Initial focus mapping: ${scopeMappings.join("; ")}.`] : []),
|
|
376
|
+
...(scopeResolution.ambiguous.length > 0
|
|
377
|
+
? [`Ambiguous focus retained as advisory: ${scopeResolution.ambiguous.map((item) => item.input).join(", ")}.`]
|
|
378
|
+
: []),
|
|
379
|
+
...(scopeResolution.unmatched.length > 0
|
|
380
|
+
? [`Unmatched focus retained for discovery or new files: ${scopeResolution.unmatched.join(", ")}.`]
|
|
381
|
+
: []),
|
|
383
382
|
written.verifyCommands.length > 0
|
|
384
383
|
? ["Exact verifier commands:", ...verifierCommandInstructions(written.verifyCommands)].join("\n")
|
|
385
384
|
: "Verify: none (read-only).",
|
|
@@ -423,7 +422,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
423
422
|
if (active?.trace.outcome === "pending") return undefined;
|
|
424
423
|
const summary = redactText(automaticTaskSummary(prompt));
|
|
425
424
|
const sessionName = currentSessionName(ctx);
|
|
426
|
-
const projectManifest =
|
|
425
|
+
const projectManifest = repositoryManifestProvider.read(ctx.cwd), projectFiles = projectManifest.files;
|
|
427
426
|
const scope = intakeMode === "read-only"
|
|
428
427
|
? automaticReadOnlyTaskScope(prompt, runtimeState.preTaskContext(ctx))
|
|
429
428
|
: automaticTaskScope(prompt, runtimeState.preTaskContext(ctx), projectFiles);
|
|
@@ -431,7 +430,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
431
430
|
`runtime-intake-${ctx.sessionManager.getSessionId()}`,
|
|
432
431
|
{
|
|
433
432
|
taskId: active && active.trace.outcome !== "pending" ? summary : hasOperatorSessionName(sessionName) ? sessionName : summary,
|
|
434
|
-
summary,
|
|
433
|
+
summary, operatorRequest: prompt,
|
|
435
434
|
riskLane: automaticTaskRiskLane(prompt),
|
|
436
435
|
intakeMode: "runtime",
|
|
437
436
|
changeMode: intakeMode,
|
|
@@ -469,9 +468,10 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
469
468
|
const baselineGuidance = task.changeMode === "source-change" && task.mutationPolicy !== "forbidden"
|
|
470
469
|
? acceptanceBaselineGuidance(task, { cwd: ctx.cwd })
|
|
471
470
|
: [];
|
|
472
|
-
const exactOutputGuidance = task.changeMode === "read-only" || task.mutationPolicy === "forbidden" ? exactFinalOutputGuidance(task
|
|
471
|
+
const exactOutputGuidance = task.changeMode === "read-only" || task.mutationPolicy === "forbidden" ? exactFinalOutputGuidance(task) : [];
|
|
473
472
|
const criticalProof = taskCriticalProofSection(
|
|
474
|
-
task, plannedContext, projectFiles, acceptanceProofGuidance, isAcceptanceTestPath, acceptanceLanguageAdapterForPath
|
|
473
|
+
task, plannedContext, projectFiles, acceptanceProofGuidance, isAcceptanceTestPath, acceptanceLanguageAdapterForPath,
|
|
474
|
+
assurance.requiresReview
|
|
475
475
|
);
|
|
476
476
|
return {
|
|
477
477
|
started: true,
|
|
@@ -479,7 +479,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
|
|
|
479
479
|
plannedContext,
|
|
480
480
|
plannedContextComplete: plannedSelection.complete,
|
|
481
481
|
text: boundedRuntimeIntakeMessage([
|
|
482
|
-
`Piagent runtime task: ${task.taskId};
|
|
482
|
+
`Piagent runtime task: ${task.taskId}; initial focus (advisory): ${task.scope.join(", ")}.`,
|
|
483
483
|
"The complete operator request above is the authoritative acceptance contract; runtime keeps its full criteria, so do not restate or re-scout it.",
|
|
484
484
|
`Assurance: ${assurance.tier} (${assurance.reasonCodes.join(", ") || "bounded-runtime"}).`,
|
|
485
485
|
...criticalProof,
|
|
@@ -6,10 +6,24 @@ export const CONTEXT_COMPACT_PERCENT = 70;
|
|
|
6
6
|
export const CONTEXT_FRESH_PERCENT = 82;
|
|
7
7
|
export const LONG_INPUT_CHARS = 8000;
|
|
8
8
|
export const MAX_INLINE_COLLAPSED_TASK_CHARS = 2200;
|
|
9
|
-
export const
|
|
10
|
-
export const
|
|
9
|
+
export const RUNTIME_INTAKE_COMPACT_CHARS = 3_500;
|
|
10
|
+
export const RUNTIME_INTAKE_MESSAGE_MAX_CHARS = 3_500;
|
|
11
|
+
export const SEMANTIC_COMPACTION_MAX_CHARS = 12_000;
|
|
11
12
|
export const CONTEXT_PACK_MAX_TOKENS = 900;
|
|
12
13
|
|
|
14
|
+
// The host's default compaction reserve is primarily an overflow guard. Piagent's
|
|
15
|
+
// governor acts earlier because repeatedly replaying a valid 200k+ context can
|
|
16
|
+
// burn substantially more tokens than the task itself. These are working-set
|
|
17
|
+
// limits, not capability limits: high-value task truth is carried forward while
|
|
18
|
+
// stale tool transcripts remain in the durable session history.
|
|
19
|
+
export const CONTEXT_PROVIDER_PROMPT_CEILING_TOKENS = 240_000;
|
|
20
|
+
export const CONTEXT_GOVERNOR_PRESSURE_TOKENS = 160_000;
|
|
21
|
+
export const CONTEXT_GOVERNOR_TARGET_MESSAGE_TOKENS = 72_000;
|
|
22
|
+
export const CONTEXT_GOVERNOR_RECENT_MESSAGE_TOKENS = 40_000;
|
|
23
|
+
export const CONTEXT_GOVERNOR_SEMANTIC_BOUNDARY_TOKENS = 48_000;
|
|
24
|
+
export const CONTEXT_GOVERNOR_TOOL_ROUND_LIMIT = 24;
|
|
25
|
+
export const CONTEXT_GOVERNOR_LEDGER_MAX_CHARS = 12_000;
|
|
26
|
+
|
|
13
27
|
export const TOOL_RESULT_COMPACT_CHAR_THRESHOLD = 12_000;
|
|
14
28
|
export const TOOL_RESULT_COMPACT_LINE_THRESHOLD = 180;
|
|
15
29
|
export const TOOL_RESULT_PREVIEW_HEAD_LINES = 24;
|