@axiom-lattice/core 4.2.2 → 4.2.3
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/dist/index.js +160 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +161 -53
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -10070,8 +10070,8 @@ var metricsPlugin = {
|
|
|
10070
10070
|
type: "metrics",
|
|
10071
10071
|
category: "data",
|
|
10072
10072
|
capabilityBundleEligible: true,
|
|
10073
|
-
name: "Metrics",
|
|
10074
|
-
description: "
|
|
10073
|
+
name: "Metrics (DEPRECATED)",
|
|
10074
|
+
description: "DEPRECATED \u2014 use the 'semantic-metrics' plugin instead. Legacy metrics querying over the old server contract; kept for backward compatibility with existing agents. New agents should enable 'semantic-metrics' (connection-backed, /api/v1, table-grant scoping, semantic meta publishing).",
|
|
10075
10075
|
tools: [
|
|
10076
10076
|
{ name: "list_datasources", description: "List all datasources from all configured servers" },
|
|
10077
10077
|
{ name: "query_metrics_list", description: "Query available metrics from datasources" },
|
|
@@ -22990,6 +22990,14 @@ Do not update or change a belief without new evidence. Every update cites the
|
|
|
22990
22990
|
observation, states how it supports or contradicts the Claim, and records the
|
|
22991
22991
|
resulting Decision Impact or explains why the plan remains unchanged.
|
|
22992
22992
|
|
|
22993
|
+
An approved scope or criteria change is one reconciliation, not two updates:
|
|
22994
|
+
revise \`## Objective\` / \`## Acceptance Criteria\` and, in the same
|
|
22995
|
+
reconciliation, re-base every affected Belief Key \u2014 its new Basis must cite the
|
|
22996
|
+
user approval \u2014 cancel or replace subtasks that depended on the superseded
|
|
22997
|
+
scope, and revise eval coverage to the revised contract. A downgraded
|
|
22998
|
+
probability after a scope change is an honest reset, not a regression; continue
|
|
22999
|
+
only from the re-based Belief State.
|
|
23000
|
+
|
|
22993
23001
|
The current runtime requires numeric \`beliefImpact.after\` values and the
|
|
22994
23002
|
canonical compatibility table below. Treat \`after\` as the evidence support
|
|
22995
23003
|
percentage for the Claim. It is not an Eval score, Agent quality metric, or Task
|
|
@@ -23051,6 +23059,15 @@ that can change the parent goal, acceptance judgment, or next action. It is not
|
|
|
23051
23059
|
tool call. Reading a skill, running one command, calling SQL, or editing a file is
|
|
23052
23060
|
normally an internal \`write_todos\` step.
|
|
23053
23061
|
|
|
23062
|
+
Persist the plan before executing it. Announcing work in conversation (for
|
|
23063
|
+
example, "I will create three sub-agents") is not a plan: before that work
|
|
23064
|
+
starts, the parent Belief State must already exist and every planned child must
|
|
23065
|
+
be persisted with its contract (\`pending\` until its phase starts,
|
|
23066
|
+
\`in_progress\` when it starts). The persisted decomposition is what the user
|
|
23067
|
+
aligns on \u2014 in normal approval flows, present the decomposition (children,
|
|
23068
|
+
Targets, and belief dimensions) and confirm it before executing it; a deviation
|
|
23069
|
+
from the approved design is a material boundary requiring renewed confirmation.
|
|
23070
|
+
|
|
23054
23071
|
Before creating a subtask, identify: (1) the uncertain parent Belief Key, (2) why
|
|
23055
23072
|
it affects a decision, (3) the observable evidence this subtask will produce, and
|
|
23056
23073
|
(4) the Prediction contract with positive and negative result branches and their
|
|
@@ -24680,6 +24697,9 @@ For a new Orchestra parent \u2014 build the delegation tree before the parent:
|
|
|
24680
24697
|
each sub-agent is a bounded specialist with a clear interface (input/output/responsibility).
|
|
24681
24698
|
A sub-agent qualifies as a sub-agent when it has independent tools, its own skill, or
|
|
24682
24699
|
needs separate eval. Do not create a sub-agent for a simple inline step.
|
|
24700
|
+
Persist the approved delegation tree as planned child tasks with contracts and
|
|
24701
|
+
\`Targets\` before creating any sub-agent ([[task-tracking]]); in normal approval
|
|
24702
|
+
flows the decomposition is presented for user confirmation first.
|
|
24683
24703
|
|
|
24684
24704
|
**2. Build each sub-agent's skill first.** Per sub-agent:
|
|
24685
24705
|
- If domain knowledge exists \u2192 load [[document-learning-learn-capability]]
|
|
@@ -32353,7 +32373,7 @@ function snapshotDate(value) {
|
|
|
32353
32373
|
|
|
32354
32374
|
// src/services/TaskLifecycleService.ts
|
|
32355
32375
|
import { createHash as createHash6 } from "crypto";
|
|
32356
|
-
import { parseTaskBeliefState as parseTaskBeliefState2, snapshotExactArray as snapshotExactArray3, snapshotExactRecord as snapshotExactRecord8, taskBeliefStatesEqual } from "@axiom-lattice/protocols";
|
|
32376
|
+
import { parseTaskBeliefState as parseTaskBeliefState2, replaceTaskBeliefState, snapshotExactArray as snapshotExactArray3, snapshotExactRecord as snapshotExactRecord8, taskBeliefStatesEqual } from "@axiom-lattice/protocols";
|
|
32357
32377
|
|
|
32358
32378
|
// src/middlewares/taskBelief.ts
|
|
32359
32379
|
import { createHash as createHash5 } from "crypto";
|
|
@@ -32450,6 +32470,71 @@ function buildParentBeliefActivity(input) {
|
|
|
32450
32470
|
function failure2(code, error, hint) {
|
|
32451
32471
|
return { success: false, code, error, ...hint === void 0 ? {} : { hint } };
|
|
32452
32472
|
}
|
|
32473
|
+
async function seedBeliefOwnerTable(taskStore, owner, impacts) {
|
|
32474
|
+
if (impacts.length === 0) return { description: owner.description ?? "" };
|
|
32475
|
+
const parsed = parseTaskBeliefState2(owner.description ?? "");
|
|
32476
|
+
if (!parsed.success && parsed.code !== "MISSING_BELIEF_STATE") {
|
|
32477
|
+
return failure2("INVALID_BELIEF_TABLE", parsed.message);
|
|
32478
|
+
}
|
|
32479
|
+
const entries = parsed.success ? [...parsed.state.entries] : [];
|
|
32480
|
+
const known = new Set(entries.map((entry) => entry.key));
|
|
32481
|
+
const missing = impacts.filter((impact) => !known.has(impact.key));
|
|
32482
|
+
if (missing.length === 0) return { description: owner.description ?? "" };
|
|
32483
|
+
for (const impact of missing) {
|
|
32484
|
+
entries.push({ key: impact.key, probability: impact.after, target: impact.after, basis: impact.basis });
|
|
32485
|
+
}
|
|
32486
|
+
const base = owner.description ?? "";
|
|
32487
|
+
const description = replaceTaskBeliefState(base, { entries });
|
|
32488
|
+
const updated = await taskStore.update(owner.tenantId, owner.id, { description });
|
|
32489
|
+
if (!updated) return failure2("TASK_STORE_WRITE_FAILED", "Failed to seed the belief owner's Belief State table.");
|
|
32490
|
+
return { description: updated.description ?? description };
|
|
32491
|
+
}
|
|
32492
|
+
function beliefValidationFailure(validation) {
|
|
32493
|
+
switch (validation.code) {
|
|
32494
|
+
case "MISSING_BELIEF_TABLE":
|
|
32495
|
+
return failure2(
|
|
32496
|
+
validation.code,
|
|
32497
|
+
"The belief owner's description has no '## Belief State' table.",
|
|
32498
|
+
"Initialize a '## Belief State' section in the belief owner task's description via manage_task update, using the canonical four-column table | Belief Key | Probability | Target | Basis |, then retry completion with beliefImpact keys from that table."
|
|
32499
|
+
);
|
|
32500
|
+
case "INVALID_BELIEF_TABLE":
|
|
32501
|
+
return failure2(
|
|
32502
|
+
validation.code,
|
|
32503
|
+
`The belief owner's Belief State table is invalid: ${validation.message}`,
|
|
32504
|
+
"Fix the Belief State table via manage_task update on the belief owner task, then retry completion."
|
|
32505
|
+
);
|
|
32506
|
+
case "INVALID_BELIEF_KEY":
|
|
32507
|
+
return failure2(
|
|
32508
|
+
validation.code,
|
|
32509
|
+
`Belief key '${validation.key}' is not in the belief owner's Belief State table.`,
|
|
32510
|
+
"Add the key to the belief owner's Belief State table via manage_task update, or report an existing key."
|
|
32511
|
+
);
|
|
32512
|
+
case "INVALID_BELIEF_VALUE":
|
|
32513
|
+
return failure2(
|
|
32514
|
+
validation.code,
|
|
32515
|
+
`Belief key '${validation.key}' has an invalid after value.`,
|
|
32516
|
+
"after must be an integer between 0 and 100."
|
|
32517
|
+
);
|
|
32518
|
+
case "INVALID_BELIEF_BASIS":
|
|
32519
|
+
return failure2(
|
|
32520
|
+
validation.code,
|
|
32521
|
+
`Belief key '${validation.key}' has an invalid basis.`,
|
|
32522
|
+
"basis must be a single nonblank line of at most 1000 characters."
|
|
32523
|
+
);
|
|
32524
|
+
case "INVALID_DUPLICATE_BELIEF_KEY":
|
|
32525
|
+
return failure2(
|
|
32526
|
+
validation.code,
|
|
32527
|
+
`Duplicate belief key '${validation.key}'.`,
|
|
32528
|
+
"Report each belief key at most once."
|
|
32529
|
+
);
|
|
32530
|
+
case "MISSING_BELIEF_IMPACT":
|
|
32531
|
+
return failure2(
|
|
32532
|
+
validation.code,
|
|
32533
|
+
"Agent task completion requires beliefImpact.",
|
|
32534
|
+
"Provide beliefImpact: [{ key: '<belief-key>', after: <0-100>, basis: '<evidence>' }]"
|
|
32535
|
+
);
|
|
32536
|
+
}
|
|
32537
|
+
}
|
|
32453
32538
|
function isProjectLifecycleTask(task) {
|
|
32454
32539
|
const source = task.context?.source;
|
|
32455
32540
|
return typeof task.workspaceId === "string" && task.workspaceId.length > 0 && typeof task.projectId === "string" && task.projectId.length > 0 && task.workspaceId !== "default" && task.projectId !== "default" && (source === "project_room" || source === "project_task");
|
|
@@ -32469,15 +32554,10 @@ function unsupportedTaskStatus() {
|
|
|
32469
32554
|
);
|
|
32470
32555
|
}
|
|
32471
32556
|
function requireProjectTaskThread(task, inputThreadId, allowPendingClaim = false) {
|
|
32472
|
-
|
|
32473
|
-
|
|
32474
|
-
|
|
32475
|
-
|
|
32476
|
-
}
|
|
32477
|
-
if (allowPendingClaim && task.status === "pending" && typeof inputThreadId === "string" && inputThreadId.length > 0) {
|
|
32478
|
-
return void 0;
|
|
32479
|
-
}
|
|
32480
|
-
return failure2("PROJECT_TASK_THREAD_REQUIRED", "Project task execution requires its authoritative Task Thread.");
|
|
32557
|
+
void task;
|
|
32558
|
+
void inputThreadId;
|
|
32559
|
+
void allowPendingClaim;
|
|
32560
|
+
return void 0;
|
|
32481
32561
|
}
|
|
32482
32562
|
function detailOf(item) {
|
|
32483
32563
|
const detail = item.detail;
|
|
@@ -33706,7 +33786,11 @@ var TaskLifecycleService = class {
|
|
|
33706
33786
|
if (existing.ownerType !== "agent") return failure2("AGENT_TASK_REQUIRED", "Lifecycle completion only supports agent tasks.");
|
|
33707
33787
|
const threadFailure = requireProjectTaskThread(existing, input.threadId);
|
|
33708
33788
|
if (threadFailure) return threadFailure;
|
|
33709
|
-
if (existing.status !== "in_progress") return failure2(
|
|
33789
|
+
if (existing.status !== "in_progress") return failure2(
|
|
33790
|
+
"TASK_STATUS_CONFLICT",
|
|
33791
|
+
"Task is not in progress.",
|
|
33792
|
+
"Start the task first (status='in_progress'), then complete it with result and beliefImpact."
|
|
33793
|
+
);
|
|
33710
33794
|
if (!review && existing.requireReview === true) {
|
|
33711
33795
|
return failure2("REVIEW_REQUIRED", "Task requires completion evidence review through submitReview.");
|
|
33712
33796
|
}
|
|
@@ -33714,12 +33798,18 @@ var TaskLifecycleService = class {
|
|
|
33714
33798
|
if (!result) return failure2("MISSING_RESULT", "Agent completion requires a nonblank result.");
|
|
33715
33799
|
const parentResult = await this.loadParent(existing);
|
|
33716
33800
|
if (parentResult && "success" in parentResult) return parentResult;
|
|
33801
|
+
const beliefOwnerTask = parentResult?.ownerType === "agent" ? parentResult : existing;
|
|
33802
|
+
if (input.beliefImpact?.length) {
|
|
33803
|
+
const seeded = await seedBeliefOwnerTable(this.deps.taskStore, beliefOwnerTask, input.beliefImpact);
|
|
33804
|
+
if ("code" in seeded) return seeded;
|
|
33805
|
+
beliefOwnerTask.description = seeded.description;
|
|
33806
|
+
}
|
|
33717
33807
|
const validation = validateBeliefImpactForTask({
|
|
33718
33808
|
parent: parentResult ? { ownerType: parentResult.ownerType } : null,
|
|
33719
33809
|
impacts: input.beliefImpact,
|
|
33720
33810
|
ownerDescription: parentResult?.ownerType === "agent" ? parentResult.description : existing.description
|
|
33721
33811
|
});
|
|
33722
|
-
if (!validation.ok) return
|
|
33812
|
+
if (!validation.ok) return beliefValidationFailure(validation);
|
|
33723
33813
|
const beliefOwner = this.beliefOwnerSnapshot(existing, parentResult);
|
|
33724
33814
|
const baseEventKey = eventKeyFor(input.taskId, result, input.beliefImpact, beliefOwner);
|
|
33725
33815
|
let eventKey = baseEventKey;
|
|
@@ -36935,7 +37025,7 @@ var semanticMetricsPlugin = {
|
|
|
36935
37025
|
category: "data",
|
|
36936
37026
|
capabilityBundleEligible: true,
|
|
36937
37027
|
name: "Semantic Metrics",
|
|
36938
|
-
description: "Semantic metrics datasource exploration, meta publishing, and runtime querying",
|
|
37028
|
+
description: "Semantic metrics datasource exploration, meta publishing, and runtime querying. PERMISSION MODEL \u2014 query-only agents (metric definitions + data): enable this middleware with allowedTools ['metrics_runtime_tool']. Metric designers (Builder): keep all three tools (metrics_datasource_tool, metrics_meta_tool, metrics_runtime_tool) for exploration, publishing, and verification, or use the built-in 'semantic-metrics-builder' agent.",
|
|
36939
37029
|
version: "1.0.0",
|
|
36940
37030
|
tools: [
|
|
36941
37031
|
{ name: "metrics_datasource_tool", description: "Explore datasource structure within the tenant's granted scope" },
|
|
@@ -36944,6 +37034,8 @@ var semanticMetricsPlugin = {
|
|
|
36944
37034
|
],
|
|
36945
37035
|
configSchema: {
|
|
36946
37036
|
type: "object",
|
|
37037
|
+
title: "Semantic Metrics Configuration",
|
|
37038
|
+
description: "First select connections (connections or connectAll). Then scope tools by role via allowedTools: QUERY-ONLY agents (metric definitions + data) set allowedTools to ['metrics_runtime_tool'] \u2014 read_semantic_catalog and query_metrics cover both; metric DESIGNERS keep all three tools (datasource exploration, meta publishing, runtime verification).",
|
|
36947
37039
|
properties: {
|
|
36948
37040
|
connections: {
|
|
36949
37041
|
type: "array",
|
|
@@ -39531,6 +39623,15 @@ function createTaskMiddleware(options = {}) {
|
|
|
39531
39623
|
});
|
|
39532
39624
|
}
|
|
39533
39625
|
const title = input.title;
|
|
39626
|
+
let createScopeWorkspaceId = workspaceId;
|
|
39627
|
+
let createScopeProjectId = projectId;
|
|
39628
|
+
if (!trustedProject && !delegatedTaskId && input.parentId && (!createScopeWorkspaceId || !createScopeProjectId)) {
|
|
39629
|
+
const parentTask = await store.getById(tenantId2, input.parentId);
|
|
39630
|
+
if (parentTask) {
|
|
39631
|
+
createScopeWorkspaceId = createScopeWorkspaceId ?? parentTask.workspaceId;
|
|
39632
|
+
createScopeProjectId = createScopeProjectId ?? parentTask.projectId;
|
|
39633
|
+
}
|
|
39634
|
+
}
|
|
39534
39635
|
const effectiveOwnerType = delegatedTaskId ? "agent" : trustedProject ? "agent" : input.ownerType || "user";
|
|
39535
39636
|
const effectiveOwnerId = delegatedTaskId ? rc.assistant_id : ownerId;
|
|
39536
39637
|
if (delegatedTaskId && !effectiveOwnerId) {
|
|
@@ -39605,7 +39706,7 @@ function createTaskMiddleware(options = {}) {
|
|
|
39605
39706
|
store,
|
|
39606
39707
|
tenantId2,
|
|
39607
39708
|
delegatedTaskId,
|
|
39608
|
-
{ workspaceId, projectId },
|
|
39709
|
+
{ workspaceId: createScopeWorkspaceId, projectId: createScopeProjectId },
|
|
39609
39710
|
input.parentId,
|
|
39610
39711
|
input.dependencies
|
|
39611
39712
|
);
|
|
@@ -39614,7 +39715,7 @@ function createTaskMiddleware(options = {}) {
|
|
|
39614
39715
|
const referenceError = await validateReferencedTasks(
|
|
39615
39716
|
store,
|
|
39616
39717
|
tenantId2,
|
|
39617
|
-
{ workspaceId, projectId },
|
|
39718
|
+
{ workspaceId: createScopeWorkspaceId, projectId: createScopeProjectId },
|
|
39618
39719
|
input.parentId,
|
|
39619
39720
|
input.dependencies
|
|
39620
39721
|
);
|
|
@@ -39631,7 +39732,7 @@ function createTaskMiddleware(options = {}) {
|
|
|
39631
39732
|
const dependencyError = await validateEffectiveDependencies(
|
|
39632
39733
|
store,
|
|
39633
39734
|
tenantId2,
|
|
39634
|
-
{ workspaceId, projectId },
|
|
39735
|
+
{ workspaceId: createScopeWorkspaceId, projectId: createScopeProjectId },
|
|
39635
39736
|
input.dependencies
|
|
39636
39737
|
);
|
|
39637
39738
|
if (dependencyError) return dependencyError;
|
|
@@ -39679,8 +39780,8 @@ function createTaskMiddleware(options = {}) {
|
|
|
39679
39780
|
dependencies: input.dependencies,
|
|
39680
39781
|
result: input.result,
|
|
39681
39782
|
failureReason: input.failureReason,
|
|
39682
|
-
workspaceId,
|
|
39683
|
-
projectId,
|
|
39783
|
+
workspaceId: createScopeWorkspaceId,
|
|
39784
|
+
projectId: createScopeProjectId,
|
|
39684
39785
|
files: input.files
|
|
39685
39786
|
});
|
|
39686
39787
|
};
|
|
@@ -39874,7 +39975,7 @@ function createTaskMiddleware(options = {}) {
|
|
|
39874
39975
|
if (delegatedTaskId && input.id !== delegatedTaskId) {
|
|
39875
39976
|
return delegatedTaskScopeError(delegatedTaskId);
|
|
39876
39977
|
}
|
|
39877
|
-
|
|
39978
|
+
let existing = await store.getById(tenantId2, input.id);
|
|
39878
39979
|
if (!existing) {
|
|
39879
39980
|
return JSON.stringify({
|
|
39880
39981
|
success: false,
|
|
@@ -39916,15 +40017,6 @@ function createTaskMiddleware(options = {}) {
|
|
|
39916
40017
|
}
|
|
39917
40018
|
const isAgentTask = existing.ownerType === "agent";
|
|
39918
40019
|
const candidateReviewInterruption = input.status === "interrupted" && input.context?.interruption && typeof input.context.interruption === "object" && input.context.interruption.type === "review_required" && !!input.result?.trim() && !!input.beliefImpact?.length;
|
|
39919
|
-
const trustedLifecycleInterruption = !!trustedProject && input.status === "interrupted" && input.context?.interruption && typeof input.context.interruption === "object";
|
|
39920
|
-
if (isAgentTask && input.context !== void 0 && !candidateReviewInterruption && !trustedLifecycleInterruption) {
|
|
39921
|
-
return JSON.stringify({
|
|
39922
|
-
success: false,
|
|
39923
|
-
code: "TASK_LIFECYCLE_CONTEXT_PROTECTED",
|
|
39924
|
-
error: "Agent task context is owned by the task lifecycle service.",
|
|
39925
|
-
hint: "Use lifecycle status inputs without context; the service preserves thread and interruption audit data."
|
|
39926
|
-
});
|
|
39927
|
-
}
|
|
39928
40020
|
const changesOwnerType = input.ownerType !== void 0 && input.ownerType !== existing.ownerType;
|
|
39929
40021
|
const changesAgentIdentity = isAgentTask && (input.ownerId !== void 0 && input.ownerId !== existing.ownerId || input.parentId !== void 0 && input.parentId !== existing.parentId);
|
|
39930
40022
|
if (changesOwnerType || changesAgentIdentity) {
|
|
@@ -39954,14 +40046,6 @@ function createTaskMiddleware(options = {}) {
|
|
|
39954
40046
|
hint: "Persist ownership or parent changes separately before changing lifecycle or task content."
|
|
39955
40047
|
});
|
|
39956
40048
|
}
|
|
39957
|
-
if (isAgentTask && input.description !== void 0 && input.status !== void 0) {
|
|
39958
|
-
return JSON.stringify({
|
|
39959
|
-
success: false,
|
|
39960
|
-
code: "AGENT_TASK_LIFECYCLE_REQUIRED",
|
|
39961
|
-
error: "Agent description and status updates must be separate operations.",
|
|
39962
|
-
hint: "Reconcile the description first, then issue the lifecycle status update."
|
|
39963
|
-
});
|
|
39964
|
-
}
|
|
39965
40049
|
const actor = trustedActor(trustedProject, rc) ?? (existing.ownerType === "agent" ? `agent:${existing.ownerId}` : `user:${existing.ownerId ?? ownerId}`);
|
|
39966
40050
|
const threadId = trustedProject?.projectTask?.threadId ?? (trustedProject?.projectRoom ? void 0 : input.sourceId ?? rc.thread_id);
|
|
39967
40051
|
const lifecycle = isAgentTask ? createTaskLifecycleService({
|
|
@@ -39972,29 +40056,36 @@ function createTaskMiddleware(options = {}) {
|
|
|
39972
40056
|
if (result.success && result.mutated) markMutation();
|
|
39973
40057
|
return lifecycleResponse(input.id, result, extra);
|
|
39974
40058
|
};
|
|
40059
|
+
const hasCarriedContentFields = () => ["title", "description", "priority", "dueDate", "metadata", "files"].some((key4) => input[key4] !== void 0);
|
|
39975
40060
|
if (lifecycle && input.status === "failed") {
|
|
39976
40061
|
await validateExecutionResult();
|
|
39977
40062
|
const callerError = await revalidateCaller();
|
|
39978
40063
|
if (callerError) return callerError;
|
|
39979
|
-
|
|
40064
|
+
const failed = await lifecycle.failTask({
|
|
39980
40065
|
tenantId: tenantId2,
|
|
39981
40066
|
taskId: input.id,
|
|
39982
40067
|
failureReason: input.failureReason ?? existing.failureReason ?? "",
|
|
39983
40068
|
actor,
|
|
39984
40069
|
threadId
|
|
39985
|
-
})
|
|
40070
|
+
});
|
|
40071
|
+
if (!failed.success) return lifecycleMutationResponse(failed);
|
|
40072
|
+
if (trustedProject || !hasCarriedContentFields()) return lifecycleMutationResponse(failed);
|
|
40073
|
+
existing = { ...existing, status: input.status };
|
|
39986
40074
|
}
|
|
39987
40075
|
if (lifecycle && input.status === "cancelled") {
|
|
39988
40076
|
await validateExecutionResult();
|
|
39989
40077
|
const callerError = await revalidateCaller();
|
|
39990
40078
|
if (callerError) return callerError;
|
|
39991
|
-
|
|
40079
|
+
const cancelled = await lifecycle.cancelTask({
|
|
39992
40080
|
tenantId: tenantId2,
|
|
39993
40081
|
taskId: input.id,
|
|
39994
40082
|
actor,
|
|
39995
40083
|
threadId,
|
|
39996
40084
|
summary: input.summary
|
|
39997
|
-
})
|
|
40085
|
+
});
|
|
40086
|
+
if (!cancelled.success) return lifecycleMutationResponse(cancelled);
|
|
40087
|
+
if (trustedProject || !hasCarriedContentFields()) return lifecycleMutationResponse(cancelled);
|
|
40088
|
+
existing = { ...existing, status: input.status };
|
|
39998
40089
|
}
|
|
39999
40090
|
if (lifecycle && input.status === "interrupted" && !(input.context?.interruption && typeof input.context.interruption === "object" && input.context.interruption.type === "review_required")) {
|
|
40000
40091
|
const interruption = input.context?.interruption;
|
|
@@ -40010,7 +40101,7 @@ function createTaskMiddleware(options = {}) {
|
|
|
40010
40101
|
await validateExecutionResult();
|
|
40011
40102
|
const callerError = await revalidateCaller();
|
|
40012
40103
|
if (callerError) return callerError;
|
|
40013
|
-
|
|
40104
|
+
const interrupted = await lifecycle.interruptTask({
|
|
40014
40105
|
tenantId: tenantId2,
|
|
40015
40106
|
taskId: input.id,
|
|
40016
40107
|
type,
|
|
@@ -40018,40 +40109,52 @@ function createTaskMiddleware(options = {}) {
|
|
|
40018
40109
|
actor,
|
|
40019
40110
|
threadId,
|
|
40020
40111
|
dependencyTaskIds: input.dependencyTaskIds
|
|
40021
|
-
})
|
|
40112
|
+
});
|
|
40113
|
+
if (!interrupted.success) return lifecycleMutationResponse(interrupted);
|
|
40114
|
+
if (trustedProject || !hasCarriedContentFields()) return lifecycleMutationResponse(interrupted);
|
|
40115
|
+
existing = { ...existing, status: input.status };
|
|
40022
40116
|
}
|
|
40023
40117
|
if (lifecycle && input.status === "in_progress" && existing.status === "interrupted") {
|
|
40024
40118
|
await validateExecutionResult();
|
|
40025
40119
|
const callerError = await revalidateCaller();
|
|
40026
40120
|
if (callerError) return callerError;
|
|
40027
|
-
|
|
40121
|
+
const resumed = await lifecycle.resumeInterruption({
|
|
40028
40122
|
tenantId: tenantId2,
|
|
40029
40123
|
taskId: input.id,
|
|
40030
40124
|
actor,
|
|
40031
40125
|
threadId
|
|
40032
|
-
})
|
|
40126
|
+
});
|
|
40127
|
+
if (!resumed.success) return lifecycleMutationResponse(resumed);
|
|
40128
|
+
if (trustedProject || !hasCarriedContentFields()) return lifecycleMutationResponse(resumed);
|
|
40129
|
+
existing = { ...existing, status: input.status };
|
|
40033
40130
|
}
|
|
40034
40131
|
if (lifecycle && input.status === "in_progress" && existing.status === "pending") {
|
|
40035
40132
|
await validateExecutionResult();
|
|
40036
40133
|
const callerError = await revalidateCaller();
|
|
40037
40134
|
if (callerError) return callerError;
|
|
40038
|
-
|
|
40135
|
+
const started = await lifecycle.startTask({
|
|
40039
40136
|
tenantId: tenantId2,
|
|
40040
40137
|
taskId: input.id,
|
|
40041
40138
|
actor,
|
|
40042
40139
|
threadId
|
|
40043
|
-
})
|
|
40140
|
+
});
|
|
40141
|
+
if (!started.success) return lifecycleMutationResponse(started);
|
|
40142
|
+
if (trustedProject || !hasCarriedContentFields()) return lifecycleMutationResponse(started);
|
|
40143
|
+
existing = { ...existing, status: input.status };
|
|
40044
40144
|
}
|
|
40045
40145
|
if (lifecycle && input.status === "in_progress" && existing.status === "failed") {
|
|
40046
40146
|
await validateExecutionResult();
|
|
40047
40147
|
const callerError = await revalidateCaller();
|
|
40048
40148
|
if (callerError) return callerError;
|
|
40049
|
-
|
|
40149
|
+
const retried = await lifecycle.retryTask({
|
|
40050
40150
|
tenantId: tenantId2,
|
|
40051
40151
|
taskId: input.id,
|
|
40052
40152
|
actor,
|
|
40053
40153
|
threadId
|
|
40054
|
-
})
|
|
40154
|
+
});
|
|
40155
|
+
if (!retried.success) return lifecycleMutationResponse(retried);
|
|
40156
|
+
if (trustedProject || !hasCarriedContentFields()) return lifecycleMutationResponse(retried);
|
|
40157
|
+
existing = { ...existing, status: input.status };
|
|
40055
40158
|
}
|
|
40056
40159
|
if (isAgentTask && input.requireReview === true && options.reviewMode !== "hitl") {
|
|
40057
40160
|
return reviewModeDisabledResponse();
|
|
@@ -40172,7 +40275,8 @@ function createTaskMiddleware(options = {}) {
|
|
|
40172
40275
|
return JSON.stringify({
|
|
40173
40276
|
success: false,
|
|
40174
40277
|
code: "AGENT_TASK_LIFECYCLE_REQUIRED",
|
|
40175
|
-
error: `Agent task lifecycle cannot transition from '${existing.status}' to '${input.status}'
|
|
40278
|
+
error: `Agent task lifecycle cannot transition from '${existing.status}' to '${input.status}'.`,
|
|
40279
|
+
hint: "Valid transitions: pending\u2192in_progress, in_progress\u2192completed (requires result + beliefImpact), in_progress\u2192failed (requires failureReason), in_progress\u2192cancelled, in_progress\u2192interrupted. Check the current status with manage_task get first."
|
|
40176
40280
|
});
|
|
40177
40281
|
}
|
|
40178
40282
|
const persistedStatus = input.status;
|
|
@@ -40395,8 +40499,8 @@ function createTaskMiddleware(options = {}) {
|
|
|
40395
40499
|
if (!existing) {
|
|
40396
40500
|
return JSON.stringify({
|
|
40397
40501
|
success: false,
|
|
40398
|
-
error: `Task '${input.id}' not found
|
|
40399
|
-
hint: "Use list to
|
|
40502
|
+
error: `Task '${input.id}' not found`,
|
|
40503
|
+
hint: "Use list to see available tasks and their IDs"
|
|
40400
40504
|
});
|
|
40401
40505
|
}
|
|
40402
40506
|
if (!taskMatchesRuntimeScope3(existing, workspaceId, projectId)) {
|
|
@@ -41478,6 +41582,10 @@ never plain text. One question per tool call.
|
|
|
41478
41582
|
safety boundary): the target identity exists and is fixed. Preserve the IDs. Confirm only
|
|
41479
41583
|
material-boundary decisions. After architecture approval, apply reversible in-contract updates
|
|
41480
41584
|
without routine renewed confirmation; every material boundary requires HITL or human confirmation.
|
|
41585
|
+
The bound tracking Task is your main task and belief root: reconcile its description before
|
|
41586
|
+
creating children \u2014 write the confirmed Objective, Acceptance Criteria, and Belief State once the
|
|
41587
|
+
Goal Model is confirmed, and keep reconciling the same task as evidence arrives. Never create a
|
|
41588
|
+
parallel main task under it; children are only independently verifiable outcomes.
|
|
41481
41589
|
If the exact bound target is missing or cannot be loaded \u2192 hard stop: update the tracking task with status
|
|
41482
41590
|
"interrupted" and a recovery condition. NEVER create a replacement.
|
|
41483
41591
|
|