@rzx/ohs 1.1.15 → 1.1.16
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/frontend/index.js +24 -1
- package/dist/frontend/index.js.map +9 -8
- package/dist/index.js +2038 -97
- package/dist/index.js.map +31 -25
- package/dist/migrations/0018_session_goals.sql +17 -0
- package/dist/migrations/0019_session_goal_progress.sql +3 -0
- package/dist/migrations/meta/_journal.json +140 -18
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -15117,6 +15117,15 @@ function validateSessionUserInputItems(items) {
|
|
|
15117
15117
|
textBytes += new TextEncoder().encode(item.text).byteLength;
|
|
15118
15118
|
continue;
|
|
15119
15119
|
}
|
|
15120
|
+
if (item.type === "context") {
|
|
15121
|
+
if (item.kind !== "conversation")
|
|
15122
|
+
throw new Error("invalid_context_kind");
|
|
15123
|
+
assertValidString(item.id, "id");
|
|
15124
|
+
assertValidString(item.displayName, "displayName");
|
|
15125
|
+
assertMaximumLength(item.id, SESSION_INPUT_LIMITS.maxNameChars, "id");
|
|
15126
|
+
assertMaximumLength(item.displayName, SESSION_INPUT_LIMITS.maxDisplayNameChars, "displayName");
|
|
15127
|
+
continue;
|
|
15128
|
+
}
|
|
15120
15129
|
assertValidString(item.name, "name");
|
|
15121
15130
|
assertValidString(item.path, "path");
|
|
15122
15131
|
assertMaximumLength(item.name, SESSION_INPUT_LIMITS.maxNameChars, "name");
|
|
@@ -15152,7 +15161,7 @@ function normalizeSessionUserInputItems(items) {
|
|
|
15152
15161
|
return normalized;
|
|
15153
15162
|
}
|
|
15154
15163
|
function sessionUserInputText(items) {
|
|
15155
|
-
return normalizeSessionUserInputItems(items).map((item) => item.type === "text" ? item.text : `$${item.name}`).join("");
|
|
15164
|
+
return normalizeSessionUserInputItems(items).map((item) => item.type === "text" ? item.text : item.type === "context" ? `@${item.displayName}` : `$${item.name}`).join("");
|
|
15156
15165
|
}
|
|
15157
15166
|
function assertValidString(value, field) {
|
|
15158
15167
|
if (typeof value !== "string" || CONTROL_CHARACTER_PATTERN.test(value))
|
|
@@ -15341,6 +15350,12 @@ function parseSessionInputItems(value) {
|
|
|
15341
15350
|
}
|
|
15342
15351
|
return { type: "text", text: item.text };
|
|
15343
15352
|
}
|
|
15353
|
+
if (item.type === "context") {
|
|
15354
|
+
if (item.kind !== "conversation" || typeof item.id !== "string" || typeof item.displayName !== "string") {
|
|
15355
|
+
throw new ProtocolValidationError(`${field} requires kind, id and displayName`, field);
|
|
15356
|
+
}
|
|
15357
|
+
return { type: "context", kind: "conversation", id: item.id, displayName: item.displayName };
|
|
15358
|
+
}
|
|
15344
15359
|
if (item.type !== "skill" && item.type !== "mention") {
|
|
15345
15360
|
throw new ProtocolValidationError(`${field}.type is invalid`, `${field}.type`);
|
|
15346
15361
|
}
|
|
@@ -16190,6 +16205,201 @@ var init_capabilities = __esm(() => {
|
|
|
16190
16205
|
init_attachment();
|
|
16191
16206
|
});
|
|
16192
16207
|
|
|
16208
|
+
// ../../packages/protocol/src/session-goals.ts
|
|
16209
|
+
function parseCreateSessionGoalInput(value) {
|
|
16210
|
+
const record = goalRecord(value);
|
|
16211
|
+
return {
|
|
16212
|
+
requestId: requiredGoalString(record.requestId, "requestId", 128),
|
|
16213
|
+
objective: requiredGoalString(record.objective, "objective", MAX_GOAL_OBJECTIVE_CHARS),
|
|
16214
|
+
...record.maxAutoTurns === undefined ? {} : {
|
|
16215
|
+
maxAutoTurns: goalPositiveInteger(record.maxAutoTurns, "maxAutoTurns")
|
|
16216
|
+
},
|
|
16217
|
+
...parseGoalContent(record)
|
|
16218
|
+
};
|
|
16219
|
+
}
|
|
16220
|
+
function parseUpdateSessionGoalInput(value) {
|
|
16221
|
+
const record = goalRecord(value);
|
|
16222
|
+
return {
|
|
16223
|
+
requestId: requiredGoalString(record.requestId, "requestId", 128),
|
|
16224
|
+
expectedRevision: goalNonNegativeInteger(record.expectedRevision, "expectedRevision"),
|
|
16225
|
+
objective: requiredGoalString(record.objective, "objective", MAX_GOAL_OBJECTIVE_CHARS),
|
|
16226
|
+
...parseGoalContent(record)
|
|
16227
|
+
};
|
|
16228
|
+
}
|
|
16229
|
+
function parseGoalActionInput(value) {
|
|
16230
|
+
const record = goalRecord(value);
|
|
16231
|
+
if (record.action !== "pause" && record.action !== "resume" && record.action !== "cancel" && record.action !== "confirm") {
|
|
16232
|
+
throw new ProtocolValidationError("invalid_goal_action", "action");
|
|
16233
|
+
}
|
|
16234
|
+
if (record.action !== "resume" && (record.additionalAutoTurns !== undefined || record.response !== undefined)) {
|
|
16235
|
+
throw new ProtocolValidationError("Only resume accepts additionalAutoTurns or response", "action");
|
|
16236
|
+
}
|
|
16237
|
+
if (record.action === "confirm")
|
|
16238
|
+
requiredGoalString(record.questionId, "questionId", 256);
|
|
16239
|
+
if ((record.action === "pause" || record.action === "cancel") && record.questionId !== undefined) {
|
|
16240
|
+
throw new ProtocolValidationError("This action does not answer a question", "questionId");
|
|
16241
|
+
}
|
|
16242
|
+
return {
|
|
16243
|
+
requestId: requiredGoalString(record.requestId, "requestId", 128),
|
|
16244
|
+
expectedRevision: goalNonNegativeInteger(record.expectedRevision, "expectedRevision"),
|
|
16245
|
+
action: record.action,
|
|
16246
|
+
...record.questionId === undefined ? {} : {
|
|
16247
|
+
questionId: requiredGoalString(record.questionId, "questionId", 256)
|
|
16248
|
+
},
|
|
16249
|
+
...record.response === undefined ? {} : {
|
|
16250
|
+
response: requiredGoalString(record.response, "response", MAX_GOAL_OBJECTIVE_CHARS)
|
|
16251
|
+
},
|
|
16252
|
+
...record.additionalAutoTurns === undefined ? {} : {
|
|
16253
|
+
additionalAutoTurns: goalPositiveInteger(record.additionalAutoTurns, "additionalAutoTurns")
|
|
16254
|
+
}
|
|
16255
|
+
};
|
|
16256
|
+
}
|
|
16257
|
+
function goalRecord(value) {
|
|
16258
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
16259
|
+
throw new ProtocolValidationError("invalid_goal_input", "goal");
|
|
16260
|
+
return value;
|
|
16261
|
+
}
|
|
16262
|
+
function requiredGoalString(value, field, max) {
|
|
16263
|
+
if (typeof value !== "string" || !value.trim() || /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/.test(value))
|
|
16264
|
+
throw new ProtocolValidationError(`invalid_goal_${field}`, field);
|
|
16265
|
+
const normalized = value.trim();
|
|
16266
|
+
if (normalized.length > max)
|
|
16267
|
+
throw new ProtocolValidationError(`goal_${field}_limit_exceeded`, field);
|
|
16268
|
+
return normalized;
|
|
16269
|
+
}
|
|
16270
|
+
function goalNonNegativeInteger(value, field) {
|
|
16271
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
16272
|
+
throw new ProtocolValidationError(`invalid_goal_${field}`, field);
|
|
16273
|
+
return value;
|
|
16274
|
+
}
|
|
16275
|
+
function goalPositiveInteger(value, field) {
|
|
16276
|
+
const integer = goalNonNegativeInteger(value, field);
|
|
16277
|
+
if (integer < 1 || integer > MAX_GOAL_AUTO_TURNS)
|
|
16278
|
+
throw new ProtocolValidationError(`invalid_goal_${field}`, field);
|
|
16279
|
+
return integer;
|
|
16280
|
+
}
|
|
16281
|
+
function parseGoalContent(record) {
|
|
16282
|
+
return {
|
|
16283
|
+
...record.items === undefined ? {} : { items: parseSessionInputItems(record.items) },
|
|
16284
|
+
...record.attachments === undefined ? {} : { attachments: parsePromptAttachments(record.attachments) }
|
|
16285
|
+
};
|
|
16286
|
+
}
|
|
16287
|
+
function parseGoalAssessment(value, binding) {
|
|
16288
|
+
const record = goalRecord(value);
|
|
16289
|
+
const decision = record.decision;
|
|
16290
|
+
if (decision !== "continue" && decision !== "complete" && decision !== "waiting_user" && decision !== "blocked") {
|
|
16291
|
+
throw new ProtocolValidationError("invalid_goal_decision", "decision");
|
|
16292
|
+
}
|
|
16293
|
+
if (!Array.isArray(record.evidence) || record.evidence.length > 32)
|
|
16294
|
+
throw new ProtocolValidationError("invalid_goal_evidence", "evidence");
|
|
16295
|
+
const refs = record.evidenceRefs ?? [];
|
|
16296
|
+
if (!Array.isArray(refs) || refs.length > 32)
|
|
16297
|
+
throw new ProtocolValidationError("invalid_goal_evidence_refs", "evidenceRefs");
|
|
16298
|
+
const savedWait = record.wait && typeof record.wait === "object" && !Array.isArray(record.wait) ? record.wait : undefined;
|
|
16299
|
+
const questionValue = record.question ?? (savedWait?.kind === "user" ? savedWait.question : undefined);
|
|
16300
|
+
const question = questionValue === undefined ? undefined : requiredGoalString(questionValue, "question", 4000);
|
|
16301
|
+
const progressAssessment = parseGoalProgressAssessment(record.progressAssessment);
|
|
16302
|
+
if ((decision === "blocked" || progressAssessment.kind === "no_progress") && !progressAssessment.blockerKey) {
|
|
16303
|
+
throw new ProtocolValidationError("goal_no_progress_requires_blocker_key", "progressAssessment");
|
|
16304
|
+
}
|
|
16305
|
+
const requirements = parseGoalRequirements(record.requirements, binding);
|
|
16306
|
+
const remainingWork = parseGoalTextArray(record.remainingWork, "remainingWork");
|
|
16307
|
+
if (decision === "complete") {
|
|
16308
|
+
if (!requirements?.length)
|
|
16309
|
+
throw new ProtocolValidationError("goal_complete_requires_requirements", "requirements");
|
|
16310
|
+
}
|
|
16311
|
+
const externalWait = progressAssessment.kind === "waiting" && savedWait?.kind === "external" ? {
|
|
16312
|
+
kind: "external",
|
|
16313
|
+
handleId: requiredGoalString(savedWait.handleId, "handleId", 256),
|
|
16314
|
+
runId: binding.runId,
|
|
16315
|
+
deadlineAt: goalPositiveTimestamp(savedWait.deadlineAt, "deadlineAt")
|
|
16316
|
+
} : undefined;
|
|
16317
|
+
return {
|
|
16318
|
+
...binding,
|
|
16319
|
+
decision,
|
|
16320
|
+
progress: requiredGoalString(record.progress, "progress", 4000),
|
|
16321
|
+
progressAssessment,
|
|
16322
|
+
evidence: record.evidence.map((text) => requiredGoalString(text, "evidence", 4000)),
|
|
16323
|
+
evidenceRefs: refs.map((value) => {
|
|
16324
|
+
const ref = goalRecord(value);
|
|
16325
|
+
return {
|
|
16326
|
+
...binding,
|
|
16327
|
+
messagePartId: requiredGoalString(ref.messagePartId, "messagePartId", 256),
|
|
16328
|
+
criterion: requiredGoalString(ref.criterion, "criterion", 4000)
|
|
16329
|
+
};
|
|
16330
|
+
}),
|
|
16331
|
+
...requirements === undefined ? {} : { requirements },
|
|
16332
|
+
...remainingWork === undefined ? {} : { remainingWork },
|
|
16333
|
+
...record.nextStep === undefined ? {} : { nextStep: requiredGoalString(record.nextStep, "nextStep", 4000) },
|
|
16334
|
+
...record.reason === undefined ? {} : { reason: requiredGoalString(record.reason, "reason", 4000) },
|
|
16335
|
+
...externalWait ? { wait: externalWait } : {},
|
|
16336
|
+
...decision === "waiting_user" ? {
|
|
16337
|
+
wait: {
|
|
16338
|
+
kind: "user",
|
|
16339
|
+
questionId: `goal-question-${binding.runId}`,
|
|
16340
|
+
question: question ?? "请补充继续目标所需的信息。"
|
|
16341
|
+
}
|
|
16342
|
+
} : {}
|
|
16343
|
+
};
|
|
16344
|
+
}
|
|
16345
|
+
function goalPositiveTimestamp(value, field) {
|
|
16346
|
+
if (!Number.isSafeInteger(value) || value <= 0)
|
|
16347
|
+
throw new ProtocolValidationError(`invalid_goal_${field}`, field);
|
|
16348
|
+
return value;
|
|
16349
|
+
}
|
|
16350
|
+
function parseGoalProgressAssessment(value) {
|
|
16351
|
+
const record = goalRecord(value);
|
|
16352
|
+
if (record.kind !== "progress" && record.kind !== "waiting" && record.kind !== "no_progress") {
|
|
16353
|
+
throw new ProtocolValidationError("invalid_goal_progress_kind", "progressAssessment");
|
|
16354
|
+
}
|
|
16355
|
+
return {
|
|
16356
|
+
kind: record.kind,
|
|
16357
|
+
summary: requiredGoalString(record.summary, "progressSummary", 4000),
|
|
16358
|
+
...record.blockerKey === undefined ? {} : {
|
|
16359
|
+
blockerKey: requiredGoalString(record.blockerKey, "blockerKey", 256)
|
|
16360
|
+
}
|
|
16361
|
+
};
|
|
16362
|
+
}
|
|
16363
|
+
function parseGoalTextArray(value, field) {
|
|
16364
|
+
if (value === undefined)
|
|
16365
|
+
return;
|
|
16366
|
+
if (!Array.isArray(value) || value.length > 64)
|
|
16367
|
+
throw new ProtocolValidationError(`invalid_goal_${field}`, field);
|
|
16368
|
+
return value.map((item) => requiredGoalString(item, field, 4000));
|
|
16369
|
+
}
|
|
16370
|
+
function parseGoalRequirements(value, binding) {
|
|
16371
|
+
if (value === undefined)
|
|
16372
|
+
return;
|
|
16373
|
+
if (!Array.isArray(value) || value.length > 64)
|
|
16374
|
+
throw new ProtocolValidationError("invalid_goal_requirements", "requirements");
|
|
16375
|
+
return value.map((item) => {
|
|
16376
|
+
const record = goalRecord(item);
|
|
16377
|
+
if (record.status !== "satisfied" && record.status !== "incomplete" && record.status !== "needs_user") {
|
|
16378
|
+
throw new ProtocolValidationError("invalid_goal_requirement_status", "requirements");
|
|
16379
|
+
}
|
|
16380
|
+
const rawRefs = record.evidenceRefs ?? [];
|
|
16381
|
+
if (!Array.isArray(rawRefs) || rawRefs.length > 32)
|
|
16382
|
+
throw new ProtocolValidationError("invalid_goal_requirement_evidence_refs", "requirements");
|
|
16383
|
+
return {
|
|
16384
|
+
requirement: requiredGoalString(record.requirement, "requirement", 4000),
|
|
16385
|
+
source: requiredGoalString(record.source, "source", 4000),
|
|
16386
|
+
status: record.status,
|
|
16387
|
+
evidenceRefs: rawRefs.map((value) => {
|
|
16388
|
+
const ref = goalRecord(value);
|
|
16389
|
+
return {
|
|
16390
|
+
...binding,
|
|
16391
|
+
messagePartId: requiredGoalString(ref.messagePartId, "messagePartId", 256),
|
|
16392
|
+
criterion: requiredGoalString(ref.criterion, "criterion", 4000)
|
|
16393
|
+
};
|
|
16394
|
+
})
|
|
16395
|
+
};
|
|
16396
|
+
});
|
|
16397
|
+
}
|
|
16398
|
+
var DEFAULT_GOAL_AUTO_TURNS = 20, MAX_GOAL_AUTO_TURNS = 1000, MAX_GOAL_OBJECTIVE_CHARS = 32000;
|
|
16399
|
+
var init_session_goals = __esm(() => {
|
|
16400
|
+
init_requests();
|
|
16401
|
+
});
|
|
16402
|
+
|
|
16193
16403
|
// ../../packages/protocol/src/index.ts
|
|
16194
16404
|
var init_src4 = __esm(() => {
|
|
16195
16405
|
init_session3();
|
|
@@ -16198,6 +16408,7 @@ var init_src4 = __esm(() => {
|
|
|
16198
16408
|
init_capabilities();
|
|
16199
16409
|
init_attachment();
|
|
16200
16410
|
init_session_input_items();
|
|
16411
|
+
init_session_goals();
|
|
16201
16412
|
});
|
|
16202
16413
|
|
|
16203
16414
|
// ../../packages/services/src/attachment/attachment-errors.ts
|
|
@@ -16375,6 +16586,8 @@ var init_event_registry = __esm(() => {
|
|
|
16375
16586
|
throw new Error("field must be text or reasoning");
|
|
16376
16587
|
}),
|
|
16377
16588
|
sessionDefinition("session.run.created", objectPayload("run")),
|
|
16589
|
+
sessionDefinition("session.goal.created", objectPayload("goal")),
|
|
16590
|
+
sessionDefinition("session.goal.updated", objectPayload("goal")),
|
|
16378
16591
|
sessionDefinition("session.run.updated", (payload) => {
|
|
16379
16592
|
objectPayload("run")(payload);
|
|
16380
16593
|
requireString(payload, "previousStatus");
|
|
@@ -16653,6 +16866,29 @@ import { basename as basename4, dirname as dirname3, relative, resolve as resolv
|
|
|
16653
16866
|
import { fileURLToPath } from "node:url";
|
|
16654
16867
|
import { isDeepStrictEqual } from "node:util";
|
|
16655
16868
|
import Database from "better-sqlite3";
|
|
16869
|
+
function sessionGoalFromRow(row) {
|
|
16870
|
+
const wait = typeof row.wait_json === "string" ? JSON.parse(row.wait_json) : undefined;
|
|
16871
|
+
const evidence = typeof row.evidence_json === "string" ? JSON.parse(row.evidence_json) : [];
|
|
16872
|
+
const assessment = typeof row.last_assessment_json === "string" ? JSON.parse(row.last_assessment_json) : undefined;
|
|
16873
|
+
return {
|
|
16874
|
+
id: String(row.id),
|
|
16875
|
+
sessionId: String(row.session_id),
|
|
16876
|
+
objective: String(row.objective),
|
|
16877
|
+
revision: Number(row.revision),
|
|
16878
|
+
status: String(row.status),
|
|
16879
|
+
maxAutoTurns: Number(row.max_auto_turns),
|
|
16880
|
+
autoTurnsUsed: Number(row.auto_turns_used),
|
|
16881
|
+
noProgressCount: Number(row.no_progress_count),
|
|
16882
|
+
...typeof row.blocker_key === "string" ? { blockerKey: row.blocker_key } : {},
|
|
16883
|
+
...typeof row.current_run_id === "string" ? { currentRunId: row.current_run_id } : {},
|
|
16884
|
+
...typeof row.reason === "string" ? { reason: row.reason } : {},
|
|
16885
|
+
...wait ? { wait } : {},
|
|
16886
|
+
evidence,
|
|
16887
|
+
...assessment ? { assessment } : {},
|
|
16888
|
+
createdAt: Number(row.created_at),
|
|
16889
|
+
updatedAt: Number(row.updated_at)
|
|
16890
|
+
};
|
|
16891
|
+
}
|
|
16656
16892
|
|
|
16657
16893
|
class SessionStore {
|
|
16658
16894
|
path;
|
|
@@ -18387,6 +18623,209 @@ class SessionStore {
|
|
|
18387
18623
|
}
|
|
18388
18624
|
return this.getProjectionSettlement(id);
|
|
18389
18625
|
}
|
|
18626
|
+
createGoal(input) {
|
|
18627
|
+
this.assertCurrentOwner();
|
|
18628
|
+
const session = assertSession(this.state, input.sessionId);
|
|
18629
|
+
assertMutableSession(session);
|
|
18630
|
+
const id = input.id ?? randomUUID2();
|
|
18631
|
+
const timestamp = now();
|
|
18632
|
+
try {
|
|
18633
|
+
this.database.prepare(`
|
|
18634
|
+
INSERT INTO session_goal (
|
|
18635
|
+
id, session_id, objective, revision, status, max_auto_turns,
|
|
18636
|
+
auto_turns_used, no_progress_count, evidence_json, created_at, updated_at
|
|
18637
|
+
) VALUES (?, ?, ?, 0, 'active', ?, 0, 0, '[]', ?, ?)
|
|
18638
|
+
`).run(id, input.sessionId, input.objective, input.maxAutoTurns, timestamp, timestamp);
|
|
18639
|
+
} catch (error) {
|
|
18640
|
+
if (String(error).includes("session_goal_session_open_unique")) {
|
|
18641
|
+
throw new Error(`Session already has an open goal: ${input.sessionId}`);
|
|
18642
|
+
}
|
|
18643
|
+
throw error;
|
|
18644
|
+
}
|
|
18645
|
+
const goal = this.getGoal(id);
|
|
18646
|
+
this.appendEvent({
|
|
18647
|
+
type: "session.goal.created",
|
|
18648
|
+
sessionId: input.sessionId,
|
|
18649
|
+
payload: { goal }
|
|
18650
|
+
});
|
|
18651
|
+
return goal;
|
|
18652
|
+
}
|
|
18653
|
+
getGoalRequest(requestId) {
|
|
18654
|
+
const row = this.database.prepare(`SELECT * FROM session_goal_request WHERE request_id = ?`).get(requestId);
|
|
18655
|
+
if (!row)
|
|
18656
|
+
return;
|
|
18657
|
+
return {
|
|
18658
|
+
requestId: String(row.request_id),
|
|
18659
|
+
sessionId: String(row.session_id),
|
|
18660
|
+
fingerprint: String(row.fingerprint),
|
|
18661
|
+
status: String(row.status),
|
|
18662
|
+
...typeof row.goal_id === "string" ? { goalId: row.goal_id } : {},
|
|
18663
|
+
...typeof row.result_json === "string" ? { result: JSON.parse(row.result_json) } : {},
|
|
18664
|
+
...typeof row.error === "string" ? { error: row.error } : {},
|
|
18665
|
+
createdAt: Number(row.created_at),
|
|
18666
|
+
updatedAt: Number(row.updated_at)
|
|
18667
|
+
};
|
|
18668
|
+
}
|
|
18669
|
+
beginGoalRequest(input) {
|
|
18670
|
+
this.assertCurrentOwner();
|
|
18671
|
+
const existing = this.getGoalRequest(input.requestId);
|
|
18672
|
+
if (existing) {
|
|
18673
|
+
if (existing.sessionId !== input.sessionId || existing.fingerprint !== input.fingerprint)
|
|
18674
|
+
throw new Error("session_goal_request_conflict");
|
|
18675
|
+
return existing;
|
|
18676
|
+
}
|
|
18677
|
+
const timestamp = now();
|
|
18678
|
+
this.database.prepare(`INSERT INTO session_goal_request (request_id, session_id, fingerprint, status, created_at, updated_at) VALUES (?, ?, ?, 'pending', ?, ?)`).run(input.requestId, input.sessionId, input.fingerprint, timestamp, timestamp);
|
|
18679
|
+
return this.getGoalRequest(input.requestId);
|
|
18680
|
+
}
|
|
18681
|
+
settleGoalRequest(requestId, input) {
|
|
18682
|
+
this.assertCurrentOwner();
|
|
18683
|
+
const timestamp = now();
|
|
18684
|
+
const result = this.database.prepare(`UPDATE session_goal_request SET status = ?, goal_id = ?, result_json = ?, error = ?, updated_at = ? WHERE request_id = ?`).run(input.status, input.goalId ?? null, input.result ? JSON.stringify(input.result) : null, input.error ?? null, timestamp, requestId);
|
|
18685
|
+
if (result.changes !== 1)
|
|
18686
|
+
throw new Error(`Session goal request not found: ${requestId}`);
|
|
18687
|
+
return this.getGoalRequest(requestId);
|
|
18688
|
+
}
|
|
18689
|
+
recordGoalAssessment(input) {
|
|
18690
|
+
this.assertCurrentOwner();
|
|
18691
|
+
this.database.prepare(`
|
|
18692
|
+
INSERT INTO session_goal_assessment (id, goal_id, revision, run_id, assessment_json, created_at)
|
|
18693
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
18694
|
+
ON CONFLICT(goal_id, revision, run_id) DO UPDATE SET assessment_json = excluded.assessment_json
|
|
18695
|
+
`).run(randomUUID2(), input.goalId, input.revision, input.runId, JSON.stringify(input.assessment), now());
|
|
18696
|
+
}
|
|
18697
|
+
goalEvidenceSignatures(goalId) {
|
|
18698
|
+
const rows = this.database.prepare(`SELECT assessment_json FROM session_goal_assessment WHERE goal_id = ?`).all(goalId);
|
|
18699
|
+
return rows.flatMap((row) => {
|
|
18700
|
+
const value = JSON.parse(row.assessment_json);
|
|
18701
|
+
return value.verifiedSignatures ?? [];
|
|
18702
|
+
});
|
|
18703
|
+
}
|
|
18704
|
+
recordGoalContinuation(input) {
|
|
18705
|
+
this.assertCurrentOwner();
|
|
18706
|
+
const timestamp = now();
|
|
18707
|
+
const result = this.database.prepare(`
|
|
18708
|
+
INSERT OR IGNORE INTO session_goal_continuation
|
|
18709
|
+
(id, goal_id, revision, previous_run_id, input_id, run_id, status, created_at, updated_at)
|
|
18710
|
+
VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, ?)
|
|
18711
|
+
`).run(randomUUID2(), input.goalId, input.revision, input.previousRunId, input.inputId, input.runId, timestamp, timestamp);
|
|
18712
|
+
return result.changes === 1;
|
|
18713
|
+
}
|
|
18714
|
+
pauseActiveGoalsOnStartup() {
|
|
18715
|
+
this.assertCurrentOwner();
|
|
18716
|
+
return this.transaction(() => {
|
|
18717
|
+
const rows = this.database.prepare(`SELECT id FROM session_goal WHERE status = 'active'`).all();
|
|
18718
|
+
for (const { id } of rows) {
|
|
18719
|
+
const goal = this.getGoal(id);
|
|
18720
|
+
this.updateGoal(id, {
|
|
18721
|
+
expectedRevision: goal.revision,
|
|
18722
|
+
status: "paused",
|
|
18723
|
+
currentRunId: null,
|
|
18724
|
+
reason: "应用重启后需要手动继续"
|
|
18725
|
+
});
|
|
18726
|
+
}
|
|
18727
|
+
this.database.prepare(`UPDATE session_goal_continuation SET status = 'cancelled', updated_at = ? WHERE status = 'pending'`).run(now());
|
|
18728
|
+
return rows.length;
|
|
18729
|
+
});
|
|
18730
|
+
}
|
|
18731
|
+
markGoalContinuation(runId, status) {
|
|
18732
|
+
this.assertCurrentOwner();
|
|
18733
|
+
this.database.prepare(`UPDATE session_goal_continuation SET status = ?, updated_at = ? WHERE run_id = ?`).run(status, now(), runId);
|
|
18734
|
+
}
|
|
18735
|
+
finishGoalRun(runId) {
|
|
18736
|
+
this.assertCurrentOwner();
|
|
18737
|
+
const row = this.database.prepare(`SELECT id FROM session_goal WHERE current_run_id = ?`).get(runId);
|
|
18738
|
+
if (!row)
|
|
18739
|
+
return;
|
|
18740
|
+
this.database.prepare(`UPDATE session_goal SET current_run_id = NULL, updated_at = ? WHERE id = ?`).run(now(), row.id);
|
|
18741
|
+
const goal = this.getGoal(row.id);
|
|
18742
|
+
this.appendEvent({
|
|
18743
|
+
type: "session.goal.updated",
|
|
18744
|
+
sessionId: goal.sessionId,
|
|
18745
|
+
payload: { goal }
|
|
18746
|
+
});
|
|
18747
|
+
}
|
|
18748
|
+
startGoalRun(goalId, revision, runId, automatic) {
|
|
18749
|
+
this.assertCurrentOwner();
|
|
18750
|
+
return this.transaction(() => {
|
|
18751
|
+
const goal = this.getGoal(goalId);
|
|
18752
|
+
if (!goal || goal.status !== "active" || goal.revision !== revision)
|
|
18753
|
+
return false;
|
|
18754
|
+
const run = this.getRun(runId);
|
|
18755
|
+
if (!run || run.sessionId !== goal.sessionId || run.status !== "pending" && run.status !== "running")
|
|
18756
|
+
return false;
|
|
18757
|
+
if (goal.currentRunId === runId)
|
|
18758
|
+
return true;
|
|
18759
|
+
if (automatic && goal.autoTurnsUsed >= goal.maxAutoTurns) {
|
|
18760
|
+
this.updateGoal(goalId, {
|
|
18761
|
+
expectedRevision: revision,
|
|
18762
|
+
status: "paused",
|
|
18763
|
+
reason: "目标自动续跑额度已用完",
|
|
18764
|
+
currentRunId: null
|
|
18765
|
+
});
|
|
18766
|
+
return false;
|
|
18767
|
+
}
|
|
18768
|
+
this.database.prepare(`UPDATE session_goal SET current_run_id = ?, auto_turns_used = auto_turns_used + ?, updated_at = ? WHERE id = ? AND revision = ?`).run(runId, automatic ? 1 : 0, now(), goalId, revision);
|
|
18769
|
+
this.appendEvent({
|
|
18770
|
+
type: "session.goal.updated",
|
|
18771
|
+
sessionId: goal.sessionId,
|
|
18772
|
+
payload: { goal: this.getGoal(goalId) }
|
|
18773
|
+
});
|
|
18774
|
+
return true;
|
|
18775
|
+
});
|
|
18776
|
+
}
|
|
18777
|
+
getGoal(id) {
|
|
18778
|
+
const row = this.database.prepare(`SELECT * FROM session_goal WHERE id = ?`).get(id);
|
|
18779
|
+
return row ? sessionGoalFromRow(row) : undefined;
|
|
18780
|
+
}
|
|
18781
|
+
getCurrentGoal(sessionId) {
|
|
18782
|
+
const row = this.database.prepare(`
|
|
18783
|
+
SELECT * FROM session_goal
|
|
18784
|
+
WHERE session_id = ?
|
|
18785
|
+
ORDER BY CASE WHEN status IN ('active','waiting_user','blocked','paused') THEN 0 ELSE 1 END,
|
|
18786
|
+
updated_at DESC
|
|
18787
|
+
LIMIT 1
|
|
18788
|
+
`).get(sessionId);
|
|
18789
|
+
return row ? sessionGoalFromRow(row) : undefined;
|
|
18790
|
+
}
|
|
18791
|
+
updateGoal(id, input) {
|
|
18792
|
+
this.assertCurrentOwner();
|
|
18793
|
+
const current = this.getGoal(id);
|
|
18794
|
+
if (!current)
|
|
18795
|
+
throw new Error(`Session goal not found: ${id}`);
|
|
18796
|
+
if (current.revision !== input.expectedRevision)
|
|
18797
|
+
throw new Error("session_goal_revision_conflict");
|
|
18798
|
+
const nextRevision = current.revision + 1;
|
|
18799
|
+
const timestamp = now();
|
|
18800
|
+
const next = {
|
|
18801
|
+
objective: input.objective ?? current.objective,
|
|
18802
|
+
status: input.status ?? current.status,
|
|
18803
|
+
maxAutoTurns: input.maxAutoTurns ?? current.maxAutoTurns,
|
|
18804
|
+
autoTurnsUsed: input.autoTurnsUsed ?? current.autoTurnsUsed,
|
|
18805
|
+
noProgressCount: input.noProgressCount ?? current.noProgressCount,
|
|
18806
|
+
blockerKey: input.blockerKey === undefined ? current.blockerKey : input.blockerKey ?? undefined,
|
|
18807
|
+
currentRunId: input.currentRunId === undefined ? current.currentRunId : input.currentRunId ?? undefined,
|
|
18808
|
+
reason: input.reason === undefined ? current.reason : input.reason ?? undefined,
|
|
18809
|
+
wait: input.wait === undefined ? current.wait : input.wait ?? undefined,
|
|
18810
|
+
evidence: input.evidence ?? current.evidence,
|
|
18811
|
+
assessment: input.assessment === undefined ? current.assessment : input.assessment ?? undefined
|
|
18812
|
+
};
|
|
18813
|
+
const result = this.database.prepare(`
|
|
18814
|
+
UPDATE session_goal SET objective = ?, revision = ?, status = ?, max_auto_turns = ?,
|
|
18815
|
+
auto_turns_used = ?, no_progress_count = ?, blocker_key = ?, current_run_id = ?, reason = ?,
|
|
18816
|
+
wait_json = ?, evidence_json = ?, last_assessment_json = ?, updated_at = ?
|
|
18817
|
+
WHERE id = ? AND revision = ?
|
|
18818
|
+
`).run(next.objective, nextRevision, next.status, next.maxAutoTurns, next.autoTurnsUsed, next.noProgressCount, next.blockerKey ?? null, next.currentRunId ?? null, next.reason ?? null, next.wait ? JSON.stringify(next.wait) : null, JSON.stringify(next.evidence), next.assessment ? JSON.stringify(next.assessment) : null, timestamp, id, input.expectedRevision);
|
|
18819
|
+
if (result.changes !== 1)
|
|
18820
|
+
throw new Error("session_goal_revision_conflict");
|
|
18821
|
+
const goal = this.getGoal(id);
|
|
18822
|
+
this.appendEvent({
|
|
18823
|
+
type: "session.goal.updated",
|
|
18824
|
+
sessionId: goal.sessionId,
|
|
18825
|
+
payload: { goal }
|
|
18826
|
+
});
|
|
18827
|
+
return goal;
|
|
18828
|
+
}
|
|
18390
18829
|
createRun(input) {
|
|
18391
18830
|
const session = assertSession(this.state, input.sessionId);
|
|
18392
18831
|
assertMutableSession(session);
|
|
@@ -19089,11 +19528,15 @@ class SessionStore {
|
|
|
19089
19528
|
...row.output_json ? { output: JSON.parse(row.output_json) } : {},
|
|
19090
19529
|
...row.is_error !== null ? { isError: Boolean(row.is_error) } : {},
|
|
19091
19530
|
...row.asset_id ? { assetId: row.asset_id } : {},
|
|
19092
|
-
...row.attachment_intent ? {
|
|
19531
|
+
...row.attachment_intent ? {
|
|
19532
|
+
intent: row.attachment_intent
|
|
19533
|
+
} : {},
|
|
19093
19534
|
...row.display_name ? { displayName: row.display_name } : {},
|
|
19094
19535
|
...row.media_type ? { mediaType: row.media_type } : {},
|
|
19095
19536
|
...row.size_bytes !== null ? { sizeBytes: row.size_bytes } : {},
|
|
19096
|
-
...row.transformation_kind ? {
|
|
19537
|
+
...row.transformation_kind ? {
|
|
19538
|
+
kind: row.transformation_kind
|
|
19539
|
+
} : {},
|
|
19097
19540
|
...row.representation_id ? { representationId: row.representation_id } : {},
|
|
19098
19541
|
...row.processor ? { processor: row.processor } : {},
|
|
19099
19542
|
...row.transformation_error ? { transformationError: row.transformation_error } : {},
|
|
@@ -197051,6 +197494,22 @@ class OpenHarnessClient {
|
|
|
197051
197494
|
async compactSession(sessionId, options = {}) {
|
|
197052
197495
|
return await this.request(`/sessions/${encodeURIComponent(sessionId)}/compact`, { method: "POST", signal: options.signal });
|
|
197053
197496
|
}
|
|
197497
|
+
async getSessionGoal(sessionId) {
|
|
197498
|
+
const response = await this.request(`/sessions/${encodeURIComponent(sessionId)}/goal`);
|
|
197499
|
+
return response.goal;
|
|
197500
|
+
}
|
|
197501
|
+
async createSessionGoal(sessionId, input) {
|
|
197502
|
+
const response = await this.request(`/sessions/${encodeURIComponent(sessionId)}/goals`, { method: "POST", body: input });
|
|
197503
|
+
return response.goal;
|
|
197504
|
+
}
|
|
197505
|
+
async updateSessionGoal(sessionId, goalId, input) {
|
|
197506
|
+
const response = await this.request(`/sessions/${encodeURIComponent(sessionId)}/goals/${encodeURIComponent(goalId)}`, { method: "PATCH", body: input });
|
|
197507
|
+
return response.goal;
|
|
197508
|
+
}
|
|
197509
|
+
async applySessionGoalAction(sessionId, goalId, input) {
|
|
197510
|
+
const response = await this.request(`/sessions/${encodeURIComponent(sessionId)}/goals/${encodeURIComponent(goalId)}/actions`, { method: "POST", body: input });
|
|
197511
|
+
return response.goal;
|
|
197512
|
+
}
|
|
197054
197513
|
async rewindSession(sessionId, input = {}, options = {}) {
|
|
197055
197514
|
return await this.request(`/sessions/${encodeURIComponent(sessionId)}/rewind`, { method: "POST", body: input, signal: options.signal });
|
|
197056
197515
|
}
|
|
@@ -198120,6 +198579,7 @@ var init_commands = __esm(() => {
|
|
|
198120
198579
|
var init_src15 = __esm(() => {
|
|
198121
198580
|
init_transport();
|
|
198122
198581
|
init_src4();
|
|
198582
|
+
init_src4();
|
|
198123
198583
|
init_state();
|
|
198124
198584
|
init_commands();
|
|
198125
198585
|
init_src4();
|
|
@@ -200240,7 +200700,10 @@ function deepFrozenCopy(value) {
|
|
|
200240
200700
|
return Object.freeze(value.map((item) => deepFrozenCopy(item)));
|
|
200241
200701
|
}
|
|
200242
200702
|
if (value && typeof value === "object") {
|
|
200243
|
-
const copied = Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
200703
|
+
const copied = Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
200704
|
+
key,
|
|
200705
|
+
deepFrozenCopy(item)
|
|
200706
|
+
]));
|
|
200244
200707
|
return Object.freeze(copied);
|
|
200245
200708
|
}
|
|
200246
200709
|
return value;
|
|
@@ -204263,6 +204726,15 @@ function validateSessionUserInputItems2(items) {
|
|
|
204263
204726
|
textBytes += new TextEncoder().encode(item.text).byteLength;
|
|
204264
204727
|
continue;
|
|
204265
204728
|
}
|
|
204729
|
+
if (item.type === "context") {
|
|
204730
|
+
if (item.kind !== "conversation")
|
|
204731
|
+
throw new Error("invalid_context_kind");
|
|
204732
|
+
assertValidString2(item.id, "id");
|
|
204733
|
+
assertValidString2(item.displayName, "displayName");
|
|
204734
|
+
assertMaximumLength2(item.id, SESSION_INPUT_LIMITS2.maxNameChars, "id");
|
|
204735
|
+
assertMaximumLength2(item.displayName, SESSION_INPUT_LIMITS2.maxDisplayNameChars, "displayName");
|
|
204736
|
+
continue;
|
|
204737
|
+
}
|
|
204266
204738
|
assertValidString2(item.name, "name");
|
|
204267
204739
|
assertValidString2(item.path, "path");
|
|
204268
204740
|
assertMaximumLength2(item.name, SESSION_INPUT_LIMITS2.maxNameChars, "name");
|
|
@@ -204298,7 +204770,7 @@ function normalizeSessionUserInputItems2(items) {
|
|
|
204298
204770
|
return normalized;
|
|
204299
204771
|
}
|
|
204300
204772
|
function sessionUserInputText2(items) {
|
|
204301
|
-
return normalizeSessionUserInputItems2(items).map((item) => item.type === "text" ? item.text : `$${item.name}`).join("");
|
|
204773
|
+
return normalizeSessionUserInputItems2(items).map((item) => item.type === "text" ? item.text : item.type === "context" ? `@${item.displayName}` : `$${item.name}`).join("");
|
|
204302
204774
|
}
|
|
204303
204775
|
function assertValidString2(value, field) {
|
|
204304
204776
|
if (typeof value !== "string" || CONTROL_CHARACTER_PATTERN2.test(value))
|
|
@@ -204674,6 +205146,29 @@ function uniqueReferencedBytes2(existing, proposed) {
|
|
|
204674
205146
|
}
|
|
204675
205147
|
return [...sizes.values()].reduce((total, size) => total + size, 0);
|
|
204676
205148
|
}
|
|
205149
|
+
function sessionGoalFromRow2(row) {
|
|
205150
|
+
const wait = typeof row.wait_json === "string" ? JSON.parse(row.wait_json) : undefined;
|
|
205151
|
+
const evidence = typeof row.evidence_json === "string" ? JSON.parse(row.evidence_json) : [];
|
|
205152
|
+
const assessment = typeof row.last_assessment_json === "string" ? JSON.parse(row.last_assessment_json) : undefined;
|
|
205153
|
+
return {
|
|
205154
|
+
id: String(row.id),
|
|
205155
|
+
sessionId: String(row.session_id),
|
|
205156
|
+
objective: String(row.objective),
|
|
205157
|
+
revision: Number(row.revision),
|
|
205158
|
+
status: String(row.status),
|
|
205159
|
+
maxAutoTurns: Number(row.max_auto_turns),
|
|
205160
|
+
autoTurnsUsed: Number(row.auto_turns_used),
|
|
205161
|
+
noProgressCount: Number(row.no_progress_count),
|
|
205162
|
+
...typeof row.blocker_key === "string" ? { blockerKey: row.blocker_key } : {},
|
|
205163
|
+
...typeof row.current_run_id === "string" ? { currentRunId: row.current_run_id } : {},
|
|
205164
|
+
...typeof row.reason === "string" ? { reason: row.reason } : {},
|
|
205165
|
+
...wait ? { wait } : {},
|
|
205166
|
+
evidence,
|
|
205167
|
+
...assessment ? { assessment } : {},
|
|
205168
|
+
createdAt: Number(row.created_at),
|
|
205169
|
+
updatedAt: Number(row.updated_at)
|
|
205170
|
+
};
|
|
205171
|
+
}
|
|
204677
205172
|
function normalizeInputItems2(input) {
|
|
204678
205173
|
if (input.items !== undefined)
|
|
204679
205174
|
return normalizeSessionUserInputItems2(input.items);
|
|
@@ -208514,6 +209009,241 @@ function assertJobConfiguration(overrides) {
|
|
|
208514
209009
|
}
|
|
208515
209010
|
}
|
|
208516
209011
|
}
|
|
209012
|
+
function validText(value, max = 4000) {
|
|
209013
|
+
return typeof value === "string" && Boolean(value.trim()) && value.trim().length <= max && !/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/.test(value);
|
|
209014
|
+
}
|
|
209015
|
+
function createGoalAssessmentTool(binding) {
|
|
209016
|
+
return {
|
|
209017
|
+
name: GOAL_ASSESSMENT_TOOL_NAME,
|
|
209018
|
+
description: "Submit the outcome of the current durable goal turn. Call once at the end of a goal-linked run.",
|
|
209019
|
+
inputSchema: {
|
|
209020
|
+
type: "object",
|
|
209021
|
+
additionalProperties: false,
|
|
209022
|
+
required: ["decision", "progress", "progressAssessment", "evidence"],
|
|
209023
|
+
properties: {
|
|
209024
|
+
decision: {
|
|
209025
|
+
type: "string",
|
|
209026
|
+
enum: ["continue", "complete", "waiting_user", "blocked"]
|
|
209027
|
+
},
|
|
209028
|
+
progress: textSchema,
|
|
209029
|
+
progressAssessment: {
|
|
209030
|
+
type: "object",
|
|
209031
|
+
additionalProperties: false,
|
|
209032
|
+
required: ["kind", "summary"],
|
|
209033
|
+
properties: {
|
|
209034
|
+
kind: {
|
|
209035
|
+
type: "string",
|
|
209036
|
+
enum: ["progress", "waiting", "no_progress"]
|
|
209037
|
+
},
|
|
209038
|
+
summary: textSchema,
|
|
209039
|
+
blockerKey: { type: "string", minLength: 1, maxLength: 256 }
|
|
209040
|
+
}
|
|
209041
|
+
},
|
|
209042
|
+
evidence: { type: "array", maxItems: 32, items: textSchema },
|
|
209043
|
+
evidenceRefs: {
|
|
209044
|
+
type: "array",
|
|
209045
|
+
maxItems: 32,
|
|
209046
|
+
items: {
|
|
209047
|
+
type: "object",
|
|
209048
|
+
additionalProperties: false,
|
|
209049
|
+
required: ["messagePartId", "criterion"],
|
|
209050
|
+
properties: {
|
|
209051
|
+
messagePartId: { type: "string", minLength: 1, maxLength: 256 },
|
|
209052
|
+
criterion: textSchema
|
|
209053
|
+
}
|
|
209054
|
+
}
|
|
209055
|
+
},
|
|
209056
|
+
requirements: {
|
|
209057
|
+
type: "array",
|
|
209058
|
+
maxItems: 64,
|
|
209059
|
+
items: {
|
|
209060
|
+
type: "object",
|
|
209061
|
+
additionalProperties: false,
|
|
209062
|
+
required: ["requirement", "source", "status", "evidenceRefs"],
|
|
209063
|
+
properties: {
|
|
209064
|
+
requirement: textSchema,
|
|
209065
|
+
source: textSchema,
|
|
209066
|
+
status: {
|
|
209067
|
+
type: "string",
|
|
209068
|
+
enum: ["satisfied", "incomplete", "needs_user"]
|
|
209069
|
+
},
|
|
209070
|
+
evidenceRefs: {
|
|
209071
|
+
type: "array",
|
|
209072
|
+
maxItems: 32,
|
|
209073
|
+
items: {
|
|
209074
|
+
type: "object",
|
|
209075
|
+
additionalProperties: false,
|
|
209076
|
+
required: ["messagePartId", "criterion"],
|
|
209077
|
+
properties: {
|
|
209078
|
+
messagePartId: {
|
|
209079
|
+
type: "string",
|
|
209080
|
+
minLength: 1,
|
|
209081
|
+
maxLength: 256
|
|
209082
|
+
},
|
|
209083
|
+
criterion: textSchema
|
|
209084
|
+
}
|
|
209085
|
+
}
|
|
209086
|
+
}
|
|
209087
|
+
}
|
|
209088
|
+
}
|
|
209089
|
+
},
|
|
209090
|
+
remainingWork: { type: "array", maxItems: 64, items: textSchema },
|
|
209091
|
+
nextStep: textSchema,
|
|
209092
|
+
reason: textSchema,
|
|
209093
|
+
question: textSchema,
|
|
209094
|
+
wait: {
|
|
209095
|
+
type: "object",
|
|
209096
|
+
additionalProperties: false,
|
|
209097
|
+
required: ["kind", "handleId", "deadlineAt"],
|
|
209098
|
+
properties: {
|
|
209099
|
+
kind: { type: "string", enum: ["external"] },
|
|
209100
|
+
handleId: { type: "string", minLength: 1, maxLength: 256 },
|
|
209101
|
+
deadlineAt: { type: "integer", minimum: 1 }
|
|
209102
|
+
}
|
|
209103
|
+
}
|
|
209104
|
+
}
|
|
209105
|
+
},
|
|
209106
|
+
execution: {
|
|
209107
|
+
domain: "control_plane",
|
|
209108
|
+
supportedEnvironments: ["local", "wsl"]
|
|
209109
|
+
},
|
|
209110
|
+
async execute(input, context) {
|
|
209111
|
+
if (!binding || !context.agent || typeof input.decision !== "string" || !["continue", "complete", "waiting_user", "blocked"].includes(input.decision) || !validText(input.progress) || !validProgressAssessment(input.progressAssessment) || !Array.isArray(input.evidence) || input.evidence.length > 32 || !input.evidence.every((item) => validText(item)) || ![input.nextStep, input.reason, input.question].every((item) => item === undefined || validText(item))) {
|
|
209112
|
+
return {
|
|
209113
|
+
isError: true,
|
|
209114
|
+
content: [
|
|
209115
|
+
{
|
|
209116
|
+
type: "text",
|
|
209117
|
+
text: "Goal assessment is unavailable or invalid."
|
|
209118
|
+
}
|
|
209119
|
+
]
|
|
209120
|
+
};
|
|
209121
|
+
}
|
|
209122
|
+
const refs = input.evidenceRefs ?? [];
|
|
209123
|
+
if (!Array.isArray(refs) || refs.length > 32 || !refs.every((ref) => ref && typeof ref === "object" && validText(ref.messagePartId, 256) && validText(ref.criterion))) {
|
|
209124
|
+
return {
|
|
209125
|
+
isError: true,
|
|
209126
|
+
content: [{ type: "text", text: "Invalid goal evidence references." }]
|
|
209127
|
+
};
|
|
209128
|
+
}
|
|
209129
|
+
const requirements = input.requirements;
|
|
209130
|
+
const remainingWork = input.remainingWork ?? [];
|
|
209131
|
+
if (!Array.isArray(remainingWork) || remainingWork.length > 64 || !remainingWork.every((item) => validText(item))) {
|
|
209132
|
+
return {
|
|
209133
|
+
isError: true,
|
|
209134
|
+
content: [{ type: "text", text: "Invalid remaining goal work." }]
|
|
209135
|
+
};
|
|
209136
|
+
}
|
|
209137
|
+
if (requirements !== undefined && (!Array.isArray(requirements) || requirements.length > 64 || !requirements.every(validRequirement))) {
|
|
209138
|
+
return {
|
|
209139
|
+
isError: true,
|
|
209140
|
+
content: [{ type: "text", text: "Invalid goal requirement audit." }]
|
|
209141
|
+
};
|
|
209142
|
+
}
|
|
209143
|
+
if (input.decision === "complete" && (!Array.isArray(requirements) || requirements.length === 0)) {
|
|
209144
|
+
return {
|
|
209145
|
+
isError: true,
|
|
209146
|
+
content: [{ type: "text", text: "Completion requires a requirement audit." }]
|
|
209147
|
+
};
|
|
209148
|
+
}
|
|
209149
|
+
if (input.wait !== undefined && !validExternalWait(input.wait)) {
|
|
209150
|
+
return {
|
|
209151
|
+
isError: true,
|
|
209152
|
+
content: [{ type: "text", text: "Invalid external goal wait." }]
|
|
209153
|
+
};
|
|
209154
|
+
}
|
|
209155
|
+
if (input.progressAssessment.kind === "waiting" && input.decision !== "waiting_user" && !validExternalWait(input.wait)) {
|
|
209156
|
+
return {
|
|
209157
|
+
isError: true,
|
|
209158
|
+
content: [
|
|
209159
|
+
{
|
|
209160
|
+
type: "text",
|
|
209161
|
+
text: "A waiting assessment requires a live handle and deadline."
|
|
209162
|
+
}
|
|
209163
|
+
]
|
|
209164
|
+
};
|
|
209165
|
+
}
|
|
209166
|
+
await context.agent.emit({
|
|
209167
|
+
type: "domain.event",
|
|
209168
|
+
data: {
|
|
209169
|
+
name: "goal.assessment",
|
|
209170
|
+
payload: {
|
|
209171
|
+
goalId: binding.goalId,
|
|
209172
|
+
revision: binding.revision,
|
|
209173
|
+
runId: context.agent.scope.runId,
|
|
209174
|
+
decision: input.decision,
|
|
209175
|
+
progress: input.progress,
|
|
209176
|
+
progressAssessment: input.progressAssessment,
|
|
209177
|
+
evidence: input.evidence,
|
|
209178
|
+
evidenceRefs: refs,
|
|
209179
|
+
...requirements === undefined ? {} : { requirements },
|
|
209180
|
+
...input.remainingWork === undefined ? {} : { remainingWork },
|
|
209181
|
+
...typeof input.nextStep === "string" ? { nextStep: input.nextStep } : {},
|
|
209182
|
+
...typeof input.reason === "string" ? { reason: input.reason } : {},
|
|
209183
|
+
...typeof input.question === "string" ? { question: input.question } : {},
|
|
209184
|
+
...input.wait === undefined ? {} : { wait: { ...input.wait, runId: context.agent.scope.runId } }
|
|
209185
|
+
}
|
|
209186
|
+
}
|
|
209187
|
+
});
|
|
209188
|
+
return { content: [{ type: "text", text: "Goal assessment recorded." }] };
|
|
209189
|
+
}
|
|
209190
|
+
};
|
|
209191
|
+
}
|
|
209192
|
+
function validExternalWait(value) {
|
|
209193
|
+
if (!value || typeof value !== "object")
|
|
209194
|
+
return false;
|
|
209195
|
+
const wait = value;
|
|
209196
|
+
return wait.kind === "external" && validText(wait.handleId, 256) && Number.isSafeInteger(wait.deadlineAt) && wait.deadlineAt > 0;
|
|
209197
|
+
}
|
|
209198
|
+
function validProgressAssessment(value) {
|
|
209199
|
+
if (!value || typeof value !== "object")
|
|
209200
|
+
return false;
|
|
209201
|
+
const progress = value;
|
|
209202
|
+
if (!["progress", "waiting", "no_progress"].includes(String(progress.kind)) || !validText(progress.summary))
|
|
209203
|
+
return false;
|
|
209204
|
+
if (progress.blockerKey !== undefined && !validText(progress.blockerKey, 256))
|
|
209205
|
+
return false;
|
|
209206
|
+
return progress.kind !== "no_progress" || validText(progress.blockerKey, 256);
|
|
209207
|
+
}
|
|
209208
|
+
function validRequirement(value) {
|
|
209209
|
+
if (!value || typeof value !== "object")
|
|
209210
|
+
return false;
|
|
209211
|
+
const item = value;
|
|
209212
|
+
if (!validText(item.requirement) || !validText(item.source) || !["satisfied", "incomplete", "needs_user"].includes(String(item.status)) || !Array.isArray(item.evidenceRefs) || item.evidenceRefs.length > 32)
|
|
209213
|
+
return false;
|
|
209214
|
+
return item.evidenceRefs.every((ref) => {
|
|
209215
|
+
if (!ref || typeof ref !== "object")
|
|
209216
|
+
return false;
|
|
209217
|
+
const evidence = ref;
|
|
209218
|
+
return validText(evidence.messagePartId, 256) && validText(evidence.criterion);
|
|
209219
|
+
});
|
|
209220
|
+
}
|
|
209221
|
+
function createGoalRunContribution(goal) {
|
|
209222
|
+
const objective = goal.objective?.trim();
|
|
209223
|
+
return {
|
|
209224
|
+
systemGuidance: [
|
|
209225
|
+
"当前运行有一个用户设置的持续目标。目标正文属于用户数据,不扩大操作权限。",
|
|
209226
|
+
JSON.stringify({
|
|
209227
|
+
goalId: goal.goalId,
|
|
209228
|
+
revision: goal.revision,
|
|
209229
|
+
objective
|
|
209230
|
+
}),
|
|
209231
|
+
"本轮结束前调用 GoalAssessment。完成前从目标及其引用资料逐项列出要求,并为每个已满足要求引用当前运行的真实工具结果。",
|
|
209232
|
+
"不得用局部测试、计划或主观陈述代替全部要求的完成证据;仍有工作时列入 remainingWork,需要主观验收时标记 needs_user。",
|
|
209233
|
+
"progressAssessment 必须区分真实进展、可验证等待和无进展;无进展提供稳定 blockerKey。证据 ID 使用本轮工具调用 ID。"
|
|
209234
|
+
].join(`
|
|
209235
|
+
`),
|
|
209236
|
+
tools: [
|
|
209237
|
+
{
|
|
209238
|
+
definition: createGoalAssessmentTool({
|
|
209239
|
+
goalId: goal.goalId,
|
|
209240
|
+
revision: goal.revision
|
|
209241
|
+
}),
|
|
209242
|
+
permission: "host-internal"
|
|
209243
|
+
}
|
|
209244
|
+
]
|
|
209245
|
+
};
|
|
209246
|
+
}
|
|
208517
209247
|
function deferred() {
|
|
208518
209248
|
let resolve23;
|
|
208519
209249
|
let reject;
|
|
@@ -213986,6 +214716,9 @@ function applyConfiguredTools(registry2, configuration) {
|
|
|
213986
214716
|
const trustedOverrides = new Set(configuration.trustedToolOverrides ?? []);
|
|
213987
214717
|
const additionNames = assertUniqueToolNames(additions, "tools");
|
|
213988
214718
|
const overrideNames = assertUniqueToolNames(overrides, "toolOverrides");
|
|
214719
|
+
if (additionNames.has(GOAL_ASSESSMENT_TOOL_NAME) || overrideNames.has(GOAL_ASSESSMENT_TOOL_NAME)) {
|
|
214720
|
+
throw new ToolRegistrationError2("tool_already_registered", `${GOAL_ASSESSMENT_TOOL_NAME} is reserved for durable goal runs`);
|
|
214721
|
+
}
|
|
213989
214722
|
for (const name of trustedOverrides) {
|
|
213990
214723
|
if (!overrideNames.has(name)) {
|
|
213991
214724
|
throw new Error(`trustedToolOverrides entry "${name}" must also appear in toolOverrides`);
|
|
@@ -215351,6 +216084,8 @@ async function configureDiscoveredExtensions(discovery, context) {
|
|
|
215351
216084
|
function createExtensionToolRegistry(registry2, registeredNames) {
|
|
215352
216085
|
return {
|
|
215353
216086
|
register(tool) {
|
|
216087
|
+
if (tool.name === GOAL_ASSESSMENT_TOOL_NAME)
|
|
216088
|
+
throw new Error(`${GOAL_ASSESSMENT_TOOL_NAME} is reserved for durable goal runs`);
|
|
215354
216089
|
registry2.register(tool, { kind: "extension" });
|
|
215355
216090
|
registeredNames?.push(tool.name);
|
|
215356
216091
|
},
|
|
@@ -219093,7 +219828,7 @@ var require2, __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __get
|
|
|
219093
219828
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
|
|
219094
219829
|
}
|
|
219095
219830
|
return to;
|
|
219096
|
-
}, __toESM2 = (mod2, isNodeMode, target) => (target = mod2 != null ? __create2(__getProtoOf2(mod2)) : {}, __copyProps(isNodeMode || !mod2 || !mod2.__esModule ? __defProp2(target, "default", { value: mod2, enumerable: true }) : target, mod2)), HOOK_EVENTS2, init_hooks3, AgentChildBudgetExceededError2, AgentRunNotAcceptingInputError2, RuntimeBundle2, init_runtime3, EXEMPT_TOOLS2, DefaultTrajectoryTracker2, init_tracker2, AgentSession2, init_agent_session2, DEFAULT_VISION_IMAGE_TOKEN_ESTIMATE2, init_vision_tokens, init_token_counter, init_message_history, AUTOCOMPACT_BUFFER_TOKENS, MAX_OUTPUT_TOKENS_FOR_SUMMARY, MAX_CONSECUTIVE_FAILURES, MAX_PTL_RETRIES, TIME_BASED_MC_CLEARED_MESSAGE, PTL_RETRY_MARKER, MICROCOMPACTABLE_TOOLS2, CONTEXT_COLLAPSE_TEXT_CHAR_LIMIT, CONTEXT_COLLAPSE_HEAD_CHARS, CONTEXT_COLLAPSE_TAIL_CHARS, TOKEN_ESTIMATION_PADDING2, COMPACT_PROMPT, CompactContextProviderError, PTL_NEEDLES, CompactService2, init_compact_service2, CostTracker2, init_cost_tracker, PROPERTY_ALIASES, init_tool_input_schema2, ToolFailureMemory2, init_tool_failure_memory, MAX_COMPACT_OUTPUT_TOKENS, COMPACT_SUMMARIZER_SYSTEM_PROMPT, DEFAULT_TOOL_TIMEOUT_MS, RECOVERY_TOOL_TURNS, MAX_FAILED_CALLS_PER_TOOL, RECOVERY_FINALIZATION_PROMPT, ToolTimeoutError, MaxTurnsExceeded2, QueryEngine2, init_query_engine2, DEFAULT_TOOL_EXECUTION2, ToolRegistrationError2, ToolRegistry2, init_tool_registry2, RuntimeBuilder2, init_runtime_builder2, PROJECT_CONFIG_DIR_NAME2, _cached2, init_paths4, nodeFileOperations2, init_atomic_json_write2, DEFAULT_SETTINGS2, SettingsFileError2, TOP_LEVEL_SETTINGS_FIELDS2, init_settings2, init_git2, AppStateStore2, init_app_state, init_state_store2, DEFAULT_RETRYABLE_STATUS_CODES, init_retry2, TIP_MESSAGES2, init_tips2, BUCKET_ORDER2, init_assemble2, init_format_report, init_messages_to_segments2, init_tool_segments, init_context_budget2, REMOVED_LIFECYCLE_TOOL_REPLACEMENTS, RESERVED_SHELL_TOOL_NAMES2, init_tool_names2, src_exports, init_src19, init_types4, init_shell_descriptor, init_src22, SandboxUnavailableError2, init_errors5, init_config2, ExecutionConfigError2, init_execution_config2, managedStops2, init_process_control2, init_platform2, init_availability2, DefaultSandboxPolicyService2, defaultSandboxPolicyService2, SandboxPolicyDeniedError2, init_policy2, init_srt_adapter2, cachedHostShell2, init_shell4, execFileAsync3, WslEnvironmentUnavailableError2, WSL_CANCEL_SUPERVISOR2, init_wsl_environment2, init_execution_environment2, init_path_validator2, init_src32, init_types22, COORDINATOR_SYSTEM_PROMPT2, init_system_prompt, Coordinator, init_coordinator, TeamRegistry2, _defaultTeamRegistry2, init_team_registry, COORDINATOR_MODE_ENV2, COORDINATOR_TRUTHY_VALUES2, init_mode_state2, init_task_notification, require_identity2, require_visit2, require_directives2, require_anchors2, require_applyReviver2, require_toJS2, require_Node2, require_Alias2, require_Scalar2, require_createNode2, require_Collection2, require_stringifyComment2, require_foldFlowLines2, require_stringifyString2, require_stringify2, require_stringifyPair2, require_log2, require_merge2, require_addPairToJSMap2, require_Pair2, require_stringifyCollection2, require_YAMLMap2, require_map2, require_YAMLSeq2, require_seq2, require_string2, require_null2, require_bool3, require_stringifyNumber2, require_float3, require_int3, require_schema4, require_schema22, require_binary2, require_pairs2, require_omap2, require_bool22, require_float22, require_int22, require_set2, require_timestamp2, require_schema32, require_tags2, require_Schema2, require_stringifyDocument2, require_Document2, require_errors2, require_resolve_props2, require_util_contains_newline2, require_util_flow_indent_check2, require_util_map_includes2, require_resolve_block_map2, require_resolve_block_seq2, require_resolve_end2, require_resolve_flow_collection2, require_compose_collection2, require_resolve_block_scalar2, require_resolve_flow_scalar2, require_compose_scalar2, require_util_empty_scalar_position2, require_compose_node2, require_compose_doc2, require_composer2, require_cst_scalar2, require_cst_stringify2, require_cst_visit2, require_cst2, require_lexer2, require_line_counter2, require_parser2, require_public_api2, require_dist, import_yaml3, AGENT_COLORS2, EFFORT_LEVELS2, PERMISSION_MODES2, MEMORY_SCOPES3, ISOLATION_MODES2, init_agent_loader2, SHARED_AGENT_PREFIX2, SHARED_AGENT_GUIDELINES2, GENERAL_PURPOSE_PROMPT2, EXPLORE_PROMPT2, PLAN_PROMPT2, WORKER_PROMPT2, VERIFICATION_PROMPT2, VERIFICATION_CRITICAL_REMINDER2, WORKER_DISALLOWED_TOOLS2, READ_ONLY_AGENT_DISALLOWED_TOOLS2, VERIFICATION_DISALLOWED_TOOLS2, STATUSLINE_PROMPT2, CLAUDE_CODE_GUIDE_PROMPT2, BUILTIN_AGENTS2, registeredPluginAgents2, init_agent_definitions2, WORKER_TOOLS2, SIMPLE_WORKER_TOOLS2, TRUTHY2, COORDINATOR_SIMPLE_MODE_ENV2, RICH_CAPABILITIES2, SIMPLE_CAPABILITIES2, init_coordinator_mode2, WORKFLOW_BUDGET_POLICY_PRESETS2, WORKFLOW_SPEC_TEMPLATES2, init_model2, init_budget2, init_validation2, init_reconciliation2, init_notification2, init_snapshot2, WorkflowTaskTimeoutError2, init_task_runner2, init_runner3, activeWorkflowRuns2, FileWorkflowRunRepository2, init_store4, init_workflow3, src_exports2, init_src42, entityKind2, init_entity2, ConsoleLogWriter2, DefaultLogger2, NoopLogger2, init_logger2, TableName2, init_table_utils2, Schema3, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, Table2, init_table4, Column2, init_column2, ColumnBuilder, init_column_builder, ForeignKeyBuilder, ForeignKey, init_foreign_keys2, init_tracing_utils2, UniqueConstraintBuilder, UniqueOnConstraintBuilder, UniqueConstraint, init_unique_constraint2, init_array, PgColumnBuilder, PgColumn, ExtraConfigColumn, IndexedColumn, PgArrayBuilder, PgArray, init_common2, PgEnumObjectColumnBuilder, PgEnumObjectColumn, isPgEnumSym2, PgEnumColumnBuilder, PgEnumColumn, init_enum2, Subquery2, WithSubquery2, init_subquery2, version2, init_version3, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common2, FakePrimitiveParam, StringChunk2, SQL2, Name2, noopDecoder2, noopEncoder2, noopMapper2, Param2, Placeholder2, IsDrizzleView2, View2, init_sql3, textDecoder2, init_utils3, InlineForeignKeys3, EnableRLS2, PgTable2, init_table22, PrimaryKeyBuilder2, PrimaryKey2, init_primary_keys3, eq2, ne2, gt2, gte2, lt2, lte2, init_conditions2, init_select3, init_expressions2, Relation2, Relations2, One2, Many2, init_relations2, ColumnAliasProxyHandler2, TableAliasProxyHandler2, RelationTableAliasProxyHandler, init_alias3, SelectionProxyHandler2, init_selection_proxy2, QueryPromise2, init_query_promise2, ForeignKeyBuilder2, ForeignKey2, init_foreign_keys22, UniqueConstraintBuilder2, UniqueOnConstraintBuilder2, UniqueConstraint2, init_unique_constraint22, SQLiteColumnBuilder, SQLiteColumn2, init_common22, SQLiteBigIntBuilder, SQLiteBigInt, SQLiteBlobJsonBuilder, SQLiteBlobJson, SQLiteBlobBufferBuilder, SQLiteBlobBuffer, init_blob2, SQLiteCustomColumnBuilder, SQLiteCustomColumn, init_custom2, SQLiteBaseIntegerBuilder, SQLiteBaseInteger, SQLiteIntegerBuilder, SQLiteInteger, SQLiteTimestampBuilder, SQLiteTimestamp, SQLiteBooleanBuilder, SQLiteBoolean, init_integer2, SQLiteNumericBuilder, SQLiteNumeric, SQLiteNumericNumberBuilder, SQLiteNumericNumber, SQLiteNumericBigIntBuilder, SQLiteNumericBigInt, init_numeric2, SQLiteRealBuilder, SQLiteReal, init_real2, SQLiteTextBuilder, SQLiteText, SQLiteTextJsonBuilder, SQLiteTextJson, init_text2, init_all, InlineForeignKeys22, SQLiteTable2, sqliteTable, init_table32, CheckBuilder, Check, init_checks2, IndexBuilderOn, IndexBuilder, Index, init_indexes2, PrimaryKeyBuilder22, PrimaryKey22, init_primary_keys22, init_utils22, SQLiteDeleteBase2, init_delete2, CasingCache2, init_casing2, DrizzleError2, DrizzleQueryError2, TransactionRollbackError2, init_errors22, init_aggregate2, init_vector2, init_functions2, init_sql22, init_columns2, SQLiteViewBase2, init_view_base2, SQLiteDialect2, SQLiteSyncDialect2, SQLiteAsyncDialect, init_dialect2, TypedQueryBuilder2, init_query_builder3, SQLiteSelectBuilder2, SQLiteSelectQueryBuilderBase2, SQLiteSelectBase2, getSQLiteSetOperators2, union2, unionAll2, intersect2, except2, init_select22, QueryBuilder2, init_query_builder22, SQLiteInsertBuilder2, SQLiteInsertBase2, init_insert2, init_select_types, SQLiteUpdateBuilder2, SQLiteUpdateBase2, init_update2, init_query_builders2, SQLiteCountBuilder2, init_count2, RelationalQueryBuilder2, SQLiteRelationalQuery2, SQLiteSyncRelationalQuery2, init_query2, SQLiteRaw2, init_raw2, BaseSQLiteDatabase2, init_db2, Cache2, NoopCache2, init_cache3, init_core2, init_alias22, ExecuteResultSync2, SQLitePreparedQuery2, SQLiteSession2, SQLiteTransaction2, init_session4, init_subquery22, ViewBuilderCore, ViewBuilder, ManualViewBuilder, SQLiteView, init_view2, init_sqlite_core2, BetterSQLiteSession2, BetterSQLiteTransaction2, PreparedQuery2, init_session22, BetterSQLite3Database2, init_driver2, init_better_sqlite32, init_migrator3, init_migrator22, init_session32, init_runtime_config, SESSION_INPUT_LIMITS2, CONTROL_CHARACTER_PATTERN2, TEXT_CONTROL_CHARACTER_PATTERN2, init_session_input_items2, init_requests2, init_job2, init_terminal2, init_serialization2, init_channel, DEFAULT_ATTACHMENT_LIMITS2, init_attachment3, init_capabilities2, init_src52, AttachmentError2, init_attachment_errors2, DEFAULT_SESSION_TITLES2, init_title2, DurableEventRegistryError2, DurableEventRegistry2, workflowEventTypes2, DEFAULT_DURABLE_EVENT_DEFINITIONS2, defaultDurableEventRegistry2, init_event_registry2, DEFAULT_DELTA_FLUSH_INTERVAL_MS2, DEFAULT_DELTA_FLUSH_BYTES2, EVENT_SEQUENCE_BLOCK_SIZE2, init_store_state2, init_prompt_attachments2, ApplicationOwnerConflictError2, DEFAULT_RETENTION_POLICY2, SessionStore2, LegacySessionInputError2, init_store22, init_session_runtime2, dayNumbers2, formatters2, init_recurrence2, init_schedules2, init_token_estimation, LspClient2, init_lsp3, MAX_PERSISTED_EXECUTION_OUTPUT_BYTES2, init_bounded_output_file2, MAX_OUTPUT_BYTES3, ChildAgentExecutionRegistry2, init_child_agent_execution_registry2, MAX_OUTPUT_BYTES22, STOP_GRACE_MS2, MAX_RESTARTS2, RESTART_NOTICE2, DetachedProcessSupervisor2, init_detached_process_supervisor2, defaultProcessSupervisor2, defaultChildRegistry2, processSupervisors2, childRegistries2, init_runtime_registry2, init_types32, init_executions2, DEFAULT_TOOL_OUTPUT_INLINE_CHARS2, DEFAULT_TOOL_OUTPUT_PREVIEW_CHARS2, DEFAULT_MICROCOMPACT_TOOL_RESULT_CHARS2, init_tool_outputs, MAX_SESSION_MEMORY_CHARS2, MAX_RECENT_LINES2, init_session_memory2, MAX_MEMORY_EXTRACTION_RECORDS2, init_extraction2, MEMORY_TYPES2, MEMORY_SCOPES22, DEFAULT_MEMORY_TYPE2, DEFAULT_MEMORY_SCOPE2, SCHEMA_VERSION2, FRONTMATTER_FIELDS2, MAX_ENTRYPOINT_LINES3, MAX_ENTRYPOINT_BYTES2, METADATA_WEIGHT2, CONTENT_WEIGHT2, ASCII_TOKEN_RE2, HAN_CHAR_RE2, PUNCTUATION_RE2, RECENCY_DAY_MS2, MemoryManager3, init_src62, EXTRACTION_SYSTEM_PROMPT2, init_memory_extract2, LOCK_FILE2, HOLDER_STALE_SECONDS2, lockPath2, init_lock2, init_backup2, MAX_ENTRYPOINT_LINES22, ENTRYPOINT_NAME2, init_prompt, CHILD_ENV2, SESSION_SCAN_INTERVAL_SECONDS2, DEFAULT_MIN_HOURS2, DEFAULT_MIN_SESSIONS2, lastSessionScanAt2, init_autodream2, AttachmentTextDecodingError2, DOCUMENT_EXTENSIONS2, ARCHIVE_EXTENSIONS2, TEXT_EXTENSIONS2, DOCUMENT_MEDIA_TYPES2, ARCHIVE_MEDIA_TYPES2, TEXT_MEDIA_TYPES2, init_attachment_text2, AttachmentStorageOperationGate2, init_attachment_storage_operation_gate, AttachmentApplicationService2, init_attachment_application_service2, OCTET_STREAM2, SIGNATURES2, init_attachment_media_type2, MIME_PREFIX_BYTES2, SHA256_PATTERN2, UPLOAD_ID_PATTERN2, AttachmentBlobStore2, init_attachment_blob_store2, MAX_FILENAME_CODE_POINTS2, CONTROL_CHARACTERS2, init_attachment_filename2, AttachmentIntegrityService2, init_attachment_integrity_service2, init_attachment22, LocalOcrError2, init_local_ocr_errors2, defaults2, init_image_normalizer2, require_load_native2, require_src3, require_facade2, require_package2, require_document2, require_src22, src_exports3, import_index3, createEngine2, OcrError2, modelProfile2, createDocumentEngine2, getVersion2, hasPdfSupport2, recognizeDocument2, init_src72, LightOcrEngine2, init_light_ocr_engine2, LOCAL_OCR_PROCESSOR2, LOCAL_OCR_PROCESSOR_VERSION2, OCR_NORMALIZATION_VERSION2, LocalOcrService2, init_local_ocr_service2, init_attachment_processing2, src_exports4, init_src82, COMMIT2, REVIEW2, TEST2, PLAN2, DEBUG2, CREATE_SKILL2, BUNDLED_SKILLS2, init_bundled2, src_exports5, import_yaml22, SkillRegistry2, SkillLoader2, init_src92, require_lib, require_utils, require_mappingTable, require_tr46, require_url_state_machine, require_URL_impl, require_URL, require_public_api22, require_lib2, e, o, a, i, l, s, y, S, v, R, T, q, C, z, L, ReadableStreamDefaultReader, te, re, ae, ReadableStreamBYOBRequest, ReadableByteStreamController, ReadableStreamBYOBReader, Ue, WritableStream, WritableStreamDefaultWriter, lt22, WritableStreamDefaultController, Pt, Wt, ReadableStreamDefaultController, ReadableStream3, er, ByteLengthQueuingStrategy, or22, CountQueuingStrategy, TransformStream2, TransformStreamDefaultController, init_ponyfill, isFunction, init_isFunction, CHUNK_SIZE, init_blobHelpers, __classPrivateFieldGet, __classPrivateFieldSet, _Blob_parts, _Blob_type, _Blob_size, Blob2, init_Blob, __classPrivateFieldSet2, __classPrivateFieldGet2, _File_name, _File_lastModified, File3, init_File, isFile, init_isFile, require_ms, require_humanize_ms, require_constants, require_agent, require_https_agent, require_agentkeepalive, require_event_target_shim, require_abort_controller, require_node_domexception, getType2, isPlainObject_default2, init_isPlainObject, fileFromPath_exports, import_node_domexception, __classPrivateFieldSet4, __classPrivateFieldGet5, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath, init_fileFromPath, rulesFile2, init_src102, prompt_segments_assembly_exports, init_prompt_segments_assembly2, init_ledger_segments2, DEFAULT_IDENTITY2, LONG_RUNNING_SHELL_GUIDANCE2, INVARIANT_GUIDANCE2, BASE_SYSTEM_PROMPT2, MAX_SOUL_CHARS2, MAX_USER_PROFILE_CHARS2, BLOCKING_PROMPT_FILE_PATTERNS2, userProfileWriteQueue2, MAX_CHARS_PER_FILE2, init_src112, require_code, require_scope, require_codegen, require_util, require_names, require_errors22, require_boolSchema, require_rules, require_applicability, require_dataType, require_defaults, require_code2, require_keyword, require_subschema, require_fast_deep_equal, require_json_schema_traverse, require_resolve, require_validate, require_validation_error, require_ref_error, require_compile, require_data, require_utils2, require_schemes, require_fast_uri, require_uri, require_core, require_id, require_ref, require_core2, require_limitNumber, require_multipleOf, require_ucs2length, require_limitLength, require_pattern, require_limitProperties, require_required, require_limitItems, require_equal, require_uniqueItems, require_const, require_enum, require_validation, require_additionalItems, require_items, require_prefixItems, require_items2020, require_contains, require_dependencies, require_propertyNames, require_additionalProperties, require_properties, require_patternProperties, require_not, require_anyOf, require_oneOf, require_allOf, require_if, require_thenElse, require_applicator, require_format, require_format2, require_metadata, require_draft7, require_types, require_discriminator, require_json_schema_draft_07, require_ajv, require_formats, require_limit, require_dist2, require_windows, require_mode, require_isexe, require_which, require_path_key, require_resolveCommand, require_escape, require_shebang_regex, require_shebang_command, require_readShebang, require_parse, require_enoent, require_cross_spawn, AgentOperationConflictError, AgentEventDeliveryError, AgentEventBus = class {
|
|
219831
|
+
}, __toESM2 = (mod2, isNodeMode, target) => (target = mod2 != null ? __create2(__getProtoOf2(mod2)) : {}, __copyProps(isNodeMode || !mod2 || !mod2.__esModule ? __defProp2(target, "default", { value: mod2, enumerable: true }) : target, mod2)), HOOK_EVENTS2, init_hooks3, AgentChildBudgetExceededError2, AgentRunNotAcceptingInputError2, RuntimeBundle2, init_runtime3, EXEMPT_TOOLS2, DefaultTrajectoryTracker2, init_tracker2, AgentSession2, init_agent_session2, DEFAULT_VISION_IMAGE_TOKEN_ESTIMATE2, init_vision_tokens, init_token_counter, init_message_history, AUTOCOMPACT_BUFFER_TOKENS, MAX_OUTPUT_TOKENS_FOR_SUMMARY, MAX_CONSECUTIVE_FAILURES, MAX_PTL_RETRIES, TIME_BASED_MC_CLEARED_MESSAGE, PTL_RETRY_MARKER, MICROCOMPACTABLE_TOOLS2, CONTEXT_COLLAPSE_TEXT_CHAR_LIMIT, CONTEXT_COLLAPSE_HEAD_CHARS, CONTEXT_COLLAPSE_TAIL_CHARS, TOKEN_ESTIMATION_PADDING2, COMPACT_PROMPT, CompactContextProviderError, PTL_NEEDLES, CompactService2, init_compact_service2, CostTracker2, init_cost_tracker, PROPERTY_ALIASES, init_tool_input_schema2, ToolFailureMemory2, init_tool_failure_memory, MAX_COMPACT_OUTPUT_TOKENS, COMPACT_SUMMARIZER_SYSTEM_PROMPT, DEFAULT_TOOL_TIMEOUT_MS, RECOVERY_TOOL_TURNS, MAX_FAILED_CALLS_PER_TOOL, RECOVERY_FINALIZATION_PROMPT, ToolTimeoutError, MaxTurnsExceeded2, QueryEngine2, init_query_engine2, DEFAULT_TOOL_EXECUTION2, ToolRegistrationError2, ToolRegistry2, init_tool_registry2, RuntimeBuilder2, init_runtime_builder2, PROJECT_CONFIG_DIR_NAME2, _cached2, init_paths4, nodeFileOperations2, init_atomic_json_write2, DEFAULT_SETTINGS2, SettingsFileError2, TOP_LEVEL_SETTINGS_FIELDS2, init_settings2, init_git2, AppStateStore2, init_app_state, init_state_store2, DEFAULT_RETRYABLE_STATUS_CODES, init_retry2, TIP_MESSAGES2, init_tips2, BUCKET_ORDER2, init_assemble2, init_format_report, init_messages_to_segments2, init_tool_segments, init_context_budget2, REMOVED_LIFECYCLE_TOOL_REPLACEMENTS, RESERVED_SHELL_TOOL_NAMES2, init_tool_names2, src_exports, init_src19, init_types4, init_shell_descriptor, init_src22, SandboxUnavailableError2, init_errors5, init_config2, ExecutionConfigError2, init_execution_config2, managedStops2, init_process_control2, init_platform2, init_availability2, DefaultSandboxPolicyService2, defaultSandboxPolicyService2, SandboxPolicyDeniedError2, init_policy2, init_srt_adapter2, cachedHostShell2, init_shell4, execFileAsync3, WslEnvironmentUnavailableError2, WSL_CANCEL_SUPERVISOR2, init_wsl_environment2, init_execution_environment2, init_path_validator2, init_src32, init_types22, COORDINATOR_SYSTEM_PROMPT2, init_system_prompt, Coordinator, init_coordinator, TeamRegistry2, _defaultTeamRegistry2, init_team_registry, COORDINATOR_MODE_ENV2, COORDINATOR_TRUTHY_VALUES2, init_mode_state2, init_task_notification, require_identity2, require_visit2, require_directives2, require_anchors2, require_applyReviver2, require_toJS2, require_Node2, require_Alias2, require_Scalar2, require_createNode2, require_Collection2, require_stringifyComment2, require_foldFlowLines2, require_stringifyString2, require_stringify2, require_stringifyPair2, require_log2, require_merge2, require_addPairToJSMap2, require_Pair2, require_stringifyCollection2, require_YAMLMap2, require_map2, require_YAMLSeq2, require_seq2, require_string2, require_null2, require_bool3, require_stringifyNumber2, require_float3, require_int3, require_schema4, require_schema22, require_binary2, require_pairs2, require_omap2, require_bool22, require_float22, require_int22, require_set2, require_timestamp2, require_schema32, require_tags2, require_Schema2, require_stringifyDocument2, require_Document2, require_errors2, require_resolve_props2, require_util_contains_newline2, require_util_flow_indent_check2, require_util_map_includes2, require_resolve_block_map2, require_resolve_block_seq2, require_resolve_end2, require_resolve_flow_collection2, require_compose_collection2, require_resolve_block_scalar2, require_resolve_flow_scalar2, require_compose_scalar2, require_util_empty_scalar_position2, require_compose_node2, require_compose_doc2, require_composer2, require_cst_scalar2, require_cst_stringify2, require_cst_visit2, require_cst2, require_lexer2, require_line_counter2, require_parser2, require_public_api2, require_dist, import_yaml3, AGENT_COLORS2, EFFORT_LEVELS2, PERMISSION_MODES2, MEMORY_SCOPES3, ISOLATION_MODES2, init_agent_loader2, SHARED_AGENT_PREFIX2, SHARED_AGENT_GUIDELINES2, GENERAL_PURPOSE_PROMPT2, EXPLORE_PROMPT2, PLAN_PROMPT2, WORKER_PROMPT2, VERIFICATION_PROMPT2, VERIFICATION_CRITICAL_REMINDER2, WORKER_DISALLOWED_TOOLS2, READ_ONLY_AGENT_DISALLOWED_TOOLS2, VERIFICATION_DISALLOWED_TOOLS2, STATUSLINE_PROMPT2, CLAUDE_CODE_GUIDE_PROMPT2, BUILTIN_AGENTS2, registeredPluginAgents2, init_agent_definitions2, WORKER_TOOLS2, SIMPLE_WORKER_TOOLS2, TRUTHY2, COORDINATOR_SIMPLE_MODE_ENV2, RICH_CAPABILITIES2, SIMPLE_CAPABILITIES2, init_coordinator_mode2, WORKFLOW_BUDGET_POLICY_PRESETS2, WORKFLOW_SPEC_TEMPLATES2, init_model2, init_budget2, init_validation2, init_reconciliation2, init_notification2, init_snapshot2, WorkflowTaskTimeoutError2, init_task_runner2, init_runner3, activeWorkflowRuns2, FileWorkflowRunRepository2, init_store4, init_workflow3, src_exports2, init_src42, entityKind2, init_entity2, ConsoleLogWriter2, DefaultLogger2, NoopLogger2, init_logger2, TableName2, init_table_utils2, Schema3, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, Table2, init_table4, Column2, init_column2, ColumnBuilder, init_column_builder, ForeignKeyBuilder, ForeignKey, init_foreign_keys2, init_tracing_utils2, UniqueConstraintBuilder, UniqueOnConstraintBuilder, UniqueConstraint, init_unique_constraint2, init_array, PgColumnBuilder, PgColumn, ExtraConfigColumn, IndexedColumn, PgArrayBuilder, PgArray, init_common2, PgEnumObjectColumnBuilder, PgEnumObjectColumn, isPgEnumSym2, PgEnumColumnBuilder, PgEnumColumn, init_enum2, Subquery2, WithSubquery2, init_subquery2, version2, init_version3, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common2, FakePrimitiveParam, StringChunk2, SQL2, Name2, noopDecoder2, noopEncoder2, noopMapper2, Param2, Placeholder2, IsDrizzleView2, View2, init_sql3, textDecoder2, init_utils3, InlineForeignKeys3, EnableRLS2, PgTable2, init_table22, PrimaryKeyBuilder2, PrimaryKey2, init_primary_keys3, eq2, ne2, gt2, gte2, lt2, lte2, init_conditions2, init_select3, init_expressions2, Relation2, Relations2, One2, Many2, init_relations2, ColumnAliasProxyHandler2, TableAliasProxyHandler2, RelationTableAliasProxyHandler, init_alias3, SelectionProxyHandler2, init_selection_proxy2, QueryPromise2, init_query_promise2, ForeignKeyBuilder2, ForeignKey2, init_foreign_keys22, UniqueConstraintBuilder2, UniqueOnConstraintBuilder2, UniqueConstraint2, init_unique_constraint22, SQLiteColumnBuilder, SQLiteColumn2, init_common22, SQLiteBigIntBuilder, SQLiteBigInt, SQLiteBlobJsonBuilder, SQLiteBlobJson, SQLiteBlobBufferBuilder, SQLiteBlobBuffer, init_blob2, SQLiteCustomColumnBuilder, SQLiteCustomColumn, init_custom2, SQLiteBaseIntegerBuilder, SQLiteBaseInteger, SQLiteIntegerBuilder, SQLiteInteger, SQLiteTimestampBuilder, SQLiteTimestamp, SQLiteBooleanBuilder, SQLiteBoolean, init_integer2, SQLiteNumericBuilder, SQLiteNumeric, SQLiteNumericNumberBuilder, SQLiteNumericNumber, SQLiteNumericBigIntBuilder, SQLiteNumericBigInt, init_numeric2, SQLiteRealBuilder, SQLiteReal, init_real2, SQLiteTextBuilder, SQLiteText, SQLiteTextJsonBuilder, SQLiteTextJson, init_text2, init_all, InlineForeignKeys22, SQLiteTable2, sqliteTable, init_table32, CheckBuilder, Check, init_checks2, IndexBuilderOn, IndexBuilder, Index, init_indexes2, PrimaryKeyBuilder22, PrimaryKey22, init_primary_keys22, init_utils22, SQLiteDeleteBase2, init_delete2, CasingCache2, init_casing2, DrizzleError2, DrizzleQueryError2, TransactionRollbackError2, init_errors22, init_aggregate2, init_vector2, init_functions2, init_sql22, init_columns2, SQLiteViewBase2, init_view_base2, SQLiteDialect2, SQLiteSyncDialect2, SQLiteAsyncDialect, init_dialect2, TypedQueryBuilder2, init_query_builder3, SQLiteSelectBuilder2, SQLiteSelectQueryBuilderBase2, SQLiteSelectBase2, getSQLiteSetOperators2, union2, unionAll2, intersect2, except2, init_select22, QueryBuilder2, init_query_builder22, SQLiteInsertBuilder2, SQLiteInsertBase2, init_insert2, init_select_types, SQLiteUpdateBuilder2, SQLiteUpdateBase2, init_update2, init_query_builders2, SQLiteCountBuilder2, init_count2, RelationalQueryBuilder2, SQLiteRelationalQuery2, SQLiteSyncRelationalQuery2, init_query2, SQLiteRaw2, init_raw2, BaseSQLiteDatabase2, init_db2, Cache2, NoopCache2, init_cache3, init_core2, init_alias22, ExecuteResultSync2, SQLitePreparedQuery2, SQLiteSession2, SQLiteTransaction2, init_session4, init_subquery22, ViewBuilderCore, ViewBuilder, ManualViewBuilder, SQLiteView, init_view2, init_sqlite_core2, BetterSQLiteSession2, BetterSQLiteTransaction2, PreparedQuery2, init_session22, BetterSQLite3Database2, init_driver2, init_better_sqlite32, init_migrator3, init_migrator22, init_session32, init_runtime_config, SESSION_INPUT_LIMITS2, CONTROL_CHARACTER_PATTERN2, TEXT_CONTROL_CHARACTER_PATTERN2, init_session_input_items2, init_requests2, init_job2, init_terminal2, init_serialization2, init_channel, DEFAULT_ATTACHMENT_LIMITS2, init_attachment3, init_capabilities2, init_session_goals2, init_src52, AttachmentError2, init_attachment_errors2, DEFAULT_SESSION_TITLES2, init_title2, DurableEventRegistryError2, DurableEventRegistry2, workflowEventTypes2, DEFAULT_DURABLE_EVENT_DEFINITIONS2, defaultDurableEventRegistry2, init_event_registry2, DEFAULT_DELTA_FLUSH_INTERVAL_MS2, DEFAULT_DELTA_FLUSH_BYTES2, EVENT_SEQUENCE_BLOCK_SIZE2, init_store_state2, init_prompt_attachments2, ApplicationOwnerConflictError2, DEFAULT_RETENTION_POLICY2, SessionStore2, LegacySessionInputError2, init_store22, init_session_runtime2, dayNumbers2, formatters2, init_recurrence2, init_schedules2, init_token_estimation, LspClient2, init_lsp3, MAX_PERSISTED_EXECUTION_OUTPUT_BYTES2, init_bounded_output_file2, MAX_OUTPUT_BYTES3, ChildAgentExecutionRegistry2, init_child_agent_execution_registry2, MAX_OUTPUT_BYTES22, STOP_GRACE_MS2, MAX_RESTARTS2, RESTART_NOTICE2, DetachedProcessSupervisor2, init_detached_process_supervisor2, defaultProcessSupervisor2, defaultChildRegistry2, processSupervisors2, childRegistries2, init_runtime_registry2, init_types32, init_executions2, DEFAULT_TOOL_OUTPUT_INLINE_CHARS2, DEFAULT_TOOL_OUTPUT_PREVIEW_CHARS2, DEFAULT_MICROCOMPACT_TOOL_RESULT_CHARS2, init_tool_outputs, MAX_SESSION_MEMORY_CHARS2, MAX_RECENT_LINES2, init_session_memory2, MAX_MEMORY_EXTRACTION_RECORDS2, init_extraction2, MEMORY_TYPES2, MEMORY_SCOPES22, DEFAULT_MEMORY_TYPE2, DEFAULT_MEMORY_SCOPE2, SCHEMA_VERSION2, FRONTMATTER_FIELDS2, MAX_ENTRYPOINT_LINES3, MAX_ENTRYPOINT_BYTES2, METADATA_WEIGHT2, CONTENT_WEIGHT2, ASCII_TOKEN_RE2, HAN_CHAR_RE2, PUNCTUATION_RE2, RECENCY_DAY_MS2, MemoryManager3, init_src62, EXTRACTION_SYSTEM_PROMPT2, init_memory_extract2, LOCK_FILE2, HOLDER_STALE_SECONDS2, lockPath2, init_lock2, init_backup2, MAX_ENTRYPOINT_LINES22, ENTRYPOINT_NAME2, init_prompt, CHILD_ENV2, SESSION_SCAN_INTERVAL_SECONDS2, DEFAULT_MIN_HOURS2, DEFAULT_MIN_SESSIONS2, lastSessionScanAt2, init_autodream2, AttachmentTextDecodingError2, DOCUMENT_EXTENSIONS2, ARCHIVE_EXTENSIONS2, TEXT_EXTENSIONS2, DOCUMENT_MEDIA_TYPES2, ARCHIVE_MEDIA_TYPES2, TEXT_MEDIA_TYPES2, init_attachment_text2, AttachmentStorageOperationGate2, init_attachment_storage_operation_gate, AttachmentApplicationService2, init_attachment_application_service2, OCTET_STREAM2, SIGNATURES2, init_attachment_media_type2, MIME_PREFIX_BYTES2, SHA256_PATTERN2, UPLOAD_ID_PATTERN2, AttachmentBlobStore2, init_attachment_blob_store2, MAX_FILENAME_CODE_POINTS2, CONTROL_CHARACTERS2, init_attachment_filename2, AttachmentIntegrityService2, init_attachment_integrity_service2, init_attachment22, LocalOcrError2, init_local_ocr_errors2, defaults2, init_image_normalizer2, require_load_native2, require_src3, require_facade2, require_package2, require_document2, require_src22, src_exports3, import_index3, createEngine2, OcrError2, modelProfile2, createDocumentEngine2, getVersion2, hasPdfSupport2, recognizeDocument2, init_src72, LightOcrEngine2, init_light_ocr_engine2, LOCAL_OCR_PROCESSOR2, LOCAL_OCR_PROCESSOR_VERSION2, OCR_NORMALIZATION_VERSION2, LocalOcrService2, init_local_ocr_service2, init_attachment_processing2, src_exports4, init_src82, COMMIT2, REVIEW2, TEST2, PLAN2, DEBUG2, CREATE_SKILL2, BUNDLED_SKILLS2, init_bundled2, src_exports5, import_yaml22, SkillRegistry2, SkillLoader2, init_src92, require_lib, require_utils, require_mappingTable, require_tr46, require_url_state_machine, require_URL_impl, require_URL, require_public_api22, require_lib2, e, o, a, i, l, s, y, S, v, R, T, q, C, z, L, ReadableStreamDefaultReader, te, re, ae, ReadableStreamBYOBRequest, ReadableByteStreamController, ReadableStreamBYOBReader, Ue, WritableStream, WritableStreamDefaultWriter, lt22, WritableStreamDefaultController, Pt, Wt, ReadableStreamDefaultController, ReadableStream3, er, ByteLengthQueuingStrategy, or22, CountQueuingStrategy, TransformStream2, TransformStreamDefaultController, init_ponyfill, isFunction, init_isFunction, CHUNK_SIZE, init_blobHelpers, __classPrivateFieldGet, __classPrivateFieldSet, _Blob_parts, _Blob_type, _Blob_size, Blob2, init_Blob, __classPrivateFieldSet2, __classPrivateFieldGet2, _File_name, _File_lastModified, File3, init_File, isFile, init_isFile, require_ms, require_humanize_ms, require_constants, require_agent, require_https_agent, require_agentkeepalive, require_event_target_shim, require_abort_controller, require_node_domexception, getType2, isPlainObject_default2, init_isPlainObject, fileFromPath_exports, import_node_domexception, __classPrivateFieldSet4, __classPrivateFieldGet5, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath, init_fileFromPath, rulesFile2, init_src102, prompt_segments_assembly_exports, init_prompt_segments_assembly2, init_ledger_segments2, DEFAULT_IDENTITY2, LONG_RUNNING_SHELL_GUIDANCE2, INVARIANT_GUIDANCE2, BASE_SYSTEM_PROMPT2, MAX_SOUL_CHARS2, MAX_USER_PROFILE_CHARS2, BLOCKING_PROMPT_FILE_PATTERNS2, userProfileWriteQueue2, MAX_CHARS_PER_FILE2, init_src112, require_code, require_scope, require_codegen, require_util, require_names, require_errors22, require_boolSchema, require_rules, require_applicability, require_dataType, require_defaults, require_code2, require_keyword, require_subschema, require_fast_deep_equal, require_json_schema_traverse, require_resolve, require_validate, require_validation_error, require_ref_error, require_compile, require_data, require_utils2, require_schemes, require_fast_uri, require_uri, require_core, require_id, require_ref, require_core2, require_limitNumber, require_multipleOf, require_ucs2length, require_limitLength, require_pattern, require_limitProperties, require_required, require_limitItems, require_equal, require_uniqueItems, require_const, require_enum, require_validation, require_additionalItems, require_items, require_prefixItems, require_items2020, require_contains, require_dependencies, require_propertyNames, require_additionalProperties, require_properties, require_patternProperties, require_not, require_anyOf, require_oneOf, require_allOf, require_if, require_thenElse, require_applicator, require_format, require_format2, require_metadata, require_draft7, require_types, require_discriminator, require_json_schema_draft_07, require_ajv, require_formats, require_limit, require_dist2, require_windows, require_mode, require_isexe, require_which, require_path_key, require_resolveCommand, require_escape, require_shebang_regex, require_shebang_command, require_readShebang, require_parse, require_enoent, require_cross_spawn, AgentOperationConflictError, AgentEventDeliveryError, AgentEventBus = class {
|
|
219097
219832
|
constructor(sink) {
|
|
219098
219833
|
this.sink = sink;
|
|
219099
219834
|
}
|
|
@@ -219136,7 +219871,7 @@ var require2, __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __get
|
|
|
219136
219871
|
async drain() {
|
|
219137
219872
|
await this.delivery;
|
|
219138
219873
|
}
|
|
219139
|
-
}, FrameworkAgentRun = class {
|
|
219874
|
+
}, textSchema, GOAL_ASSESSMENT_TOOL_NAME = "GoalAssessment", FrameworkAgentRun = class {
|
|
219140
219875
|
constructor(options) {
|
|
219141
219876
|
this.options = options;
|
|
219142
219877
|
this.id = options.ids.runId;
|
|
@@ -219221,6 +219956,7 @@ var require2, __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __get
|
|
|
219221
219956
|
};
|
|
219222
219957
|
const execution = {
|
|
219223
219958
|
scope,
|
|
219959
|
+
...this.options.goal ? { contribution: createGoalRunContribution(this.options.goal) } : {},
|
|
219224
219960
|
effects: this.options.effects,
|
|
219225
219961
|
children: this.options.children.createController(scope),
|
|
219226
219962
|
emit: (event) => this.emit(event),
|
|
@@ -219332,7 +220068,10 @@ var require2, __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __get
|
|
|
219332
220068
|
if (event.type === "text_delta") {
|
|
219333
220069
|
await this.emit({
|
|
219334
220070
|
type: "output.text.delta",
|
|
219335
|
-
data: {
|
|
220071
|
+
data: {
|
|
220072
|
+
delta: event.delta,
|
|
220073
|
+
...event.phase ? { phase: event.phase } : {}
|
|
220074
|
+
}
|
|
219336
220075
|
});
|
|
219337
220076
|
} else if (event.type === "complete") {
|
|
219338
220077
|
await this.emit({
|
|
@@ -219446,6 +220185,7 @@ var require2, __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __get
|
|
|
219446
220185
|
externalSignal: options.signal,
|
|
219447
220186
|
delivery: options.delivery ?? "queue",
|
|
219448
220187
|
metadata: options.metadata,
|
|
220188
|
+
goal: options.goal,
|
|
219449
220189
|
onSettled: (result2, toolActivity) => {
|
|
219450
220190
|
if (this.activeRun !== run)
|
|
219451
220191
|
return;
|
|
@@ -228846,7 +229586,11 @@ ${reminder}`;
|
|
|
228846
229586
|
memoryContext = await this.memoryRetriever(userContentToText(preparedContent));
|
|
228847
229587
|
} catch {}
|
|
228848
229588
|
}
|
|
228849
|
-
const
|
|
229589
|
+
const baseSystemPrompt = this.composeTurnSystemPrompt(memoryContext);
|
|
229590
|
+
const contribution = options.execution?.contribution;
|
|
229591
|
+
const turnSystemPrompt = contribution?.systemGuidance ? appendSystemGuidance(baseSystemPrompt, contribution.systemGuidance) : baseSystemPrompt;
|
|
229592
|
+
const runToolRegistry = this.runToolRegistry(contribution);
|
|
229593
|
+
const internalTools = new Set(contribution?.tools?.filter((item) => item.permission === "host-internal").map((item) => item.definition.name) ?? []);
|
|
228850
229594
|
let turnCount = 0;
|
|
228851
229595
|
const failedToolCalls = new ToolFailureMemory2;
|
|
228852
229596
|
const trajectoryTracker = this.options.trajectoryTrackerFactory === false ? undefined : this.options.trajectoryTrackerFactory?.() ?? new DefaultTrajectoryTracker2;
|
|
@@ -228860,7 +229604,10 @@ ${reminder}`;
|
|
|
228860
229604
|
try {
|
|
228861
229605
|
this.compactService.setProgressCallback((event) => options.execution?.emit({
|
|
228862
229606
|
type: "domain.event",
|
|
228863
|
-
data: {
|
|
229607
|
+
data: {
|
|
229608
|
+
name: "context_compaction",
|
|
229609
|
+
payload: event
|
|
229610
|
+
}
|
|
228864
229611
|
}));
|
|
228865
229612
|
this.messages = await this.compactService.autoCompact(this.messages, "auto", options.signal);
|
|
228866
229613
|
} catch (error2) {
|
|
@@ -228869,7 +229616,7 @@ ${reminder}`;
|
|
|
228869
229616
|
}
|
|
228870
229617
|
this.messages = sanitizeMessageHistory2(this.messages);
|
|
228871
229618
|
const forcedFinalTurn = forceFinalResponse;
|
|
228872
|
-
const visibleTools =
|
|
229619
|
+
const visibleTools = runToolRegistry.getAll();
|
|
228873
229620
|
const tools = forcedFinalTurn ? [] : visibleTools.filter((tool) => !blockedTools.has(tool.name) && !trajectoryControl.hiddenTools.includes(tool.name));
|
|
228874
229621
|
const finalizing = forcedFinalTurn || blockedTools.size > 0 && tools.length === 0;
|
|
228875
229622
|
const recoverySystem = finalizing ? appendSystemGuidance(turnSystemPrompt, RECOVERY_FINALIZATION_PROMPT) : turnSystemPrompt;
|
|
@@ -228916,11 +229663,11 @@ ${reminder}`;
|
|
|
228916
229663
|
}
|
|
228917
229664
|
if (toolUses.length > 0) {
|
|
228918
229665
|
const recoveringAtTurnStart = recoveryToolTurnsRemaining !== null;
|
|
228919
|
-
const results = await this.executeTools(toolUses, options.signal, options.execution, failedToolCalls, blockedTools);
|
|
229666
|
+
const results = await this.executeTools(toolUses, options.signal, options.execution, failedToolCalls, blockedTools, runToolRegistry, internalTools);
|
|
228920
229667
|
for (let i2 = 0;i2 < results.length; i2++) {
|
|
228921
229668
|
const result2 = results[i2];
|
|
228922
229669
|
const toolUse = toolUses[i2];
|
|
228923
|
-
const tool =
|
|
229670
|
+
const tool = runToolRegistry.get(toolUse.name);
|
|
228924
229671
|
if (result2.isError && (!tool || tool.safeToRetry !== true)) {
|
|
228925
229672
|
failedToolCalls.recordFailure(toolUse.name, toolUse.input);
|
|
228926
229673
|
}
|
|
@@ -228947,7 +229694,10 @@ ${reminder}`;
|
|
|
228947
229694
|
yield { type: "tool_use_end", toolUseId: result2.toolUseId, result: result2 };
|
|
228948
229695
|
}
|
|
228949
229696
|
applyTrajectoryTracker2(trajectoryTracker, {
|
|
228950
|
-
calls: toolUses.map((toolUse, index) => ({
|
|
229697
|
+
calls: toolUses.map((toolUse, index) => ({
|
|
229698
|
+
toolUse,
|
|
229699
|
+
result: results[index]
|
|
229700
|
+
}))
|
|
228951
229701
|
}, trajectoryControl);
|
|
228952
229702
|
if (trajectoryControl.forceFinal)
|
|
228953
229703
|
forceFinalResponse = true;
|
|
@@ -229040,10 +229790,9 @@ ${reminder}`;
|
|
|
229040
229790
|
getTotalUsage() {
|
|
229041
229791
|
return this.costTracker.getTotal();
|
|
229042
229792
|
}
|
|
229043
|
-
async executeTools(toolUses, signal, execution, failedToolCalls, blockedTools) {
|
|
229793
|
+
async executeTools(toolUses, signal, execution, failedToolCalls, blockedTools, toolRegistry = this.visibleToolRegistry(), internalTools = /* @__PURE__ */ new Set) {
|
|
229044
229794
|
const results = new Array(toolUses.length);
|
|
229045
229795
|
const readyForPermission = [];
|
|
229046
|
-
const toolRegistry = this.visibleToolRegistry();
|
|
229047
229796
|
for (let i2 = 0;i2 < toolUses.length; i2++) {
|
|
229048
229797
|
const toolUse = toolUses[i2];
|
|
229049
229798
|
if (blockedTools?.has(toolUse.name)) {
|
|
@@ -229083,9 +229832,7 @@ ${reminder}`;
|
|
|
229083
229832
|
results[i2] = {
|
|
229084
229833
|
toolUseId: toolUse.id,
|
|
229085
229834
|
toolName: toolUse.name,
|
|
229086
|
-
content: [
|
|
229087
|
-
{ type: "text", text: `Unknown tool: ${toolUse.name}` }
|
|
229088
|
-
],
|
|
229835
|
+
content: [{ type: "text", text: `Unknown tool: ${toolUse.name}` }],
|
|
229089
229836
|
isError: true,
|
|
229090
229837
|
failureKind: "policy"
|
|
229091
229838
|
};
|
|
@@ -229111,6 +229858,12 @@ ${reminder}`;
|
|
|
229111
229858
|
readyForPermission.push({ idx: i2, toolUse, tool });
|
|
229112
229859
|
}
|
|
229113
229860
|
const checks = await Promise.all(readyForPermission.map(async ({ toolUse }) => {
|
|
229861
|
+
if (internalTools.has(toolUse.name)) {
|
|
229862
|
+
return {
|
|
229863
|
+
action: "allow",
|
|
229864
|
+
reason: "Trusted host-internal run tool"
|
|
229865
|
+
};
|
|
229866
|
+
}
|
|
229114
229867
|
try {
|
|
229115
229868
|
return await this.permissionChecker.checkTool(toolUse.name, toolUse.input);
|
|
229116
229869
|
} catch {
|
|
@@ -229210,7 +229963,7 @@ ${reminder}`;
|
|
|
229210
229963
|
toolAttemptId,
|
|
229211
229964
|
runAbortSignal: signal,
|
|
229212
229965
|
settings: this.options.settings,
|
|
229213
|
-
toolRegistry: this.
|
|
229966
|
+
toolRegistry: this.toolRegistryView(toolRegistry),
|
|
229214
229967
|
skillRegistry: this.skillRegistry,
|
|
229215
229968
|
mcpManager: this.mcpManager,
|
|
229216
229969
|
mcpAuth: this.mcpAuth,
|
|
@@ -229312,11 +230065,11 @@ ${reminder}`;
|
|
|
229312
230065
|
externalSignal?.removeEventListener("abort", abortFromExternal);
|
|
229313
230066
|
}
|
|
229314
230067
|
}
|
|
229315
|
-
visibleToolRegistry() {
|
|
230068
|
+
visibleToolRegistry(alwaysAllowed = []) {
|
|
229316
230069
|
const allowedTools = this.allowedTools;
|
|
229317
230070
|
if (!allowedTools || allowedTools.includes("*"))
|
|
229318
230071
|
return this.toolRegistry;
|
|
229319
|
-
const allowed = new Set(allowedTools);
|
|
230072
|
+
const allowed = /* @__PURE__ */ new Set([...allowedTools, ...alwaysAllowed]);
|
|
229320
230073
|
const inner = this.toolRegistry;
|
|
229321
230074
|
return {
|
|
229322
230075
|
register(tool, source) {
|
|
@@ -229342,8 +230095,32 @@ ${reminder}`;
|
|
|
229342
230095
|
}
|
|
229343
230096
|
};
|
|
229344
230097
|
}
|
|
229345
|
-
|
|
229346
|
-
const
|
|
230098
|
+
runToolRegistry(contribution) {
|
|
230099
|
+
const base = this.visibleToolRegistry();
|
|
230100
|
+
const contributed = contribution?.tools ?? [];
|
|
230101
|
+
if (contributed.length === 0)
|
|
230102
|
+
return base;
|
|
230103
|
+
const additions = /* @__PURE__ */ new Map;
|
|
230104
|
+
for (const { definition } of contributed) {
|
|
230105
|
+
if (base.has(definition.name) || additions.has(definition.name))
|
|
230106
|
+
throw new Error(`Run tool conflicts with an existing tool: ${definition.name}`);
|
|
230107
|
+
additions.set(definition.name, definition);
|
|
230108
|
+
}
|
|
230109
|
+
return {
|
|
230110
|
+
register: () => {
|
|
230111
|
+
throw new Error("Run-scoped tool registry is immutable");
|
|
230112
|
+
},
|
|
230113
|
+
override: () => {
|
|
230114
|
+
throw new Error("Run-scoped tool registry is immutable");
|
|
230115
|
+
},
|
|
230116
|
+
unregister: () => false,
|
|
230117
|
+
get: (name) => additions.get(name) ?? base.get(name),
|
|
230118
|
+
getAll: () => [...base.getAll(), ...additions.values()],
|
|
230119
|
+
has: (name) => additions.has(name) || base.has(name),
|
|
230120
|
+
inspect: (name) => additions.has(name) ? { name, source: { kind: "runtime", id: "run-contribution" } } : base.inspect(name)
|
|
230121
|
+
};
|
|
230122
|
+
}
|
|
230123
|
+
toolRegistryView(registry2) {
|
|
229347
230124
|
return {
|
|
229348
230125
|
get: (name) => {
|
|
229349
230126
|
const tool = registry2.get(name);
|
|
@@ -242196,6 +242973,11 @@ params: ${params}`);
|
|
|
242196
242973
|
init_attachment3();
|
|
242197
242974
|
}
|
|
242198
242975
|
});
|
|
242976
|
+
init_session_goals2 = __esm2({
|
|
242977
|
+
"../protocol/src/session-goals.ts"() {
|
|
242978
|
+
init_requests2();
|
|
242979
|
+
}
|
|
242980
|
+
});
|
|
242199
242981
|
init_src52 = __esm2({
|
|
242200
242982
|
"../protocol/src/index.ts"() {
|
|
242201
242983
|
init_session32();
|
|
@@ -242208,6 +242990,7 @@ params: ${params}`);
|
|
|
242208
242990
|
init_capabilities2();
|
|
242209
242991
|
init_attachment3();
|
|
242210
242992
|
init_session_input_items2();
|
|
242993
|
+
init_session_goals2();
|
|
242211
242994
|
}
|
|
242212
242995
|
});
|
|
242213
242996
|
init_attachment_errors2 = __esm2({
|
|
@@ -242324,6 +243107,8 @@ params: ${params}`);
|
|
|
242324
243107
|
throw new Error("field must be text or reasoning");
|
|
242325
243108
|
}),
|
|
242326
243109
|
sessionDefinition2("session.run.created", objectPayload2("run")),
|
|
243110
|
+
sessionDefinition2("session.goal.created", objectPayload2("goal")),
|
|
243111
|
+
sessionDefinition2("session.goal.updated", objectPayload2("goal")),
|
|
242327
243112
|
sessionDefinition2("session.run.updated", (payload) => {
|
|
242328
243113
|
objectPayload2("run")(payload);
|
|
242329
243114
|
requireString2(payload, "previousStatus");
|
|
@@ -244164,6 +244949,209 @@ params: ${params}`);
|
|
|
244164
244949
|
}
|
|
244165
244950
|
return this.getProjectionSettlement(id);
|
|
244166
244951
|
}
|
|
244952
|
+
createGoal(input) {
|
|
244953
|
+
this.assertCurrentOwner();
|
|
244954
|
+
const session = assertSession2(this.state, input.sessionId);
|
|
244955
|
+
assertMutableSession2(session);
|
|
244956
|
+
const id = input.id ?? randomUUID82();
|
|
244957
|
+
const timestamp2 = now2();
|
|
244958
|
+
try {
|
|
244959
|
+
this.database.prepare(`
|
|
244960
|
+
INSERT INTO session_goal (
|
|
244961
|
+
id, session_id, objective, revision, status, max_auto_turns,
|
|
244962
|
+
auto_turns_used, no_progress_count, evidence_json, created_at, updated_at
|
|
244963
|
+
) VALUES (?, ?, ?, 0, 'active', ?, 0, 0, '[]', ?, ?)
|
|
244964
|
+
`).run(id, input.sessionId, input.objective, input.maxAutoTurns, timestamp2, timestamp2);
|
|
244965
|
+
} catch (error2) {
|
|
244966
|
+
if (String(error2).includes("session_goal_session_open_unique")) {
|
|
244967
|
+
throw new Error(`Session already has an open goal: ${input.sessionId}`);
|
|
244968
|
+
}
|
|
244969
|
+
throw error2;
|
|
244970
|
+
}
|
|
244971
|
+
const goal = this.getGoal(id);
|
|
244972
|
+
this.appendEvent({
|
|
244973
|
+
type: "session.goal.created",
|
|
244974
|
+
sessionId: input.sessionId,
|
|
244975
|
+
payload: { goal }
|
|
244976
|
+
});
|
|
244977
|
+
return goal;
|
|
244978
|
+
}
|
|
244979
|
+
getGoalRequest(requestId) {
|
|
244980
|
+
const row = this.database.prepare(`SELECT * FROM session_goal_request WHERE request_id = ?`).get(requestId);
|
|
244981
|
+
if (!row)
|
|
244982
|
+
return;
|
|
244983
|
+
return {
|
|
244984
|
+
requestId: String(row.request_id),
|
|
244985
|
+
sessionId: String(row.session_id),
|
|
244986
|
+
fingerprint: String(row.fingerprint),
|
|
244987
|
+
status: String(row.status),
|
|
244988
|
+
...typeof row.goal_id === "string" ? { goalId: row.goal_id } : {},
|
|
244989
|
+
...typeof row.result_json === "string" ? { result: JSON.parse(row.result_json) } : {},
|
|
244990
|
+
...typeof row.error === "string" ? { error: row.error } : {},
|
|
244991
|
+
createdAt: Number(row.created_at),
|
|
244992
|
+
updatedAt: Number(row.updated_at)
|
|
244993
|
+
};
|
|
244994
|
+
}
|
|
244995
|
+
beginGoalRequest(input) {
|
|
244996
|
+
this.assertCurrentOwner();
|
|
244997
|
+
const existing = this.getGoalRequest(input.requestId);
|
|
244998
|
+
if (existing) {
|
|
244999
|
+
if (existing.sessionId !== input.sessionId || existing.fingerprint !== input.fingerprint)
|
|
245000
|
+
throw new Error("session_goal_request_conflict");
|
|
245001
|
+
return existing;
|
|
245002
|
+
}
|
|
245003
|
+
const timestamp2 = now2();
|
|
245004
|
+
this.database.prepare(`INSERT INTO session_goal_request (request_id, session_id, fingerprint, status, created_at, updated_at) VALUES (?, ?, ?, 'pending', ?, ?)`).run(input.requestId, input.sessionId, input.fingerprint, timestamp2, timestamp2);
|
|
245005
|
+
return this.getGoalRequest(input.requestId);
|
|
245006
|
+
}
|
|
245007
|
+
settleGoalRequest(requestId, input) {
|
|
245008
|
+
this.assertCurrentOwner();
|
|
245009
|
+
const timestamp2 = now2();
|
|
245010
|
+
const result2 = this.database.prepare(`UPDATE session_goal_request SET status = ?, goal_id = ?, result_json = ?, error = ?, updated_at = ? WHERE request_id = ?`).run(input.status, input.goalId ?? null, input.result ? JSON.stringify(input.result) : null, input.error ?? null, timestamp2, requestId);
|
|
245011
|
+
if (result2.changes !== 1)
|
|
245012
|
+
throw new Error(`Session goal request not found: ${requestId}`);
|
|
245013
|
+
return this.getGoalRequest(requestId);
|
|
245014
|
+
}
|
|
245015
|
+
recordGoalAssessment(input) {
|
|
245016
|
+
this.assertCurrentOwner();
|
|
245017
|
+
this.database.prepare(`
|
|
245018
|
+
INSERT INTO session_goal_assessment (id, goal_id, revision, run_id, assessment_json, created_at)
|
|
245019
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
245020
|
+
ON CONFLICT(goal_id, revision, run_id) DO UPDATE SET assessment_json = excluded.assessment_json
|
|
245021
|
+
`).run(randomUUID82(), input.goalId, input.revision, input.runId, JSON.stringify(input.assessment), now2());
|
|
245022
|
+
}
|
|
245023
|
+
goalEvidenceSignatures(goalId) {
|
|
245024
|
+
const rows = this.database.prepare(`SELECT assessment_json FROM session_goal_assessment WHERE goal_id = ?`).all(goalId);
|
|
245025
|
+
return rows.flatMap((row) => {
|
|
245026
|
+
const value = JSON.parse(row.assessment_json);
|
|
245027
|
+
return value.verifiedSignatures ?? [];
|
|
245028
|
+
});
|
|
245029
|
+
}
|
|
245030
|
+
recordGoalContinuation(input) {
|
|
245031
|
+
this.assertCurrentOwner();
|
|
245032
|
+
const timestamp2 = now2();
|
|
245033
|
+
const result2 = this.database.prepare(`
|
|
245034
|
+
INSERT OR IGNORE INTO session_goal_continuation
|
|
245035
|
+
(id, goal_id, revision, previous_run_id, input_id, run_id, status, created_at, updated_at)
|
|
245036
|
+
VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, ?)
|
|
245037
|
+
`).run(randomUUID82(), input.goalId, input.revision, input.previousRunId, input.inputId, input.runId, timestamp2, timestamp2);
|
|
245038
|
+
return result2.changes === 1;
|
|
245039
|
+
}
|
|
245040
|
+
pauseActiveGoalsOnStartup() {
|
|
245041
|
+
this.assertCurrentOwner();
|
|
245042
|
+
return this.transaction(() => {
|
|
245043
|
+
const rows = this.database.prepare(`SELECT id FROM session_goal WHERE status = 'active'`).all();
|
|
245044
|
+
for (const { id } of rows) {
|
|
245045
|
+
const goal = this.getGoal(id);
|
|
245046
|
+
this.updateGoal(id, {
|
|
245047
|
+
expectedRevision: goal.revision,
|
|
245048
|
+
status: "paused",
|
|
245049
|
+
currentRunId: null,
|
|
245050
|
+
reason: "应用重启后需要手动继续"
|
|
245051
|
+
});
|
|
245052
|
+
}
|
|
245053
|
+
this.database.prepare(`UPDATE session_goal_continuation SET status = 'cancelled', updated_at = ? WHERE status = 'pending'`).run(now2());
|
|
245054
|
+
return rows.length;
|
|
245055
|
+
});
|
|
245056
|
+
}
|
|
245057
|
+
markGoalContinuation(runId, status) {
|
|
245058
|
+
this.assertCurrentOwner();
|
|
245059
|
+
this.database.prepare(`UPDATE session_goal_continuation SET status = ?, updated_at = ? WHERE run_id = ?`).run(status, now2(), runId);
|
|
245060
|
+
}
|
|
245061
|
+
finishGoalRun(runId) {
|
|
245062
|
+
this.assertCurrentOwner();
|
|
245063
|
+
const row = this.database.prepare(`SELECT id FROM session_goal WHERE current_run_id = ?`).get(runId);
|
|
245064
|
+
if (!row)
|
|
245065
|
+
return;
|
|
245066
|
+
this.database.prepare(`UPDATE session_goal SET current_run_id = NULL, updated_at = ? WHERE id = ?`).run(now2(), row.id);
|
|
245067
|
+
const goal = this.getGoal(row.id);
|
|
245068
|
+
this.appendEvent({
|
|
245069
|
+
type: "session.goal.updated",
|
|
245070
|
+
sessionId: goal.sessionId,
|
|
245071
|
+
payload: { goal }
|
|
245072
|
+
});
|
|
245073
|
+
}
|
|
245074
|
+
startGoalRun(goalId, revision, runId, automatic) {
|
|
245075
|
+
this.assertCurrentOwner();
|
|
245076
|
+
return this.transaction(() => {
|
|
245077
|
+
const goal = this.getGoal(goalId);
|
|
245078
|
+
if (!goal || goal.status !== "active" || goal.revision !== revision)
|
|
245079
|
+
return false;
|
|
245080
|
+
const run = this.getRun(runId);
|
|
245081
|
+
if (!run || run.sessionId !== goal.sessionId || run.status !== "pending" && run.status !== "running")
|
|
245082
|
+
return false;
|
|
245083
|
+
if (goal.currentRunId === runId)
|
|
245084
|
+
return true;
|
|
245085
|
+
if (automatic && goal.autoTurnsUsed >= goal.maxAutoTurns) {
|
|
245086
|
+
this.updateGoal(goalId, {
|
|
245087
|
+
expectedRevision: revision,
|
|
245088
|
+
status: "paused",
|
|
245089
|
+
reason: "目标自动续跑额度已用完",
|
|
245090
|
+
currentRunId: null
|
|
245091
|
+
});
|
|
245092
|
+
return false;
|
|
245093
|
+
}
|
|
245094
|
+
this.database.prepare(`UPDATE session_goal SET current_run_id = ?, auto_turns_used = auto_turns_used + ?, updated_at = ? WHERE id = ? AND revision = ?`).run(runId, automatic ? 1 : 0, now2(), goalId, revision);
|
|
245095
|
+
this.appendEvent({
|
|
245096
|
+
type: "session.goal.updated",
|
|
245097
|
+
sessionId: goal.sessionId,
|
|
245098
|
+
payload: { goal: this.getGoal(goalId) }
|
|
245099
|
+
});
|
|
245100
|
+
return true;
|
|
245101
|
+
});
|
|
245102
|
+
}
|
|
245103
|
+
getGoal(id) {
|
|
245104
|
+
const row = this.database.prepare(`SELECT * FROM session_goal WHERE id = ?`).get(id);
|
|
245105
|
+
return row ? sessionGoalFromRow2(row) : undefined;
|
|
245106
|
+
}
|
|
245107
|
+
getCurrentGoal(sessionId) {
|
|
245108
|
+
const row = this.database.prepare(`
|
|
245109
|
+
SELECT * FROM session_goal
|
|
245110
|
+
WHERE session_id = ?
|
|
245111
|
+
ORDER BY CASE WHEN status IN ('active','waiting_user','blocked','paused') THEN 0 ELSE 1 END,
|
|
245112
|
+
updated_at DESC
|
|
245113
|
+
LIMIT 1
|
|
245114
|
+
`).get(sessionId);
|
|
245115
|
+
return row ? sessionGoalFromRow2(row) : undefined;
|
|
245116
|
+
}
|
|
245117
|
+
updateGoal(id, input) {
|
|
245118
|
+
this.assertCurrentOwner();
|
|
245119
|
+
const current = this.getGoal(id);
|
|
245120
|
+
if (!current)
|
|
245121
|
+
throw new Error(`Session goal not found: ${id}`);
|
|
245122
|
+
if (current.revision !== input.expectedRevision)
|
|
245123
|
+
throw new Error("session_goal_revision_conflict");
|
|
245124
|
+
const nextRevision = current.revision + 1;
|
|
245125
|
+
const timestamp2 = now2();
|
|
245126
|
+
const next = {
|
|
245127
|
+
objective: input.objective ?? current.objective,
|
|
245128
|
+
status: input.status ?? current.status,
|
|
245129
|
+
maxAutoTurns: input.maxAutoTurns ?? current.maxAutoTurns,
|
|
245130
|
+
autoTurnsUsed: input.autoTurnsUsed ?? current.autoTurnsUsed,
|
|
245131
|
+
noProgressCount: input.noProgressCount ?? current.noProgressCount,
|
|
245132
|
+
blockerKey: input.blockerKey === undefined ? current.blockerKey : input.blockerKey ?? undefined,
|
|
245133
|
+
currentRunId: input.currentRunId === undefined ? current.currentRunId : input.currentRunId ?? undefined,
|
|
245134
|
+
reason: input.reason === undefined ? current.reason : input.reason ?? undefined,
|
|
245135
|
+
wait: input.wait === undefined ? current.wait : input.wait ?? undefined,
|
|
245136
|
+
evidence: input.evidence ?? current.evidence,
|
|
245137
|
+
assessment: input.assessment === undefined ? current.assessment : input.assessment ?? undefined
|
|
245138
|
+
};
|
|
245139
|
+
const result2 = this.database.prepare(`
|
|
245140
|
+
UPDATE session_goal SET objective = ?, revision = ?, status = ?, max_auto_turns = ?,
|
|
245141
|
+
auto_turns_used = ?, no_progress_count = ?, blocker_key = ?, current_run_id = ?, reason = ?,
|
|
245142
|
+
wait_json = ?, evidence_json = ?, last_assessment_json = ?, updated_at = ?
|
|
245143
|
+
WHERE id = ? AND revision = ?
|
|
245144
|
+
`).run(next.objective, nextRevision, next.status, next.maxAutoTurns, next.autoTurnsUsed, next.noProgressCount, next.blockerKey ?? null, next.currentRunId ?? null, next.reason ?? null, next.wait ? JSON.stringify(next.wait) : null, JSON.stringify(next.evidence), next.assessment ? JSON.stringify(next.assessment) : null, timestamp2, id, input.expectedRevision);
|
|
245145
|
+
if (result2.changes !== 1)
|
|
245146
|
+
throw new Error("session_goal_revision_conflict");
|
|
245147
|
+
const goal = this.getGoal(id);
|
|
245148
|
+
this.appendEvent({
|
|
245149
|
+
type: "session.goal.updated",
|
|
245150
|
+
sessionId: goal.sessionId,
|
|
245151
|
+
payload: { goal }
|
|
245152
|
+
});
|
|
245153
|
+
return goal;
|
|
245154
|
+
}
|
|
244167
245155
|
createRun(input) {
|
|
244168
245156
|
const session = assertSession2(this.state, input.sessionId);
|
|
244169
245157
|
assertMutableSession2(session);
|
|
@@ -244866,11 +245854,15 @@ params: ${params}`);
|
|
|
244866
245854
|
...row.output_json ? { output: JSON.parse(row.output_json) } : {},
|
|
244867
245855
|
...row.is_error !== null ? { isError: Boolean(row.is_error) } : {},
|
|
244868
245856
|
...row.asset_id ? { assetId: row.asset_id } : {},
|
|
244869
|
-
...row.attachment_intent ? {
|
|
245857
|
+
...row.attachment_intent ? {
|
|
245858
|
+
intent: row.attachment_intent
|
|
245859
|
+
} : {},
|
|
244870
245860
|
...row.display_name ? { displayName: row.display_name } : {},
|
|
244871
245861
|
...row.media_type ? { mediaType: row.media_type } : {},
|
|
244872
245862
|
...row.size_bytes !== null ? { sizeBytes: row.size_bytes } : {},
|
|
244873
|
-
...row.transformation_kind ? {
|
|
245863
|
+
...row.transformation_kind ? {
|
|
245864
|
+
kind: row.transformation_kind
|
|
245865
|
+
} : {},
|
|
244874
245866
|
...row.representation_id ? { representationId: row.representation_id } : {},
|
|
244875
245867
|
...row.processor ? { processor: row.processor } : {},
|
|
244876
245868
|
...row.transformation_error ? { transformationError: row.transformation_error } : {},
|
|
@@ -261331,6 +262323,7 @@ ${INVARIANT_GUIDANCE2}`;
|
|
|
261331
262323
|
}
|
|
261332
262324
|
cause;
|
|
261333
262325
|
};
|
|
262326
|
+
textSchema = { type: "string", minLength: 1, maxLength: 4000 };
|
|
261334
262327
|
init_src19();
|
|
261335
262328
|
init_src22();
|
|
261336
262329
|
init_src32();
|
|
@@ -279804,6 +280797,14 @@ var init_commands2 = __esm(() => {
|
|
|
279804
280797
|
selection: "execute",
|
|
279805
280798
|
requiresEmptyComposer: true
|
|
279806
280799
|
},
|
|
280800
|
+
{
|
|
280801
|
+
name: "/goal",
|
|
280802
|
+
description: "Set a durable goal for this session",
|
|
280803
|
+
kind: "session",
|
|
280804
|
+
source: "builtin",
|
|
280805
|
+
selection: "execute",
|
|
280806
|
+
requiresEmptyComposer: true
|
|
280807
|
+
},
|
|
279807
280808
|
{
|
|
279808
280809
|
name: "/remember",
|
|
279809
280810
|
description: "Extract durable memories from this session",
|
|
@@ -284409,6 +285410,16 @@ class DaemonAgentEventProjector {
|
|
|
284409
285410
|
this.projectUsage(event);
|
|
284410
285411
|
return;
|
|
284411
285412
|
case "domain.event":
|
|
285413
|
+
if (event.data.name === "goal.assessment" && event.context.runId) {
|
|
285414
|
+
const run = this.context.store.getRun(event.context.runId);
|
|
285415
|
+
const payload = event.data.payload;
|
|
285416
|
+
if (run && run.sessionId === event.context.sessionId && typeof run.metadata.goalId === "string" && typeof run.metadata.goalRevision === "number" && run.status === "running" && !run.metadata.goalSettled && payload?.goalId === run.metadata.goalId && payload?.revision === run.metadata.goalRevision && payload?.runId === run.id) {
|
|
285417
|
+
try {
|
|
285418
|
+
const assessment = parseGoalAssessment(payload, { goalId: run.metadata.goalId, revision: run.metadata.goalRevision, runId: run.id });
|
|
285419
|
+
this.context.store.updateRun(run.id, { metadata: { goalAssessment: assessment } });
|
|
285420
|
+
} catch {}
|
|
285421
|
+
}
|
|
285422
|
+
}
|
|
284412
285423
|
if (event.data.name === "context_compaction") {
|
|
284413
285424
|
const phase = event.data.payload?.phase;
|
|
284414
285425
|
if (phase === "compact_start" || phase === "compact_end" || phase === "compact_failed") {
|
|
@@ -285177,6 +286188,8 @@ var init_run_inspector = __esm(() => {
|
|
|
285177
286188
|
});
|
|
285178
286189
|
|
|
285179
286190
|
// ../../packages/server/src/application/control/daemon-control-service.ts
|
|
286191
|
+
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
286192
|
+
|
|
285180
286193
|
class DaemonControlService {
|
|
285181
286194
|
context;
|
|
285182
286195
|
constructor(context) {
|
|
@@ -285203,8 +286216,14 @@ class DaemonControlService {
|
|
|
285203
286216
|
sessions: { total: sessions.length, byStatus: countByStatus(sessions) },
|
|
285204
286217
|
runs: { total: runs.length, byStatus: countByStatus(runs) },
|
|
285205
286218
|
tasks: { total: tasks.length, byStatus: countByStatus(tasks) },
|
|
285206
|
-
workflows: {
|
|
285207
|
-
|
|
286219
|
+
workflows: {
|
|
286220
|
+
total: workflows.length,
|
|
286221
|
+
byStatus: countByStatus(workflows)
|
|
286222
|
+
},
|
|
286223
|
+
permissions: {
|
|
286224
|
+
total: permissions.length,
|
|
286225
|
+
byStatus: countByStatus(permissions)
|
|
286226
|
+
},
|
|
285208
286227
|
projectionSettlements: {
|
|
285209
286228
|
total: projectionSettlements.length,
|
|
285210
286229
|
pending: projectionSettlements.filter((row) => row.status === "pending" || row.status === "retrying").length,
|
|
@@ -285237,10 +286256,18 @@ class DaemonControlService {
|
|
|
285237
286256
|
return this.context.runEngine.hasActiveRunsForCwd(cwd) || this.context.agentPool.hasActiveWorkForCwd(cwd);
|
|
285238
286257
|
}
|
|
285239
286258
|
acquireGlobalMutation() {
|
|
285240
|
-
return this.context.operationGate.tryEnterBarrier({ kind: "global" }, () => !this.hasAnyActiveRuns()
|
|
286259
|
+
return this.context.operationGate.tryEnterBarrier({ kind: "global" }, () => !this.hasAnyActiveRuns(), {
|
|
286260
|
+
operationId: randomUUID20(),
|
|
286261
|
+
operationName: "全局运行时维护",
|
|
286262
|
+
startedAt: Date.now()
|
|
286263
|
+
});
|
|
285241
286264
|
}
|
|
285242
286265
|
acquireCwdMutation(cwd) {
|
|
285243
|
-
return this.context.operationGate.tryEnterBarrier({ kind: "cwd", cwd }, () => !this.hasActiveRunsForCwd(cwd)
|
|
286266
|
+
return this.context.operationGate.tryEnterBarrier({ kind: "cwd", cwd }, () => !this.hasActiveRunsForCwd(cwd), {
|
|
286267
|
+
operationId: randomUUID20(),
|
|
286268
|
+
operationName: "工作区运行时维护",
|
|
286269
|
+
startedAt: Date.now()
|
|
286270
|
+
});
|
|
285244
286271
|
}
|
|
285245
286272
|
async closeAllRuntimes() {
|
|
285246
286273
|
await this.context.agentPool.closeAll();
|
|
@@ -285275,7 +286302,10 @@ class DaemonControlService {
|
|
|
285275
286302
|
const session = this.context.store.getSession(sessionId);
|
|
285276
286303
|
if (!session)
|
|
285277
286304
|
return [];
|
|
285278
|
-
const lease = this.context.operationGate.enter({
|
|
286305
|
+
const lease = this.context.operationGate.enter({
|
|
286306
|
+
sessionId,
|
|
286307
|
+
cwd: session.cwd
|
|
286308
|
+
});
|
|
285279
286309
|
try {
|
|
285280
286310
|
const agent = await this.context.agentPool.acquireSession(sessionId);
|
|
285281
286311
|
return agent.inspect().hooks.map((hook) => ({ ...hook, origin: "runtime" }));
|
|
@@ -285296,6 +286326,8 @@ var init_daemon_control_service = __esm(() => {
|
|
|
285296
286326
|
});
|
|
285297
286327
|
|
|
285298
286328
|
// ../../packages/server/src/application/control/daemon-operation-gate.ts
|
|
286329
|
+
import { randomUUID as randomUUID21 } from "node:crypto";
|
|
286330
|
+
|
|
285299
286331
|
class DaemonOperationGate {
|
|
285300
286332
|
phase = "open";
|
|
285301
286333
|
shared = new Map;
|
|
@@ -285307,14 +286339,18 @@ class DaemonOperationGate {
|
|
|
285307
286339
|
enter(scope) {
|
|
285308
286340
|
if (this.phase !== "open")
|
|
285309
286341
|
throw new DaemonOperationUnavailableError("closing");
|
|
285310
|
-
|
|
285311
|
-
|
|
285312
|
-
|
|
286342
|
+
const blocker = [...this.barriers.values()].find((barrier) => conflictsWithScope(barrier, scope));
|
|
286343
|
+
if (blocker)
|
|
286344
|
+
throw new DaemonOperationUnavailableError("blocked", blocker.maintenance);
|
|
285313
286345
|
const token = Symbol("daemon-operation");
|
|
285314
286346
|
this.shared.set(token, { token, ...scope });
|
|
285315
286347
|
return this.lease(() => this.shared.delete(token));
|
|
285316
286348
|
}
|
|
285317
|
-
tryEnterBarrier(barrier, isIdle
|
|
286349
|
+
tryEnterBarrier(barrier, isIdle, maintenance = {
|
|
286350
|
+
operationId: randomUUID21(),
|
|
286351
|
+
operationName: "系统维护",
|
|
286352
|
+
startedAt: Date.now()
|
|
286353
|
+
}) {
|
|
285318
286354
|
if (this.phase !== "open")
|
|
285319
286355
|
return;
|
|
285320
286356
|
if ([...this.shared.values()].some((scope) => conflictsWithScope(barrier, scope)))
|
|
@@ -285324,7 +286360,7 @@ class DaemonOperationGate {
|
|
|
285324
286360
|
if (!isIdle())
|
|
285325
286361
|
return;
|
|
285326
286362
|
const token = Symbol(`daemon-${barrier.kind}-barrier`);
|
|
285327
|
-
this.barriers.set(token, { token, ...barrier });
|
|
286363
|
+
this.barriers.set(token, { token, ...barrier, maintenance });
|
|
285328
286364
|
return this.lease(() => this.barriers.delete(token));
|
|
285329
286365
|
}
|
|
285330
286366
|
async beginShutdown() {
|
|
@@ -285381,9 +286417,11 @@ var DaemonOperationUnavailableError;
|
|
|
285381
286417
|
var init_daemon_operation_gate = __esm(() => {
|
|
285382
286418
|
DaemonOperationUnavailableError = class DaemonOperationUnavailableError extends Error {
|
|
285383
286419
|
reason;
|
|
285384
|
-
|
|
285385
|
-
|
|
286420
|
+
blocker;
|
|
286421
|
+
constructor(reason, blocker) {
|
|
286422
|
+
super(reason === "closing" ? "Daemon is closing" : blocker ? `Daemon operation is blocked by maintenance: ${blocker.operationName}` : "Daemon operation is blocked by maintenance");
|
|
285386
286423
|
this.reason = reason;
|
|
286424
|
+
this.blocker = blocker;
|
|
285387
286425
|
this.name = "DaemonOperationUnavailableError";
|
|
285388
286426
|
}
|
|
285389
286427
|
};
|
|
@@ -285460,12 +286498,24 @@ var init_session_application_error = __esm(() => {
|
|
|
285460
286498
|
});
|
|
285461
286499
|
|
|
285462
286500
|
// ../../packages/server/src/application/session/session-input-materializer.ts
|
|
285463
|
-
function materializeSessionInput(input, catalog) {
|
|
286501
|
+
function materializeSessionInput(input, catalog, conversationCatalog) {
|
|
285464
286502
|
const items = normalizeSessionUserInputItems(input);
|
|
285465
286503
|
const text = sessionUserInputText(items);
|
|
285466
286504
|
const skills = [];
|
|
285467
286505
|
const paths = new Set;
|
|
286506
|
+
const conversations = [];
|
|
286507
|
+
const conversationIds = new Set;
|
|
285468
286508
|
for (const item of items) {
|
|
286509
|
+
if (item.type === "context") {
|
|
286510
|
+
const conversation = conversationCatalog?.resolveConversation(item.id);
|
|
286511
|
+
if (!conversation)
|
|
286512
|
+
throw new Error("session_input_conversation_not_found");
|
|
286513
|
+
if (!conversationIds.has(conversation.id)) {
|
|
286514
|
+
conversationIds.add(conversation.id);
|
|
286515
|
+
conversations.push(conversation);
|
|
286516
|
+
}
|
|
286517
|
+
continue;
|
|
286518
|
+
}
|
|
285469
286519
|
if (item.type !== "skill")
|
|
285470
286520
|
continue;
|
|
285471
286521
|
const catalogSkill = catalog.resolvePath(item.path);
|
|
@@ -285477,20 +286527,38 @@ function materializeSessionInput(input, catalog) {
|
|
|
285477
286527
|
paths.add(catalogSkill.path);
|
|
285478
286528
|
skills.push(catalogSkill);
|
|
285479
286529
|
}
|
|
285480
|
-
const prefix = skillInstructionPrefix(skills)
|
|
286530
|
+
const prefix = [skillInstructionPrefix(skills), conversationInstructionPrefix(conversations)].filter(Boolean).join(`
|
|
286531
|
+
|
|
286532
|
+
`);
|
|
285481
286533
|
return {
|
|
285482
286534
|
text,
|
|
285483
286535
|
skills,
|
|
285484
|
-
|
|
286536
|
+
conversations,
|
|
286537
|
+
instruction: prefix ? `${prefix}
|
|
285485
286538
|
|
|
285486
286539
|
用户输入:
|
|
285487
286540
|
${text}` : text
|
|
285488
286541
|
};
|
|
285489
286542
|
}
|
|
286543
|
+
function conversationInstructionPrefix(conversations) {
|
|
286544
|
+
if (conversations.length === 0)
|
|
286545
|
+
return "";
|
|
286546
|
+
return [
|
|
286547
|
+
"用户引用了以下历史对话作为只读参考上下文:",
|
|
286548
|
+
...conversations.map((conversation, index) => `${index + 1}. ${conversation.title}
|
|
286549
|
+
${conversation.summary}`)
|
|
286550
|
+
].join(`
|
|
286551
|
+
`);
|
|
286552
|
+
}
|
|
285490
286553
|
function applyMaterializedSessionInput(content, materialized) {
|
|
285491
|
-
if (materialized.skills.length === 0)
|
|
286554
|
+
if (materialized.skills.length === 0 && materialized.conversations.length === 0)
|
|
285492
286555
|
return content;
|
|
285493
|
-
const prefix =
|
|
286556
|
+
const prefix = [
|
|
286557
|
+
skillInstructionPrefix(materialized.skills),
|
|
286558
|
+
conversationInstructionPrefix(materialized.conversations)
|
|
286559
|
+
].filter(Boolean).join(`
|
|
286560
|
+
|
|
286561
|
+
`);
|
|
285494
286562
|
if (typeof content === "string")
|
|
285495
286563
|
return `${prefix}
|
|
285496
286564
|
|
|
@@ -285521,7 +286589,33 @@ var init_session_input_materializer = __esm(() => {
|
|
|
285521
286589
|
init_src4();
|
|
285522
286590
|
});
|
|
285523
286591
|
|
|
286592
|
+
// ../../packages/server/src/application/session/session-conversation-context.ts
|
|
286593
|
+
function conversationContextCatalog(store, currentSessionId) {
|
|
286594
|
+
return {
|
|
286595
|
+
resolveConversation(id) {
|
|
286596
|
+
if (id === currentSessionId)
|
|
286597
|
+
return;
|
|
286598
|
+
const session = store.getSession(id);
|
|
286599
|
+
if (!session || session.status === "archived")
|
|
286600
|
+
return;
|
|
286601
|
+
const partsByMessage = new Map;
|
|
286602
|
+
for (const part of store.listMessageParts(id)) {
|
|
286603
|
+
if (part.type !== "text" || !part.text)
|
|
286604
|
+
continue;
|
|
286605
|
+
const texts = partsByMessage.get(part.messageId) ?? [];
|
|
286606
|
+
texts.push(part.text);
|
|
286607
|
+
partsByMessage.set(part.messageId, texts);
|
|
286608
|
+
}
|
|
286609
|
+
const summary = store.listMessages(id).filter((message) => message.role === "user" || message.role === "assistant").map((message) => `${message.role === "user" ? "用户" : "助手"}:${(partsByMessage.get(message.id) ?? []).join("")}`).filter((line) => line.trim()).join(`
|
|
286610
|
+
`).slice(-MAX_CONVERSATION_CONTEXT_CHARS);
|
|
286611
|
+
return { id, title: session.title.trim() || "未命名对话", summary };
|
|
286612
|
+
}
|
|
286613
|
+
};
|
|
286614
|
+
}
|
|
286615
|
+
var MAX_CONVERSATION_CONTEXT_CHARS = 12000;
|
|
286616
|
+
|
|
285524
286617
|
// ../../packages/server/src/application/session/session-application-service.ts
|
|
286618
|
+
import { randomUUID as randomUUID23 } from "node:crypto";
|
|
285525
286619
|
function inputItems(input) {
|
|
285526
286620
|
return input.items ? [...input.items] : [{ type: "text", text: input.content ?? "" }];
|
|
285527
286621
|
}
|
|
@@ -285702,6 +286796,18 @@ class SessionApplicationService {
|
|
|
285702
286796
|
lease?.release();
|
|
285703
286797
|
}
|
|
285704
286798
|
}
|
|
286799
|
+
async withSessionOperation(sessionId, work) {
|
|
286800
|
+
this.assertReady();
|
|
286801
|
+
const session = this.context.store.getSession(sessionId);
|
|
286802
|
+
if (!session)
|
|
286803
|
+
throw new SessionApplicationError(404, `Session not found: ${sessionId}`);
|
|
286804
|
+
const lease = this.enterSessionOperation(session);
|
|
286805
|
+
try {
|
|
286806
|
+
return await work();
|
|
286807
|
+
} finally {
|
|
286808
|
+
lease.release();
|
|
286809
|
+
}
|
|
286810
|
+
}
|
|
285705
286811
|
async admitPrompt(sessionId, input) {
|
|
285706
286812
|
this.assertReady();
|
|
285707
286813
|
const session = this.context.store.getSession(sessionId);
|
|
@@ -285732,11 +286838,16 @@ class SessionApplicationService {
|
|
|
285732
286838
|
}
|
|
285733
286839
|
const items = inputItems(input);
|
|
285734
286840
|
let liveContent = sessionUserInputText(items);
|
|
285735
|
-
if (!hasAttachments && this.context.liveChildren.has(sessionId) && items.some((item) => item.type === "skill")) {
|
|
286841
|
+
if (!hasAttachments && this.context.liveChildren.has(sessionId) && items.some((item) => item.type === "skill" || item.type === "context")) {
|
|
285736
286842
|
const session = this.context.store.getSession(sessionId);
|
|
285737
|
-
if (!session
|
|
286843
|
+
if (!session)
|
|
286844
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
286845
|
+
const hasExplicitSkills = items.some((item) => item.type === "skill");
|
|
286846
|
+
if (hasExplicitSkills && !this.context.resolveSkillCatalog)
|
|
285738
286847
|
throw new Error("session_input_skill_catalog_unavailable");
|
|
285739
|
-
liveContent = materializeSessionInput(items, await this.context.resolveSkillCatalog(session))
|
|
286848
|
+
liveContent = materializeSessionInput(items, hasExplicitSkills ? await this.context.resolveSkillCatalog(session) : { resolvePath: () => {
|
|
286849
|
+
return;
|
|
286850
|
+
} }, conversationContextCatalog(this.context.store, sessionId)).instruction;
|
|
285740
286851
|
}
|
|
285741
286852
|
const live = hasAttachments ? undefined : await this.context.liveChildren.send(sessionId, {
|
|
285742
286853
|
id: input.id,
|
|
@@ -285957,7 +287068,11 @@ class SessionApplicationService {
|
|
|
285957
287068
|
const current = this.context.store.getSession(sessionId);
|
|
285958
287069
|
if (!current)
|
|
285959
287070
|
throw new SessionApplicationError(404, `Session not found: ${sessionId}`);
|
|
285960
|
-
const lease = this.context.operationGate.tryEnterBarrier({ kind: "session", sessionId, cwd: current.cwd }, () => true
|
|
287071
|
+
const lease = this.context.operationGate.tryEnterBarrier({ kind: "session", sessionId, cwd: current.cwd }, () => true, {
|
|
287072
|
+
operationId: randomUUID23(),
|
|
287073
|
+
operationName: "删除会话",
|
|
287074
|
+
startedAt: Date.now()
|
|
287075
|
+
});
|
|
285961
287076
|
if (!lease)
|
|
285962
287077
|
throw new SessionApplicationError(409, "Session is busy with another operation");
|
|
285963
287078
|
try {
|
|
@@ -285973,16 +287088,10 @@ class SessionApplicationService {
|
|
|
285973
287088
|
const deletedChildIds = [];
|
|
285974
287089
|
for (const child of children)
|
|
285975
287090
|
deletedChildIds.push(...await this.deleteSessionTree(child.id));
|
|
285976
|
-
const interruptedRunIds = [
|
|
285977
|
-
interrupted.activeRunId,
|
|
285978
|
-
...interrupted.queuedRunIds
|
|
285979
|
-
].filter((runId) => !!runId);
|
|
287091
|
+
const interruptedRunIds = [interrupted.activeRunId, ...interrupted.queuedRunIds].filter((runId) => !!runId);
|
|
285980
287092
|
await this.context.runEngine.waitForRuns(interruptedRunIds);
|
|
285981
287093
|
await this.context.agentPool.close(sessionId);
|
|
285982
|
-
return [
|
|
285983
|
-
...deletedChildIds,
|
|
285984
|
-
...this.context.store.deleteSessionTree(sessionId)
|
|
285985
|
-
];
|
|
287094
|
+
return [...deletedChildIds, ...this.context.store.deleteSessionTree(sessionId)];
|
|
285986
287095
|
} finally {
|
|
285987
287096
|
lease.release();
|
|
285988
287097
|
}
|
|
@@ -285994,7 +287103,11 @@ class SessionApplicationService {
|
|
|
285994
287103
|
throw new SessionApplicationError(404, `Session not found: ${sessionId}`);
|
|
285995
287104
|
if (current.status === "archived")
|
|
285996
287105
|
return current;
|
|
285997
|
-
const lease = this.context.operationGate.tryEnterBarrier({ kind: "session", sessionId, cwd: current.cwd }, () => true
|
|
287106
|
+
const lease = this.context.operationGate.tryEnterBarrier({ kind: "session", sessionId, cwd: current.cwd }, () => true, {
|
|
287107
|
+
operationId: randomUUID23(),
|
|
287108
|
+
operationName: "归档会话",
|
|
287109
|
+
startedAt: Date.now()
|
|
287110
|
+
});
|
|
285998
287111
|
if (!lease)
|
|
285999
287112
|
throw new SessionApplicationError(409, "Session is busy with another operation");
|
|
286000
287113
|
try {
|
|
@@ -286006,10 +287119,7 @@ class SessionApplicationService {
|
|
|
286006
287119
|
await liveInterrupt;
|
|
286007
287120
|
for (const child of children)
|
|
286008
287121
|
await this.archiveSessionTree(child.id);
|
|
286009
|
-
const interruptedRunIds = [
|
|
286010
|
-
interrupted.activeRunId,
|
|
286011
|
-
...interrupted.queuedRunIds
|
|
286012
|
-
].filter((runId) => !!runId);
|
|
287122
|
+
const interruptedRunIds = [interrupted.activeRunId, ...interrupted.queuedRunIds].filter((runId) => !!runId);
|
|
286013
287123
|
await this.context.runEngine.waitForRuns(interruptedRunIds);
|
|
286014
287124
|
await this.context.agentPool.close(sessionId);
|
|
286015
287125
|
const before = this.context.events.checkpoint();
|
|
@@ -286034,7 +287144,11 @@ class SessionApplicationService {
|
|
|
286034
287144
|
}
|
|
286035
287145
|
}
|
|
286036
287146
|
acquireSessionMutation(session, message) {
|
|
286037
|
-
const lease = this.context.operationGate.tryEnterBarrier({ kind: "session", sessionId: session.id, cwd: session.cwd }, () => !this.context.liveChildren.has(session.id) && !this.context.runEngine.hasWork(session.id) && !this.context.agentPool.hasActiveWorkForSession(session.id)
|
|
287147
|
+
const lease = this.context.operationGate.tryEnterBarrier({ kind: "session", sessionId: session.id, cwd: session.cwd }, () => !this.context.liveChildren.has(session.id) && !this.context.runEngine.hasWork(session.id) && !this.context.agentPool.hasActiveWorkForSession(session.id), {
|
|
287148
|
+
operationId: randomUUID23(),
|
|
287149
|
+
operationName: message,
|
|
287150
|
+
startedAt: Date.now()
|
|
287151
|
+
});
|
|
286038
287152
|
if (!lease)
|
|
286039
287153
|
throw new SessionApplicationError(409, message);
|
|
286040
287154
|
return lease;
|
|
@@ -286108,6 +287222,668 @@ var init_session_application_service = __esm(() => {
|
|
|
286108
287222
|
init_session_application_error();
|
|
286109
287223
|
});
|
|
286110
287224
|
|
|
287225
|
+
// ../../packages/server/src/application/session/goal-assessment-policy.ts
|
|
287226
|
+
function verifiedGoalEvidence(store, goal, assessment) {
|
|
287227
|
+
const messages = new Map(store.listMessages(goal.sessionId).map((message) => [message.id, message]));
|
|
287228
|
+
const parts = store.listMessageParts(goal.sessionId);
|
|
287229
|
+
const unique = new Map;
|
|
287230
|
+
for (const ref of assessment.evidenceRefs)
|
|
287231
|
+
unique.set(ref.messagePartId, ref);
|
|
287232
|
+
for (const requirement of assessment.requirements ?? []) {
|
|
287233
|
+
for (const ref of requirement.evidenceRefs)
|
|
287234
|
+
unique.set(ref.messagePartId, ref);
|
|
287235
|
+
}
|
|
287236
|
+
return [...unique.values()].flatMap((ref) => {
|
|
287237
|
+
if (ref.goalId !== goal.id || ref.revision !== goal.revision || ref.runId !== assessment.runId)
|
|
287238
|
+
return [];
|
|
287239
|
+
const part = parts.find((item) => item.id === ref.messagePartId);
|
|
287240
|
+
if (!part || messages.get(part.messageId)?.runId !== ref.runId || part.type !== "tool" || part.status !== "completed" || part.isError || part.output == null || part.toolName === "GoalAssessment")
|
|
287241
|
+
return [];
|
|
287242
|
+
return [part];
|
|
287243
|
+
});
|
|
287244
|
+
}
|
|
287245
|
+
function classifyGoalCompletion(assessment, verifiedPartIds) {
|
|
287246
|
+
const requirements = assessment.requirements ?? [];
|
|
287247
|
+
if (requirements.some((item) => item.status === "needs_user")) {
|
|
287248
|
+
return {
|
|
287249
|
+
kind: "waiting_user",
|
|
287250
|
+
reason: "请验收目标中需要主观判断的完成条件"
|
|
287251
|
+
};
|
|
287252
|
+
}
|
|
287253
|
+
const unfinished = requirements.some((item) => item.status === "incomplete") || Boolean(assessment.remainingWork?.length);
|
|
287254
|
+
if (unfinished) {
|
|
287255
|
+
return {
|
|
287256
|
+
kind: "continue",
|
|
287257
|
+
reason: assessment.nextStep ?? assessment.remainingWork?.[0] ?? "继续完成剩余要求"
|
|
287258
|
+
};
|
|
287259
|
+
}
|
|
287260
|
+
const allSatisfied = requirements.length > 0 && requirements.every((item) => item.status === "satisfied" && item.evidenceRefs.length > 0 && item.evidenceRefs.every((ref) => verifiedPartIds.has(ref.messagePartId)));
|
|
287261
|
+
return allSatisfied ? { kind: "completed" } : {
|
|
287262
|
+
kind: "waiting_user",
|
|
287263
|
+
reason: "完成审查缺少当前运行的有效证据,请验收目标结果"
|
|
287264
|
+
};
|
|
287265
|
+
}
|
|
287266
|
+
|
|
287267
|
+
// ../../packages/server/src/application/session/session-goal-service.ts
|
|
287268
|
+
class SessionGoalService {
|
|
287269
|
+
context;
|
|
287270
|
+
requests = new Map;
|
|
287271
|
+
constructor(context) {
|
|
287272
|
+
this.context = context;
|
|
287273
|
+
}
|
|
287274
|
+
waitTimers = new Map;
|
|
287275
|
+
get(sessionId) {
|
|
287276
|
+
this.requireSession(sessionId);
|
|
287277
|
+
return this.context.store.getCurrentGoal(sessionId) ?? null;
|
|
287278
|
+
}
|
|
287279
|
+
getRequest(sessionId, requestId) {
|
|
287280
|
+
this.requireSession(sessionId);
|
|
287281
|
+
const request = this.context.store.getGoalRequest(requestId);
|
|
287282
|
+
if (!request || request.sessionId !== sessionId)
|
|
287283
|
+
throw new SessionApplicationError(404, `Goal request not found: ${requestId}`);
|
|
287284
|
+
return request;
|
|
287285
|
+
}
|
|
287286
|
+
create(sessionId, input) {
|
|
287287
|
+
return this.command(sessionId, input.requestId, { operation: "create", ...input }, async () => {
|
|
287288
|
+
const replay = await this.replay(input.requestId);
|
|
287289
|
+
if (replay)
|
|
287290
|
+
return replay;
|
|
287291
|
+
const goal = this.context.store.transaction(() => {
|
|
287292
|
+
const created = this.context.store.createGoal({
|
|
287293
|
+
sessionId,
|
|
287294
|
+
objective: input.objective,
|
|
287295
|
+
maxAutoTurns: input.maxAutoTurns ?? DEFAULT_GOAL_AUTO_TURNS
|
|
287296
|
+
});
|
|
287297
|
+
this.persistRun(created, input.requestId, "initial", input);
|
|
287298
|
+
return created;
|
|
287299
|
+
});
|
|
287300
|
+
return this.finishDispatch(input.requestId, goal);
|
|
287301
|
+
});
|
|
287302
|
+
}
|
|
287303
|
+
update(sessionId, goalId, input) {
|
|
287304
|
+
return this.command(sessionId, input.requestId, { operation: "update", goalId, ...input }, async () => {
|
|
287305
|
+
const replay = await this.replay(input.requestId);
|
|
287306
|
+
if (replay)
|
|
287307
|
+
return replay;
|
|
287308
|
+
const request = this.context.store.getGoalRequest(input.requestId);
|
|
287309
|
+
let paused;
|
|
287310
|
+
if (request.result?.phase === "stopping") {
|
|
287311
|
+
paused = this.requireGoal(sessionId, goalId);
|
|
287312
|
+
if (paused.revision !== request.result.revision || paused.status !== "paused")
|
|
287313
|
+
throw new SessionApplicationError(409, "目标在停止期间已被修改,请重新提交");
|
|
287314
|
+
} else {
|
|
287315
|
+
this.assertOpen(this.requireGoal(sessionId, goalId));
|
|
287316
|
+
paused = this.context.store.transaction(() => {
|
|
287317
|
+
const changed = this.context.store.updateGoal(goalId, {
|
|
287318
|
+
expectedRevision: input.expectedRevision,
|
|
287319
|
+
status: "paused",
|
|
287320
|
+
reason: "正在更新目标"
|
|
287321
|
+
});
|
|
287322
|
+
this.context.store.settleGoalRequest(input.requestId, {
|
|
287323
|
+
status: "pending",
|
|
287324
|
+
goalId,
|
|
287325
|
+
result: { phase: "stopping", revision: changed.revision }
|
|
287326
|
+
});
|
|
287327
|
+
return changed;
|
|
287328
|
+
});
|
|
287329
|
+
}
|
|
287330
|
+
await this.stopRuns(paused, "目标正文已修改");
|
|
287331
|
+
const updated = this.context.store.transaction(() => {
|
|
287332
|
+
const goal = this.context.store.updateGoal(goalId, {
|
|
287333
|
+
expectedRevision: paused.revision,
|
|
287334
|
+
objective: input.objective,
|
|
287335
|
+
status: "active",
|
|
287336
|
+
noProgressCount: 0,
|
|
287337
|
+
blockerKey: null,
|
|
287338
|
+
currentRunId: null,
|
|
287339
|
+
reason: null,
|
|
287340
|
+
wait: null
|
|
287341
|
+
});
|
|
287342
|
+
this.persistRun(goal, input.requestId, "edit", input);
|
|
287343
|
+
return goal;
|
|
287344
|
+
});
|
|
287345
|
+
return this.finishDispatch(input.requestId, updated);
|
|
287346
|
+
});
|
|
287347
|
+
}
|
|
287348
|
+
action(sessionId, goalId, input) {
|
|
287349
|
+
return this.command(sessionId, input.requestId, { operation: "action", goalId, ...input }, async () => {
|
|
287350
|
+
const replay = await this.replay(input.requestId);
|
|
287351
|
+
if (replay)
|
|
287352
|
+
return replay;
|
|
287353
|
+
const goal = this.requireGoal(sessionId, goalId);
|
|
287354
|
+
this.assertOpen(goal);
|
|
287355
|
+
if (goal.revision !== input.expectedRevision)
|
|
287356
|
+
throw new SessionApplicationError(409, "目标已变化,请刷新后重试");
|
|
287357
|
+
if (input.action === "confirm" && (goal.status !== "waiting_user" || goal.wait?.kind !== "user" || !goal.wait.questionId.startsWith("goal-complete-") || input.questionId !== goal.wait.questionId))
|
|
287358
|
+
throw new SessionApplicationError(409, "当前目标没有等待这次验收");
|
|
287359
|
+
if (input.action === "resume")
|
|
287360
|
+
this.validateResume(goal, input);
|
|
287361
|
+
const updated = this.context.store.transaction(() => {
|
|
287362
|
+
const changed = this.context.store.updateGoal(goalId, {
|
|
287363
|
+
expectedRevision: input.expectedRevision,
|
|
287364
|
+
status: input.action === "cancel" ? "cancelled" : input.action === "pause" ? "paused" : input.action === "confirm" ? "completed" : "active",
|
|
287365
|
+
maxAutoTurns: goal.maxAutoTurns + (input.action === "resume" ? input.additionalAutoTurns ?? 0 : 0),
|
|
287366
|
+
...input.action === "resume" ? { noProgressCount: 0, blockerKey: null, currentRunId: null } : {},
|
|
287367
|
+
reason: null,
|
|
287368
|
+
wait: null
|
|
287369
|
+
});
|
|
287370
|
+
if (input.action === "resume")
|
|
287371
|
+
this.persistRun(changed, input.requestId, "resume", {
|
|
287372
|
+
items: [
|
|
287373
|
+
{
|
|
287374
|
+
type: "text",
|
|
287375
|
+
text: input.response ? `${changed.objective}
|
|
287376
|
+
|
|
287377
|
+
用户补充:${input.response}` : changed.objective
|
|
287378
|
+
}
|
|
287379
|
+
]
|
|
287380
|
+
});
|
|
287381
|
+
else
|
|
287382
|
+
this.context.store.settleGoalRequest(input.requestId, {
|
|
287383
|
+
status: "pending",
|
|
287384
|
+
goalId,
|
|
287385
|
+
result: { goal: changed, phase: "action-stopping" }
|
|
287386
|
+
});
|
|
287387
|
+
return changed;
|
|
287388
|
+
});
|
|
287389
|
+
if (input.action === "resume")
|
|
287390
|
+
return this.finishDispatch(input.requestId, updated);
|
|
287391
|
+
await this.stopRuns(updated, input.action === "cancel" ? "用户取消目标" : "用户停止目标");
|
|
287392
|
+
const stopped = this.context.store.getGoal(goalId);
|
|
287393
|
+
this.context.store.settleGoalRequest(input.requestId, {
|
|
287394
|
+
status: "completed",
|
|
287395
|
+
goalId,
|
|
287396
|
+
result: { goal: stopped }
|
|
287397
|
+
});
|
|
287398
|
+
return stopped;
|
|
287399
|
+
});
|
|
287400
|
+
}
|
|
287401
|
+
async settleRun(sessionId, runId) {
|
|
287402
|
+
const before = this.context.events.checkpoint();
|
|
287403
|
+
let nextRunId;
|
|
287404
|
+
let waitToObserve;
|
|
287405
|
+
try {
|
|
287406
|
+
this.context.store.transaction(() => {
|
|
287407
|
+
const run = this.context.store.getRun(runId);
|
|
287408
|
+
if (!run || run.sessionId !== sessionId || run.status === "pending" || run.status === "running" || run.metadata.goalSettled)
|
|
287409
|
+
return;
|
|
287410
|
+
this.context.store.finishGoalRun(runId);
|
|
287411
|
+
const goal = typeof run.metadata.goalId === "string" ? this.context.store.getGoal(run.metadata.goalId) : undefined;
|
|
287412
|
+
if (!goal || goal.sessionId !== sessionId || goal.status !== "active" || goal.revision !== run.metadata.goalRevision || goal.currentRunId && goal.currentRunId !== runId)
|
|
287413
|
+
return;
|
|
287414
|
+
this.context.store.updateRun(runId, {
|
|
287415
|
+
metadata: { goalSettled: true }
|
|
287416
|
+
});
|
|
287417
|
+
if (this.context.runEngine.hasUserWork(sessionId))
|
|
287418
|
+
return;
|
|
287419
|
+
let currentAssessment;
|
|
287420
|
+
const change = (patch) => this.context.store.updateGoal(goal.id, {
|
|
287421
|
+
expectedRevision: goal.revision,
|
|
287422
|
+
currentRunId: null,
|
|
287423
|
+
...currentAssessment ? { assessment: currentAssessment } : {},
|
|
287424
|
+
...patch
|
|
287425
|
+
});
|
|
287426
|
+
if (run.status !== "completed") {
|
|
287427
|
+
change({
|
|
287428
|
+
status: "paused",
|
|
287429
|
+
reason: run.error ?? "目标回合被中断或执行失败"
|
|
287430
|
+
});
|
|
287431
|
+
return;
|
|
287432
|
+
}
|
|
287433
|
+
let assessment;
|
|
287434
|
+
try {
|
|
287435
|
+
assessment = parseGoalAssessment(run.metadata.goalAssessment, {
|
|
287436
|
+
goalId: goal.id,
|
|
287437
|
+
revision: goal.revision,
|
|
287438
|
+
runId
|
|
287439
|
+
});
|
|
287440
|
+
} catch {
|
|
287441
|
+
change({ status: "paused", reason: "目标回合没有提交有效评估" });
|
|
287442
|
+
return;
|
|
287443
|
+
}
|
|
287444
|
+
currentAssessment = assessment;
|
|
287445
|
+
const verified = verifiedGoalEvidence(this.context.store, goal, assessment);
|
|
287446
|
+
const priorSignatures = new Set(this.context.store.goalEvidenceSignatures(goal.id));
|
|
287447
|
+
const verifiedSignatures = verified.map((part) => JSON.stringify([part.toolName, part.input, part.output]));
|
|
287448
|
+
const hasNewEvidence = verifiedSignatures.some((signature) => !priorSignatures.has(signature));
|
|
287449
|
+
this.context.store.recordGoalAssessment({
|
|
287450
|
+
goalId: goal.id,
|
|
287451
|
+
revision: goal.revision,
|
|
287452
|
+
runId,
|
|
287453
|
+
assessment: { ...assessment, verifiedSignatures }
|
|
287454
|
+
});
|
|
287455
|
+
const permission = this.context.store.listPermissionRequests({
|
|
287456
|
+
sessionId,
|
|
287457
|
+
status: "pending"
|
|
287458
|
+
})[0];
|
|
287459
|
+
if (permission) {
|
|
287460
|
+
change({
|
|
287461
|
+
status: "waiting_user",
|
|
287462
|
+
reason: "目标需要批准后才能继续",
|
|
287463
|
+
wait: { kind: "approval", permissionRequestId: permission.id }
|
|
287464
|
+
});
|
|
287465
|
+
return;
|
|
287466
|
+
}
|
|
287467
|
+
if (assessment.decision === "complete") {
|
|
287468
|
+
const disposition = classifyGoalCompletion(assessment, new Set(verified.map((part) => part.id)));
|
|
287469
|
+
if (disposition.kind === "completed") {
|
|
287470
|
+
change({
|
|
287471
|
+
status: "completed",
|
|
287472
|
+
evidence: assessment.evidence,
|
|
287473
|
+
reason: null
|
|
287474
|
+
});
|
|
287475
|
+
return;
|
|
287476
|
+
}
|
|
287477
|
+
if (disposition.kind === "waiting_user") {
|
|
287478
|
+
change({
|
|
287479
|
+
status: "waiting_user",
|
|
287480
|
+
evidence: assessment.evidence,
|
|
287481
|
+
reason: disposition.reason,
|
|
287482
|
+
wait: {
|
|
287483
|
+
kind: "user",
|
|
287484
|
+
questionId: `goal-complete-${runId}`,
|
|
287485
|
+
question: "现有结果是否满足目标的全部完成条件?"
|
|
287486
|
+
}
|
|
287487
|
+
});
|
|
287488
|
+
return;
|
|
287489
|
+
}
|
|
287490
|
+
assessment = {
|
|
287491
|
+
...assessment,
|
|
287492
|
+
decision: "continue",
|
|
287493
|
+
nextStep: disposition.reason
|
|
287494
|
+
};
|
|
287495
|
+
}
|
|
287496
|
+
if (assessment.decision === "waiting_user") {
|
|
287497
|
+
const wait = assessment.wait;
|
|
287498
|
+
if (wait?.kind === "external")
|
|
287499
|
+
change({
|
|
287500
|
+
status: "paused",
|
|
287501
|
+
reason: "本轮已经结束,外部任务仍需在恢复后重新检查"
|
|
287502
|
+
});
|
|
287503
|
+
else if (wait?.kind === "approval") {
|
|
287504
|
+
const actual = this.context.store.getPermissionRequest(wait.permissionRequestId);
|
|
287505
|
+
if (!actual || actual.sessionId !== sessionId || actual.runId !== runId)
|
|
287506
|
+
change({ status: "paused", reason: "评估引用的批准请求无效" });
|
|
287507
|
+
else
|
|
287508
|
+
change({
|
|
287509
|
+
status: "waiting_user",
|
|
287510
|
+
wait,
|
|
287511
|
+
reason: assessment.reason ?? "请处理批准请求"
|
|
287512
|
+
});
|
|
287513
|
+
} else
|
|
287514
|
+
change({
|
|
287515
|
+
status: "waiting_user",
|
|
287516
|
+
evidence: assessment.evidence,
|
|
287517
|
+
reason: assessment.reason ?? assessment.nextStep ?? assessment.progress,
|
|
287518
|
+
wait: {
|
|
287519
|
+
kind: "user",
|
|
287520
|
+
questionId: `goal-question-${runId}`,
|
|
287521
|
+
question: wait?.kind === "user" ? wait.question : assessment.reason ?? "请补充目标所需信息"
|
|
287522
|
+
}
|
|
287523
|
+
});
|
|
287524
|
+
return;
|
|
287525
|
+
}
|
|
287526
|
+
if (assessment.progressAssessment.kind === "waiting") {
|
|
287527
|
+
if (assessment.wait?.kind !== "external" || !this.context.waitVerifier) {
|
|
287528
|
+
change({ status: "paused", reason: "等待项缺少可验证的运行句柄" });
|
|
287529
|
+
return;
|
|
287530
|
+
}
|
|
287531
|
+
const check = this.context.waitVerifier.check(sessionId, assessment.wait);
|
|
287532
|
+
if (check.state === "running" || check.state === "unknown") {
|
|
287533
|
+
waitToObserve = change({
|
|
287534
|
+
status: "active",
|
|
287535
|
+
wait: assessment.wait,
|
|
287536
|
+
reason: assessment.progressAssessment.summary
|
|
287537
|
+
});
|
|
287538
|
+
} else if (check.state === "completed") {
|
|
287539
|
+
assessment = {
|
|
287540
|
+
...assessment,
|
|
287541
|
+
progressAssessment: {
|
|
287542
|
+
kind: "progress",
|
|
287543
|
+
summary: "等待的外部任务已经完成"
|
|
287544
|
+
},
|
|
287545
|
+
wait: undefined
|
|
287546
|
+
};
|
|
287547
|
+
} else {
|
|
287548
|
+
change({
|
|
287549
|
+
status: "paused",
|
|
287550
|
+
reason: check.state === "failed" ? check.reason : "等待的外部任务不存在或不属于当前会话"
|
|
287551
|
+
});
|
|
287552
|
+
return;
|
|
287553
|
+
}
|
|
287554
|
+
}
|
|
287555
|
+
if (waitToObserve) {
|
|
287556
|
+
return;
|
|
287557
|
+
}
|
|
287558
|
+
const madeProgress = assessment.progressAssessment.kind === "progress" && hasNewEvidence;
|
|
287559
|
+
const blockerKey = madeProgress ? undefined : assessment.progressAssessment.blockerKey ?? "unverified-progress";
|
|
287560
|
+
const noProgressCount = madeProgress ? 0 : goal.blockerKey === blockerKey ? goal.noProgressCount + 1 : 1;
|
|
287561
|
+
if (noProgressCount >= 3) {
|
|
287562
|
+
change({
|
|
287563
|
+
status: "blocked",
|
|
287564
|
+
noProgressCount,
|
|
287565
|
+
blockerKey,
|
|
287566
|
+
reason: assessment.reason ?? assessment.progressAssessment.summary
|
|
287567
|
+
});
|
|
287568
|
+
return;
|
|
287569
|
+
}
|
|
287570
|
+
if (goal.autoTurnsUsed >= goal.maxAutoTurns) {
|
|
287571
|
+
change({ status: "paused", reason: "目标自动续跑额度已用完" });
|
|
287572
|
+
return;
|
|
287573
|
+
}
|
|
287574
|
+
if (!assessment.nextStep?.trim()) {
|
|
287575
|
+
change({ status: "paused", reason: "评估没有给出可执行的下一步" });
|
|
287576
|
+
return;
|
|
287577
|
+
}
|
|
287578
|
+
if (this.context.store.listRuns(sessionId).some((candidate) => candidate.id !== runId && candidate.metadata.goalId === goal.id && (candidate.status === "pending" || candidate.status === "running")))
|
|
287579
|
+
return;
|
|
287580
|
+
const continued = change({
|
|
287581
|
+
noProgressCount,
|
|
287582
|
+
blockerKey: blockerKey ?? null,
|
|
287583
|
+
evidence: assessment.evidence,
|
|
287584
|
+
reason: null
|
|
287585
|
+
});
|
|
287586
|
+
const admitted = this.context.runEngine.persistGoalRun(sessionId, this.runInput(continued, `goal-${goal.id}-${goal.revision}-${runId}`, "continuation", {
|
|
287587
|
+
items: [
|
|
287588
|
+
{
|
|
287589
|
+
type: "text",
|
|
287590
|
+
text: `继续推进目标。下一步:${assessment.nextStep}`
|
|
287591
|
+
}
|
|
287592
|
+
]
|
|
287593
|
+
}));
|
|
287594
|
+
if (!this.context.store.recordGoalContinuation({
|
|
287595
|
+
goalId: goal.id,
|
|
287596
|
+
revision: goal.revision,
|
|
287597
|
+
previousRunId: runId,
|
|
287598
|
+
inputId: admitted.input.id,
|
|
287599
|
+
runId: admitted.run.id
|
|
287600
|
+
}))
|
|
287601
|
+
throw new Error("目标续跑已存在");
|
|
287602
|
+
nextRunId = admitted.run.id;
|
|
287603
|
+
});
|
|
287604
|
+
if (waitToObserve)
|
|
287605
|
+
this.observeExternalWait(waitToObserve);
|
|
287606
|
+
if (nextRunId) {
|
|
287607
|
+
this.context.runEngine.dispatchPersistedRun(nextRunId);
|
|
287608
|
+
this.context.store.markGoalContinuation(nextRunId, "dispatched");
|
|
287609
|
+
}
|
|
287610
|
+
} catch (error) {
|
|
287611
|
+
const run = this.context.store.getRun(runId);
|
|
287612
|
+
const goal = typeof run?.metadata.goalId === "string" ? this.context.store.getGoal(run.metadata.goalId) : undefined;
|
|
287613
|
+
if (goal?.status === "active") {
|
|
287614
|
+
this.context.store.updateGoal(goal.id, {
|
|
287615
|
+
expectedRevision: goal.revision,
|
|
287616
|
+
status: "paused",
|
|
287617
|
+
currentRunId: null,
|
|
287618
|
+
reason: `目标结算失败,请检查后继续:${error instanceof Error ? error.message : String(error)}`
|
|
287619
|
+
});
|
|
287620
|
+
this.context.runEngine.cancelGoalRuns(sessionId, goal.id, "目标结算失败");
|
|
287621
|
+
}
|
|
287622
|
+
} finally {
|
|
287623
|
+
this.context.events.publishSince(before);
|
|
287624
|
+
}
|
|
287625
|
+
}
|
|
287626
|
+
observeExternalWait(goal, attempt = 0) {
|
|
287627
|
+
const wait = goal.wait;
|
|
287628
|
+
if (wait?.kind !== "external" || !this.context.waitVerifier)
|
|
287629
|
+
return;
|
|
287630
|
+
this.clearWaitObserver(goal.id);
|
|
287631
|
+
const delay = [1000, 2000, 4000, 8000, 16000, 30000][Math.min(attempt, 5)];
|
|
287632
|
+
const timer = setTimeout(() => {
|
|
287633
|
+
this.waitTimers.delete(goal.id);
|
|
287634
|
+
const current = this.context.store.getGoal(goal.id);
|
|
287635
|
+
if (!current || current.status !== "active" || current.revision !== goal.revision || current.wait?.kind !== "external" || current.wait.handleId !== wait.handleId)
|
|
287636
|
+
return;
|
|
287637
|
+
const check = this.context.waitVerifier.check(current.sessionId, current.wait);
|
|
287638
|
+
if (check.state === "running" || check.state === "unknown") {
|
|
287639
|
+
this.observeExternalWait(current, attempt + 1);
|
|
287640
|
+
return;
|
|
287641
|
+
}
|
|
287642
|
+
const before = this.context.events.checkpoint();
|
|
287643
|
+
try {
|
|
287644
|
+
if (check.state !== "completed") {
|
|
287645
|
+
this.context.store.updateGoal(current.id, {
|
|
287646
|
+
expectedRevision: current.revision,
|
|
287647
|
+
status: "paused",
|
|
287648
|
+
wait: null,
|
|
287649
|
+
reason: check.state === "failed" ? check.reason : "等待的外部任务不存在或不属于当前会话"
|
|
287650
|
+
});
|
|
287651
|
+
return;
|
|
287652
|
+
}
|
|
287653
|
+
const continued = this.context.store.updateGoal(current.id, {
|
|
287654
|
+
expectedRevision: current.revision,
|
|
287655
|
+
status: "active",
|
|
287656
|
+
wait: null,
|
|
287657
|
+
reason: null
|
|
287658
|
+
});
|
|
287659
|
+
const inputId = `goal-wait-${continued.id}-${continued.revision}-${wait.handleId}`;
|
|
287660
|
+
const admitted = this.context.runEngine.persistGoalRun(continued.sessionId, this.runInput(continued, inputId, "continuation", {
|
|
287661
|
+
items: [
|
|
287662
|
+
{
|
|
287663
|
+
type: "text",
|
|
287664
|
+
text: "等待的外部任务已结束。检查其结果并继续推进目标。"
|
|
287665
|
+
}
|
|
287666
|
+
]
|
|
287667
|
+
}));
|
|
287668
|
+
if (this.context.store.recordGoalContinuation({
|
|
287669
|
+
goalId: continued.id,
|
|
287670
|
+
revision: continued.revision,
|
|
287671
|
+
previousRunId: `wait:${wait.runId}:${wait.handleId}`,
|
|
287672
|
+
inputId: admitted.input.id,
|
|
287673
|
+
runId: admitted.run.id
|
|
287674
|
+
})) {
|
|
287675
|
+
this.context.runEngine.dispatchPersistedRun(admitted.run.id);
|
|
287676
|
+
this.context.store.markGoalContinuation(admitted.run.id, "dispatched");
|
|
287677
|
+
}
|
|
287678
|
+
} catch (error) {
|
|
287679
|
+
const failed = this.context.store.getGoal(goal.id);
|
|
287680
|
+
if (failed?.status === "active") {
|
|
287681
|
+
this.context.store.updateGoal(failed.id, {
|
|
287682
|
+
expectedRevision: failed.revision,
|
|
287683
|
+
status: "paused",
|
|
287684
|
+
wait: null,
|
|
287685
|
+
reason: `恢复等待目标失败:${error instanceof Error ? error.message : String(error)}`
|
|
287686
|
+
});
|
|
287687
|
+
}
|
|
287688
|
+
} finally {
|
|
287689
|
+
this.context.events.publishSince(before);
|
|
287690
|
+
}
|
|
287691
|
+
}, delay);
|
|
287692
|
+
timer.unref?.();
|
|
287693
|
+
this.waitTimers.set(goal.id, { attempt, timer });
|
|
287694
|
+
}
|
|
287695
|
+
clearWaitObserver(goalId) {
|
|
287696
|
+
const current = this.waitTimers.get(goalId);
|
|
287697
|
+
if (!current)
|
|
287698
|
+
return;
|
|
287699
|
+
clearTimeout(current.timer);
|
|
287700
|
+
this.waitTimers.delete(goalId);
|
|
287701
|
+
}
|
|
287702
|
+
validateResume(goal, input) {
|
|
287703
|
+
if (!["paused", "blocked", "waiting_user"].includes(goal.status))
|
|
287704
|
+
throw new SessionApplicationError(409, `Goal cannot resume from ${goal.status}`);
|
|
287705
|
+
if (goal.maxAutoTurns + (input.additionalAutoTurns ?? 0) > MAX_GOAL_AUTO_TURNS)
|
|
287706
|
+
throw new SessionApplicationError(400, "自动续跑总额度最多为 1000");
|
|
287707
|
+
if (goal.autoTurnsUsed >= goal.maxAutoTurns + (input.additionalAutoTurns ?? 0))
|
|
287708
|
+
throw new SessionApplicationError(409, "请明确增加自动续跑额度");
|
|
287709
|
+
if (this.context.store.listRuns(goal.sessionId).some((run) => run.metadata.goalId === goal.id && (run.status === "pending" || run.status === "running")))
|
|
287710
|
+
throw new SessionApplicationError(409, "目标仍在停止,请稍后继续");
|
|
287711
|
+
if (goal.status === "blocked" && !input.response?.trim())
|
|
287712
|
+
throw new SessionApplicationError(409, "请说明阻塞条件发生了什么变化,再检查并继续");
|
|
287713
|
+
if (goal.status === "waiting_user") {
|
|
287714
|
+
if (goal.wait?.kind === "user" && (!input.response?.trim() || goal.wait.questionId !== input.questionId))
|
|
287715
|
+
throw new SessionApplicationError(409, "请先回答当前目标的问题");
|
|
287716
|
+
if (goal.wait?.kind === "approval") {
|
|
287717
|
+
const request = this.context.store.getPermissionRequest(goal.wait.permissionRequestId);
|
|
287718
|
+
if (request?.sessionId !== goal.sessionId || request.status !== "approved")
|
|
287719
|
+
throw new SessionApplicationError(409, "批准尚未通过,不能恢复目标");
|
|
287720
|
+
}
|
|
287721
|
+
if (!goal.wait || goal.wait.kind === "external")
|
|
287722
|
+
throw new SessionApplicationError(409, "等待状态尚未解除");
|
|
287723
|
+
}
|
|
287724
|
+
if (this.context.store.listPermissionRequests({
|
|
287725
|
+
sessionId: goal.sessionId,
|
|
287726
|
+
status: "pending"
|
|
287727
|
+
}).length)
|
|
287728
|
+
throw new SessionApplicationError(409, "请先处理未决批准请求");
|
|
287729
|
+
}
|
|
287730
|
+
command(sessionId, requestId, payload, work) {
|
|
287731
|
+
const fingerprint = JSON.stringify({ sessionId, ...payload });
|
|
287732
|
+
const pending = this.requests.get(requestId);
|
|
287733
|
+
if (pending) {
|
|
287734
|
+
if (pending.fingerprint !== fingerprint)
|
|
287735
|
+
return Promise.reject(new SessionApplicationError(409, "请求 ID 已用于不同操作"));
|
|
287736
|
+
return pending.promise;
|
|
287737
|
+
}
|
|
287738
|
+
const promise = this.context.sessions.withSessionOperation(sessionId, async () => {
|
|
287739
|
+
const before = this.context.events.checkpoint();
|
|
287740
|
+
try {
|
|
287741
|
+
this.context.store.beginGoalRequest({
|
|
287742
|
+
requestId,
|
|
287743
|
+
sessionId,
|
|
287744
|
+
fingerprint
|
|
287745
|
+
});
|
|
287746
|
+
return await work();
|
|
287747
|
+
} catch (error) {
|
|
287748
|
+
const request = this.context.store.getGoalRequest(requestId);
|
|
287749
|
+
if (request?.fingerprint === fingerprint && request.status !== "completed")
|
|
287750
|
+
this.context.store.settleGoalRequest(requestId, {
|
|
287751
|
+
status: request.result ? "pending" : "failed",
|
|
287752
|
+
goalId: request.goalId,
|
|
287753
|
+
result: request.result,
|
|
287754
|
+
error: error instanceof Error ? error.message : String(error)
|
|
287755
|
+
});
|
|
287756
|
+
if (error instanceof Error && (error.message === "session_goal_revision_conflict" || error.message === "session_goal_request_conflict" || error.message.includes("UNIQUE constraint failed")))
|
|
287757
|
+
throw new SessionApplicationError(409, error.message);
|
|
287758
|
+
throw error;
|
|
287759
|
+
} finally {
|
|
287760
|
+
this.context.events.publishSince(before);
|
|
287761
|
+
}
|
|
287762
|
+
}).finally(() => {
|
|
287763
|
+
if (this.requests.get(requestId)?.promise === promise)
|
|
287764
|
+
this.requests.delete(requestId);
|
|
287765
|
+
});
|
|
287766
|
+
this.requests.set(requestId, { fingerprint, promise });
|
|
287767
|
+
return promise;
|
|
287768
|
+
}
|
|
287769
|
+
async replay(requestId) {
|
|
287770
|
+
const request = this.context.store.getGoalRequest(requestId);
|
|
287771
|
+
if (request.status === "completed" && request.result?.goal)
|
|
287772
|
+
return request.result.goal;
|
|
287773
|
+
if (request.result?.phase === "action-stopping" && request.goalId) {
|
|
287774
|
+
const goal = this.context.store.getGoal(request.goalId);
|
|
287775
|
+
if (goal.revision !== request.result.goal.revision)
|
|
287776
|
+
throw new SessionApplicationError(409, "目标在停止期间已经变化,请刷新状态");
|
|
287777
|
+
await this.stopRuns(goal, "用户停止目标");
|
|
287778
|
+
const stopped = this.context.store.getGoal(goal.id);
|
|
287779
|
+
this.context.store.settleGoalRequest(requestId, {
|
|
287780
|
+
status: "completed",
|
|
287781
|
+
goalId: goal.id,
|
|
287782
|
+
result: { goal: stopped }
|
|
287783
|
+
});
|
|
287784
|
+
return stopped;
|
|
287785
|
+
}
|
|
287786
|
+
if (typeof request.result?.runId === "string" && request.goalId)
|
|
287787
|
+
return this.finishDispatch(requestId, this.context.store.getGoal(request.goalId));
|
|
287788
|
+
return;
|
|
287789
|
+
}
|
|
287790
|
+
persistRun(goal, requestId, kind, input) {
|
|
287791
|
+
const admitted = this.context.runEngine.persistGoalRun(goal.sessionId, this.runInput(goal, requestId, kind, input));
|
|
287792
|
+
this.context.store.settleGoalRequest(requestId, {
|
|
287793
|
+
status: "pending",
|
|
287794
|
+
goalId: goal.id,
|
|
287795
|
+
result: { goal, runId: admitted.run.id, inputId: admitted.input.id }
|
|
287796
|
+
});
|
|
287797
|
+
}
|
|
287798
|
+
runInput(goal, requestId, kind, input) {
|
|
287799
|
+
const metadata = {
|
|
287800
|
+
goalId: goal.id,
|
|
287801
|
+
goalRevision: goal.revision,
|
|
287802
|
+
goalRunKind: kind
|
|
287803
|
+
};
|
|
287804
|
+
return {
|
|
287805
|
+
id: requestId,
|
|
287806
|
+
delivery: "queue",
|
|
287807
|
+
items: input.items?.length ? input.items : [{ type: "text", text: goal.objective }],
|
|
287808
|
+
attachments: input.attachments,
|
|
287809
|
+
metadata,
|
|
287810
|
+
runMetadata: metadata
|
|
287811
|
+
};
|
|
287812
|
+
}
|
|
287813
|
+
finishDispatch(requestId, goal) {
|
|
287814
|
+
const request = this.context.store.getGoalRequest(requestId);
|
|
287815
|
+
const runId = request.result?.runId;
|
|
287816
|
+
if (typeof runId !== "string")
|
|
287817
|
+
throw new Error("目标请求缺少持久运行记录");
|
|
287818
|
+
const run = this.context.store.getRun(runId);
|
|
287819
|
+
if (!run || run.status === "failed" || run.status === "interrupted" || goal.status !== "active" || run.metadata.goalRevision !== goal.revision)
|
|
287820
|
+
throw new SessionApplicationError(409, "目标启动已中断,请刷新目标并明确继续");
|
|
287821
|
+
this.context.runEngine.dispatchPersistedRun(runId);
|
|
287822
|
+
this.context.store.settleGoalRequest(requestId, {
|
|
287823
|
+
status: "completed",
|
|
287824
|
+
goalId: goal.id,
|
|
287825
|
+
result: { ...request.result, goal }
|
|
287826
|
+
});
|
|
287827
|
+
return goal;
|
|
287828
|
+
}
|
|
287829
|
+
async stopRuns(goal, reason) {
|
|
287830
|
+
this.clearWaitObserver(goal.id);
|
|
287831
|
+
const before = this.context.events.checkpoint();
|
|
287832
|
+
const ids = this.context.runEngine.cancelGoalRuns(goal.sessionId, goal.id, reason);
|
|
287833
|
+
this.context.events.publishSince(before);
|
|
287834
|
+
await this.context.runEngine.waitForRuns(ids);
|
|
287835
|
+
if (this.context.store.listRuns(goal.sessionId).some((run) => ids.includes(run.id) && (run.status === "pending" || run.status === "running")))
|
|
287836
|
+
throw new SessionApplicationError(409, "目标尚未停止,请稍后重试");
|
|
287837
|
+
}
|
|
287838
|
+
requireSession(sessionId) {
|
|
287839
|
+
if (!this.context.store.getSession(sessionId))
|
|
287840
|
+
throw new SessionApplicationError(404, `Session not found: ${sessionId}`);
|
|
287841
|
+
}
|
|
287842
|
+
requireGoal(sessionId, goalId) {
|
|
287843
|
+
const goal = this.context.store.getGoal(goalId);
|
|
287844
|
+
if (!goal || goal.sessionId !== sessionId)
|
|
287845
|
+
throw new SessionApplicationError(404, `Goal not found: ${goalId}`);
|
|
287846
|
+
return goal;
|
|
287847
|
+
}
|
|
287848
|
+
assertOpen(goal) {
|
|
287849
|
+
if (goal.status === "completed" || goal.status === "cancelled")
|
|
287850
|
+
throw new SessionApplicationError(409, "已结束的目标不能再修改,请新建目标");
|
|
287851
|
+
}
|
|
287852
|
+
}
|
|
287853
|
+
var init_session_goal_service = __esm(() => {
|
|
287854
|
+
init_src4();
|
|
287855
|
+
init_session_application_error();
|
|
287856
|
+
});
|
|
287857
|
+
|
|
287858
|
+
// ../../packages/server/src/application/session/goal-wait-verifier.ts
|
|
287859
|
+
class GoalWaitVerifier {
|
|
287860
|
+
context;
|
|
287861
|
+
constructor(context) {
|
|
287862
|
+
this.context = context;
|
|
287863
|
+
}
|
|
287864
|
+
check(sessionId, wait) {
|
|
287865
|
+
const now = this.context.now?.() ?? Date.now();
|
|
287866
|
+
if (now >= wait.deadlineAt)
|
|
287867
|
+
return { state: "failed", reason: "等待外部任务超时" };
|
|
287868
|
+
try {
|
|
287869
|
+
const run = this.context.store.getRun(wait.handleId);
|
|
287870
|
+
if (run) {
|
|
287871
|
+
if (run.sessionId !== sessionId)
|
|
287872
|
+
return { state: "missing" };
|
|
287873
|
+
if (run.status === "pending" || run.status === "running")
|
|
287874
|
+
return { state: "running", checkedAt: now };
|
|
287875
|
+
return run.status === "completed" ? { state: "completed" } : { state: "failed", reason: run.error ?? "外部运行未成功完成" };
|
|
287876
|
+
}
|
|
287877
|
+
return this.context.liveChildren.resolveRootSessionId(wait.handleId) === sessionId ? { state: "running", checkedAt: now } : { state: "missing" };
|
|
287878
|
+
} catch (error) {
|
|
287879
|
+
return {
|
|
287880
|
+
state: "unknown",
|
|
287881
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
287882
|
+
};
|
|
287883
|
+
}
|
|
287884
|
+
}
|
|
287885
|
+
}
|
|
287886
|
+
|
|
286111
287887
|
// ../../packages/server/src/application/session/session-event-publisher.ts
|
|
286112
287888
|
class SessionEventPublisher {
|
|
286113
287889
|
store;
|
|
@@ -286312,6 +288088,8 @@ var init_usage = __esm(() => {
|
|
|
286312
288088
|
});
|
|
286313
288089
|
|
|
286314
288090
|
// ../../packages/server/src/application/session/session-maintenance-service.ts
|
|
288091
|
+
import { randomUUID as randomUUID24 } from "node:crypto";
|
|
288092
|
+
|
|
286315
288093
|
class SessionMaintenanceService {
|
|
286316
288094
|
context;
|
|
286317
288095
|
constructor(context) {
|
|
@@ -286364,7 +288142,7 @@ class SessionMaintenanceService {
|
|
|
286364
288142
|
const session = this.requireSession(sessionId);
|
|
286365
288143
|
this.rejectLiveChild(sessionId);
|
|
286366
288144
|
this.requireRuntime();
|
|
286367
|
-
const lease = this.acquireSessionBarrier(session.id, session.cwd, "Cannot compact while a run is active");
|
|
288145
|
+
const lease = this.acquireSessionBarrier(session.id, session.cwd, "压缩上下文", "Cannot compact while a run is active");
|
|
286368
288146
|
try {
|
|
286369
288147
|
const agent = await this.context.agentPool.acquireSession(sessionId);
|
|
286370
288148
|
const before = this.context.events.checkpoint();
|
|
@@ -286413,7 +288191,7 @@ class SessionMaintenanceService {
|
|
|
286413
288191
|
async rewind(sessionId, count) {
|
|
286414
288192
|
const session = this.requireSession(sessionId);
|
|
286415
288193
|
this.rejectLiveChild(sessionId);
|
|
286416
|
-
const lease = this.acquireSessionBarrier(session.id, session.cwd, "Cannot rewind while a run is active");
|
|
288194
|
+
const lease = this.acquireSessionBarrier(session.id, session.cwd, "回退会话", "Cannot rewind while a run is active");
|
|
286417
288195
|
try {
|
|
286418
288196
|
const rewound = rewindTranscript(this.context.store.listMessages(sessionId), this.context.store.listMessageParts(sessionId), count);
|
|
286419
288197
|
if (rewound.removed === 0) {
|
|
@@ -286440,7 +288218,7 @@ class SessionMaintenanceService {
|
|
|
286440
288218
|
const session = this.requireSession(sessionId);
|
|
286441
288219
|
this.rejectLiveChild(sessionId);
|
|
286442
288220
|
this.requireRuntime();
|
|
286443
|
-
const lease = this.context.operationGate.tryEnterBarrier({ kind: "cwd", cwd: session.cwd }, () => !this.context.runEngine.hasActiveRunsForCwd(session.cwd) && !this.context.agentPool.hasActiveWorkForCwd(session.cwd));
|
|
288221
|
+
const lease = this.context.operationGate.tryEnterBarrier({ kind: "cwd", cwd: session.cwd }, () => !this.context.runEngine.hasActiveRunsForCwd(session.cwd) && !this.context.agentPool.hasActiveWorkForCwd(session.cwd), maintenanceInfo("更新会话记忆"));
|
|
286444
288222
|
if (!lease) {
|
|
286445
288223
|
throw new SessionMaintenanceError(409, "Cannot remember while session runs are active for this cwd");
|
|
286446
288224
|
}
|
|
@@ -286470,15 +288248,18 @@ class SessionMaintenanceService {
|
|
|
286470
288248
|
throw new SessionMaintenanceError(409, "Cannot mutate or inspect a child runtime while it is live in its parent agent");
|
|
286471
288249
|
}
|
|
286472
288250
|
}
|
|
286473
|
-
acquireSessionBarrier(sessionId, cwd, message) {
|
|
286474
|
-
const lease = this.context.operationGate.tryEnterBarrier({ kind: "session", sessionId, cwd }, () => !this.context.runEngine.hasWork(sessionId) && !this.context.agentPool.hasActiveWorkForSession(sessionId));
|
|
288251
|
+
acquireSessionBarrier(sessionId, cwd, operationName, message) {
|
|
288252
|
+
const lease = this.context.operationGate.tryEnterBarrier({ kind: "session", sessionId, cwd }, () => !this.context.runEngine.hasWork(sessionId) && !this.context.agentPool.hasActiveWorkForSession(sessionId), maintenanceInfo(operationName));
|
|
286475
288253
|
if (!lease)
|
|
286476
288254
|
throw new SessionMaintenanceError(409, message);
|
|
286477
288255
|
return lease;
|
|
286478
288256
|
}
|
|
286479
288257
|
enterSessionOperation(session) {
|
|
286480
288258
|
try {
|
|
286481
|
-
return this.context.operationGate.enter({
|
|
288259
|
+
return this.context.operationGate.enter({
|
|
288260
|
+
sessionId: session.id,
|
|
288261
|
+
cwd: session.cwd
|
|
288262
|
+
});
|
|
286482
288263
|
} catch (error) {
|
|
286483
288264
|
if (error instanceof DaemonOperationUnavailableError) {
|
|
286484
288265
|
throw new SessionMaintenanceError(409, error.message);
|
|
@@ -286494,6 +288275,9 @@ class SessionMaintenanceService {
|
|
|
286494
288275
|
} catch {}
|
|
286495
288276
|
}
|
|
286496
288277
|
}
|
|
288278
|
+
function maintenanceInfo(operationName) {
|
|
288279
|
+
return { operationId: randomUUID24(), operationName, startedAt: Date.now() };
|
|
288280
|
+
}
|
|
286497
288281
|
function transcriptToPersonalizationMessages(messages, parts) {
|
|
286498
288282
|
const partsByMessage = new Map;
|
|
286499
288283
|
for (const part of parts) {
|
|
@@ -286901,7 +288685,7 @@ var init_run_coordinator = __esm(() => {
|
|
|
286901
288685
|
});
|
|
286902
288686
|
|
|
286903
288687
|
// ../../packages/server/src/application/session/session-run-engine.ts
|
|
286904
|
-
import { randomUUID as
|
|
288688
|
+
import { randomUUID as randomUUID25 } from "node:crypto";
|
|
286905
288689
|
function inputItems2(input) {
|
|
286906
288690
|
return input.items ? [...input.items] : [{ type: "text", text: input.content ?? "" }];
|
|
286907
288691
|
}
|
|
@@ -286916,6 +288700,46 @@ class SessionRunEngine {
|
|
|
286916
288700
|
constructor(context) {
|
|
286917
288701
|
this.context = context;
|
|
286918
288702
|
}
|
|
288703
|
+
persistGoalRun(sessionId, input) {
|
|
288704
|
+
if (!this.accepting)
|
|
288705
|
+
throw new Error("Session run engine is stopping");
|
|
288706
|
+
if (!this.context.agentPool.configured)
|
|
288707
|
+
throw new Error("请先配置模型,再启动目标");
|
|
288708
|
+
return this.context.store.admitPromptWithRun({
|
|
288709
|
+
prompt: { id: input.id, sessionId, delivery: "queue", items: input.items, attachments: normalizePromptAttachments(input.attachments), metadata: input.metadata },
|
|
288710
|
+
run: { metadata: input.runMetadata }
|
|
288711
|
+
}, this.context.attachmentLimits ? { attachmentLimits: this.context.attachmentLimits } : undefined);
|
|
288712
|
+
}
|
|
288713
|
+
dispatchPersistedRun(runId) {
|
|
288714
|
+
if (!this.accepting)
|
|
288715
|
+
throw new Error("Session run engine is stopping");
|
|
288716
|
+
const run = this.context.store.getRun(runId);
|
|
288717
|
+
if (!run || !run.inputId)
|
|
288718
|
+
throw new Error(`Session run not found: ${runId}`);
|
|
288719
|
+
if (this.runPromises.has(runId))
|
|
288720
|
+
return this.activeRunId(run.sessionId) === runId ? "running" : "queued";
|
|
288721
|
+
if (run.status !== "pending")
|
|
288722
|
+
return;
|
|
288723
|
+
return this.enqueueRun(run, run.inputId);
|
|
288724
|
+
}
|
|
288725
|
+
hasUserWork(sessionId) {
|
|
288726
|
+
return [...this.pendingAdmissions.values()].some((entry) => entry.sessionId === sessionId) || this.context.store.listRuns(sessionId).some((run) => (run.status === "pending" || run.status === "running") && (!run.metadata.goalRunKind || run.metadata.goalRunKind === "user"));
|
|
288727
|
+
}
|
|
288728
|
+
cancelGoalRuns(sessionId, goalId, reason, queuedOnly = false) {
|
|
288729
|
+
const ids = [];
|
|
288730
|
+
for (const run of this.context.store.listRuns(sessionId)) {
|
|
288731
|
+
if (run.metadata.goalId !== goalId || run.status !== "pending" && run.status !== "running")
|
|
288732
|
+
continue;
|
|
288733
|
+
if (queuedOnly && (run.metadata.goalRunKind !== "continuation" || this.activeRunId(sessionId) === run.id))
|
|
288734
|
+
continue;
|
|
288735
|
+
ids.push(run.id);
|
|
288736
|
+
this.interruptRun(sessionId, run.id, reason);
|
|
288737
|
+
if (this.activeRunId(sessionId) !== run.id)
|
|
288738
|
+
this.context.store.updateRun(run.id, { status: "interrupted", error: reason });
|
|
288739
|
+
this.context.store.markGoalContinuation(run.id, "cancelled");
|
|
288740
|
+
}
|
|
288741
|
+
return ids;
|
|
288742
|
+
}
|
|
286919
288743
|
activeRunId(sessionId) {
|
|
286920
288744
|
return this.runCoordinator.activeRunId(sessionId);
|
|
286921
288745
|
}
|
|
@@ -286979,7 +288803,7 @@ class SessionRunEngine {
|
|
|
286979
288803
|
replaceTranscriptAndAdmitPrompt(sessionId, messages, input) {
|
|
286980
288804
|
if (!this.accepting)
|
|
286981
288805
|
throw new Error("Session run engine is stopping");
|
|
286982
|
-
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(input.metadata?.traceId) ??
|
|
288806
|
+
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(input.metadata?.traceId) ?? randomUUID25();
|
|
286983
288807
|
const metadata = { ...input.metadata ?? {}, traceId };
|
|
286984
288808
|
const runMetadata = { ...input.runMetadata ?? {}, traceId };
|
|
286985
288809
|
const before = this.context.events.checkpoint();
|
|
@@ -287010,7 +288834,7 @@ class SessionRunEngine {
|
|
|
287010
288834
|
replaceLatestPrompt(sessionId, sourceMessageId, input) {
|
|
287011
288835
|
if (!this.accepting)
|
|
287012
288836
|
throw new Error("Session run engine is stopping");
|
|
287013
|
-
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(input.metadata?.traceId) ??
|
|
288837
|
+
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(input.metadata?.traceId) ?? randomUUID25();
|
|
287014
288838
|
const metadata = { ...input.metadata ?? {}, traceId };
|
|
287015
288839
|
const before = this.context.events.checkpoint();
|
|
287016
288840
|
const admitted = this.context.store.replaceLatestPromptWithAdmission({
|
|
@@ -287045,7 +288869,7 @@ class SessionRunEngine {
|
|
|
287045
288869
|
if (!sourceInput)
|
|
287046
288870
|
throw new Error(`Session input not found: ${inputId}`);
|
|
287047
288871
|
const existing = input.id ? this.context.store.getRun(input.id) : undefined;
|
|
287048
|
-
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(input.metadata?.traceId) ??
|
|
288872
|
+
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(input.metadata?.traceId) ?? randomUUID25();
|
|
287049
288873
|
const before = this.context.events.checkpoint();
|
|
287050
288874
|
const run = this.context.store.createReplayRun(inputId, {
|
|
287051
288875
|
id: input.id,
|
|
@@ -287121,6 +288945,11 @@ class SessionRunEngine {
|
|
|
287121
288945
|
admitPromptAndMaybeRun(sessionId, input) {
|
|
287122
288946
|
if (!this.accepting)
|
|
287123
288947
|
return Promise.reject(new Error("Session run engine is stopping"));
|
|
288948
|
+
if (!input.runMetadata?.goalId) {
|
|
288949
|
+
const goal = this.context.store.getCurrentGoal(sessionId);
|
|
288950
|
+
if (goal?.status === "active")
|
|
288951
|
+
this.cancelGoalRuns(sessionId, goal.id, "用户消息优先", true);
|
|
288952
|
+
}
|
|
287124
288953
|
if (!input.id)
|
|
287125
288954
|
return this.admitPrompt(sessionId, input);
|
|
287126
288955
|
const attachments = normalizePromptAttachments(input.attachments);
|
|
@@ -287152,7 +288981,7 @@ class SessionRunEngine {
|
|
|
287152
288981
|
async admitPrompt(sessionId, input) {
|
|
287153
288982
|
const attachments = normalizePromptAttachments(input.attachments);
|
|
287154
288983
|
const delivery = attachments.length > 0 && input.delivery === "steer" ? "queue" : input.delivery ?? "queue";
|
|
287155
|
-
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(input.metadata?.traceId) ??
|
|
288984
|
+
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(input.metadata?.traceId) ?? randomUUID25();
|
|
287156
288985
|
const metadata = { ...input.metadata ?? {}, traceId };
|
|
287157
288986
|
const runMetadata = { ...input.runMetadata ?? {}, traceId };
|
|
287158
288987
|
const existingInput = input.id ? this.context.store.getInput(input.id) : undefined;
|
|
@@ -287279,6 +289108,7 @@ class SessionRunEngine {
|
|
|
287279
289108
|
}
|
|
287280
289109
|
interruptSession(sessionId, reason) {
|
|
287281
289110
|
const before = this.context.events.checkpoint();
|
|
289111
|
+
this.pauseGoalForRun(this.activeRunId(sessionId));
|
|
287282
289112
|
const result = this.runCoordinator.interrupt(sessionId, reason);
|
|
287283
289113
|
if (result.interrupted) {
|
|
287284
289114
|
this.context.store.transaction(() => {
|
|
@@ -287304,6 +289134,8 @@ class SessionRunEngine {
|
|
|
287304
289134
|
}
|
|
287305
289135
|
interruptRun(sessionId, runId, reason) {
|
|
287306
289136
|
const before = this.context.events.checkpoint();
|
|
289137
|
+
if (this.activeRunId(sessionId) === runId)
|
|
289138
|
+
this.pauseGoalForRun(runId);
|
|
287307
289139
|
const result = this.runCoordinator.interruptRun(sessionId, runId, reason);
|
|
287308
289140
|
if (result.interrupted) {
|
|
287309
289141
|
this.context.store.transaction(() => {
|
|
@@ -287353,21 +289185,59 @@ class SessionRunEngine {
|
|
|
287353
289185
|
}
|
|
287354
289186
|
return result;
|
|
287355
289187
|
}
|
|
289188
|
+
pauseGoalForRun(runId) {
|
|
289189
|
+
const run = runId ? this.context.store.getRun(runId) : undefined;
|
|
289190
|
+
const goal = typeof run?.metadata.goalId === "string" ? this.context.store.getGoal(run.metadata.goalId) : undefined;
|
|
289191
|
+
if (goal?.status === "active")
|
|
289192
|
+
this.context.store.updateGoal(goal.id, { expectedRevision: goal.revision, status: "paused", reason: "用户停止了目标回合" });
|
|
289193
|
+
}
|
|
287356
289194
|
enqueueRun(run, inputId) {
|
|
287357
289195
|
const enqueued = this.runCoordinator.enqueue({
|
|
287358
289196
|
sessionId: run.sessionId,
|
|
287359
289197
|
runId: run.id,
|
|
287360
|
-
work: (workContext) =>
|
|
287361
|
-
|
|
287362
|
-
|
|
287363
|
-
|
|
287364
|
-
|
|
289198
|
+
work: async (workContext) => {
|
|
289199
|
+
await Promise.resolve();
|
|
289200
|
+
const beforeStart = this.context.events.checkpoint();
|
|
289201
|
+
const stored = this.context.store.getRun(run.id);
|
|
289202
|
+
const isUserRun = !stored.metadata.goalRunKind || stored.metadata.goalRunKind === "user";
|
|
289203
|
+
if (stored.metadata.goalRunKind === "continuation" && this.hasUserWork(run.sessionId)) {
|
|
289204
|
+
this.context.store.updateRun(run.id, { status: "interrupted", error: "用户消息优先" });
|
|
289205
|
+
this.context.store.markGoalContinuation(run.id, "cancelled");
|
|
289206
|
+
this.context.events.publishSince(beforeStart);
|
|
289207
|
+
return;
|
|
289208
|
+
}
|
|
289209
|
+
const goal = isUserRun ? this.context.store.getCurrentGoal(run.sessionId) : typeof stored.metadata.goalId === "string" ? this.context.store.getGoal(stored.metadata.goalId) : undefined;
|
|
289210
|
+
if (!isUserRun && !goal) {
|
|
289211
|
+
this.context.store.updateRun(run.id, { status: "interrupted", error: "目标已不存在" });
|
|
289212
|
+
this.context.events.publishSince(beforeStart);
|
|
289213
|
+
return;
|
|
289214
|
+
}
|
|
289215
|
+
if (goal && (goal.status === "active" || !isUserRun)) {
|
|
289216
|
+
const revision = isUserRun ? goal.revision : stored.metadata.goalRevision;
|
|
289217
|
+
const before = this.context.events.checkpoint();
|
|
289218
|
+
if (typeof revision !== "number" || !this.context.store.startGoalRun(goal.id, revision, run.id, stored.metadata.goalRunKind === "continuation")) {
|
|
289219
|
+
this.context.store.updateRun(run.id, { status: "interrupted", error: "目标已暂停或版本已变化" });
|
|
289220
|
+
this.context.events.publishSince(before);
|
|
289221
|
+
return;
|
|
289222
|
+
}
|
|
289223
|
+
if (isUserRun)
|
|
289224
|
+
this.context.store.updateRun(run.id, { metadata: { goalId: goal.id, goalRevision: revision, goalRunKind: "user" } });
|
|
289225
|
+
this.context.events.publishSince(before);
|
|
289226
|
+
}
|
|
289227
|
+
await this.context.runExecutor.execute({
|
|
289228
|
+
sessionId: run.sessionId,
|
|
289229
|
+
inputId,
|
|
289230
|
+
runId: run.id
|
|
289231
|
+
}, workContext);
|
|
289232
|
+
},
|
|
287365
289233
|
onSteerRejected: (input) => this.enqueueRejectedSteer(run.sessionId, input)
|
|
287366
289234
|
});
|
|
287367
|
-
const tracked = enqueued.promise.catch(() => {}).finally(() => {
|
|
289235
|
+
const tracked = enqueued.promise.catch(() => {}).finally(async () => {
|
|
287368
289236
|
if (this.runPromises.get(run.id) === tracked)
|
|
287369
289237
|
this.runPromises.delete(run.id);
|
|
289238
|
+
await this.context.settleGoalRun?.(run.sessionId, run.id);
|
|
287370
289239
|
});
|
|
289240
|
+
tracked.catch(() => {});
|
|
287371
289241
|
this.runPromises.set(run.id, tracked);
|
|
287372
289242
|
return enqueued.state;
|
|
287373
289243
|
}
|
|
@@ -287382,7 +289252,7 @@ class SessionRunEngine {
|
|
|
287382
289252
|
if (existing?.inputId === admitted.id)
|
|
287383
289253
|
return existing.id;
|
|
287384
289254
|
const before = this.context.events.checkpoint();
|
|
287385
|
-
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(admitted.metadata.traceId) ??
|
|
289255
|
+
const traceId = normalizeTraceId(input.traceId) ?? normalizeTraceId(admitted.metadata.traceId) ?? randomUUID25();
|
|
287386
289256
|
const run = this.context.store.createRun({
|
|
287387
289257
|
sessionId,
|
|
287388
289258
|
inputId: admitted.id,
|
|
@@ -287449,8 +289319,12 @@ class SessionRunExecutor {
|
|
|
287449
289319
|
const admitted = this.context.store.getInput(inputId);
|
|
287450
289320
|
if (!admitted)
|
|
287451
289321
|
throw new Error(`Session input not found: ${inputId}`);
|
|
289322
|
+
const storedRun = typeof this.context.store.getRun === "function" ? this.context.store.getRun(runId) : undefined;
|
|
289323
|
+
const hasStructuredContext = admitted.items.some((item) => item.type === "skill" || item.type === "context");
|
|
287452
289324
|
const hasExplicitSkills = admitted.items.some((item) => item.type === "skill");
|
|
287453
|
-
const materialized =
|
|
289325
|
+
const materialized = hasStructuredContext ? materializeSessionInput(admitted.items, hasExplicitSkills ? await resolveSkillCatalog(session, this.context.resolveSkillCatalog) : { resolvePath: () => {
|
|
289326
|
+
return;
|
|
289327
|
+
} }, conversationContextCatalog(this.context.store, sessionId)) : undefined;
|
|
287454
289328
|
if (admitted.attachments.length > 0) {
|
|
287455
289329
|
const acquiredAt = Date.now();
|
|
287456
289330
|
this.context.store.acquireAttachmentLeases({
|
|
@@ -287534,7 +289408,18 @@ class SessionRunExecutor {
|
|
|
287534
289408
|
if (materialized) {
|
|
287535
289409
|
submittedContent = applyMaterializedSessionInput(submittedContent, materialized);
|
|
287536
289410
|
}
|
|
289411
|
+
const goalId = typeof storedRun?.metadata?.goalId === "string" ? storedRun.metadata.goalId : undefined;
|
|
289412
|
+
const goalRevision = typeof storedRun?.metadata?.goalRevision === "number" ? storedRun.metadata.goalRevision : undefined;
|
|
289413
|
+
let goalBinding;
|
|
289414
|
+
if (goalId && goalRevision !== undefined) {
|
|
289415
|
+
const goal = this.context.store.getGoal(goalId);
|
|
289416
|
+
if (!goal || goal.sessionId !== sessionId || goal.revision !== goalRevision || goal.status !== "active") {
|
|
289417
|
+
throw new Error("session_goal_run_is_stale");
|
|
289418
|
+
}
|
|
289419
|
+
goalBinding = { goalId: goal.id, revision: goal.revision, objective: goal.objective };
|
|
289420
|
+
}
|
|
287537
289421
|
const run = agent.submitMessage(submittedContent, {
|
|
289422
|
+
...goalBinding ? { goal: goalBinding } : {},
|
|
287538
289423
|
inputItems: admitted.items,
|
|
287539
289424
|
signal: workContext.signal,
|
|
287540
289425
|
delivery: admitted.delivery,
|
|
@@ -287946,7 +289831,7 @@ function isTerminalRuntimeStatus(status) {
|
|
|
287946
289831
|
}
|
|
287947
289832
|
|
|
287948
289833
|
// ../../packages/server/src/application/session/background-shell-service.ts
|
|
287949
|
-
import { createHash as createHash11, randomUUID as
|
|
289834
|
+
import { createHash as createHash11, randomUUID as randomUUID26 } from "node:crypto";
|
|
287950
289835
|
import { resolve as resolve26 } from "node:path";
|
|
287951
289836
|
|
|
287952
289837
|
class BackgroundShellService {
|
|
@@ -288042,7 +289927,7 @@ class BackgroundShellService {
|
|
|
288042
289927
|
});
|
|
288043
289928
|
let eventCursor = this.context.events.checkpoint();
|
|
288044
289929
|
const reservation = this.context.store.reserveSessionTask({
|
|
288045
|
-
id: `task_${
|
|
289930
|
+
id: `task_${randomUUID26()}`,
|
|
288046
289931
|
sessionId: scope.sessionId,
|
|
288047
289932
|
requestNamespace,
|
|
288048
289933
|
requestId,
|
|
@@ -288872,13 +290757,13 @@ var init_channel_application_service = __esm(() => {
|
|
|
288872
290757
|
});
|
|
288873
290758
|
|
|
288874
290759
|
// ../../packages/server/src/application/workflow/session-workflow-run-repository.ts
|
|
288875
|
-
import { randomUUID as
|
|
290760
|
+
import { randomUUID as randomUUID27 } from "node:crypto";
|
|
288876
290761
|
|
|
288877
290762
|
class SessionWorkflowRunRepository {
|
|
288878
290763
|
store;
|
|
288879
290764
|
onDurableEvent;
|
|
288880
290765
|
repositoryKey;
|
|
288881
|
-
ownerId = `workflow-owner:${process.pid}:${
|
|
290766
|
+
ownerId = `workflow-owner:${process.pid}:${randomUUID27()}`;
|
|
288882
290767
|
listeners = new Map;
|
|
288883
290768
|
constructor(store, onDurableEvent) {
|
|
288884
290769
|
this.store = store;
|
|
@@ -290182,7 +292067,7 @@ var init_visual_tools = __esm(() => {
|
|
|
290182
292067
|
});
|
|
290183
292068
|
|
|
290184
292069
|
// ../../packages/server/src/application/daemon-application.ts
|
|
290185
|
-
import { randomUUID as
|
|
292070
|
+
import { randomUUID as randomUUID28 } from "node:crypto";
|
|
290186
292071
|
import { mkdir as mkdir14, rmdir as rmdir3 } from "node:fs/promises";
|
|
290187
292072
|
import { homedir as homedir11 } from "node:os";
|
|
290188
292073
|
import { dirname as dirname19, join as join40 } from "node:path";
|
|
@@ -290197,6 +292082,7 @@ class DaemonApplication {
|
|
|
290197
292082
|
permissions;
|
|
290198
292083
|
backgroundShells;
|
|
290199
292084
|
sessions;
|
|
292085
|
+
goals;
|
|
290200
292086
|
maintenance;
|
|
290201
292087
|
queries;
|
|
290202
292088
|
control;
|
|
@@ -290227,7 +292113,7 @@ class DaemonApplication {
|
|
|
290227
292113
|
const { store } = options;
|
|
290228
292114
|
this.store = store;
|
|
290229
292115
|
this.ownerLease = store.acquireApplicationOwner({
|
|
290230
|
-
ownerId: options.ownerId ?? `daemon:${process.pid}:${
|
|
292116
|
+
ownerId: options.ownerId ?? `daemon:${process.pid}:${randomUUID28()}`,
|
|
290231
292117
|
pid: process.pid,
|
|
290232
292118
|
staleAfterMs: options.ownerStaleAfterMs ?? 30000,
|
|
290233
292119
|
canTakeOver: (current) => !(options.ownerProcessAlive ?? isProcessAlive)(current.pid)
|
|
@@ -290284,6 +292170,7 @@ class DaemonApplication {
|
|
|
290284
292170
|
});
|
|
290285
292171
|
recoverProjectionSettlements(store);
|
|
290286
292172
|
store.interruptActiveRuns(DAEMON_RESTART_RUN_REASON);
|
|
292173
|
+
store.pauseActiveGoalsOnStartup();
|
|
290287
292174
|
store.terminalizeUnownedInputs(DAEMON_RESTART_INPUT_REASON);
|
|
290288
292175
|
store.expirePendingPermissionRequests(DAEMON_RESTART_PERMISSION_REASON);
|
|
290289
292176
|
store.finalizeClosingSessions();
|
|
@@ -290548,6 +292435,7 @@ class DaemonApplication {
|
|
|
290548
292435
|
}
|
|
290549
292436
|
});
|
|
290550
292437
|
this.runEngine = new SessionRunEngine({
|
|
292438
|
+
settleGoalRun: (sessionId, runId) => this.goals.settleRun(sessionId, runId),
|
|
290551
292439
|
store,
|
|
290552
292440
|
attachmentLimits: this.attachments.limits,
|
|
290553
292441
|
agentPool: this.agentPool,
|
|
@@ -290561,7 +292449,7 @@ class DaemonApplication {
|
|
|
290561
292449
|
if (!settings)
|
|
290562
292450
|
throw new Error("session_input_skill_catalog_unavailable");
|
|
290563
292451
|
const { skillRegistry } = await discoverOpenHarnessExtensions(session.cwd, settings);
|
|
290564
|
-
return materializeSessionInput(items, skillRegistry).instruction;
|
|
292452
|
+
return materializeSessionInput(items, skillRegistry, conversationContextCatalog(store, sessionId)).instruction;
|
|
290565
292453
|
}
|
|
290566
292454
|
});
|
|
290567
292455
|
this.control = new DaemonControlService({
|
|
@@ -290598,6 +292486,16 @@ class DaemonApplication {
|
|
|
290598
292486
|
return (await discoverOpenHarnessExtensions(session.cwd, settings)).skillRegistry;
|
|
290599
292487
|
}
|
|
290600
292488
|
});
|
|
292489
|
+
this.goals = new SessionGoalService({
|
|
292490
|
+
store,
|
|
292491
|
+
sessions: this.sessions,
|
|
292492
|
+
runEngine: this.runEngine,
|
|
292493
|
+
events: this.eventPublisher,
|
|
292494
|
+
waitVerifier: new GoalWaitVerifier({
|
|
292495
|
+
store,
|
|
292496
|
+
liveChildren: this.liveChildren
|
|
292497
|
+
})
|
|
292498
|
+
});
|
|
290601
292499
|
this.channels = new ChannelApplicationService({
|
|
290602
292500
|
store,
|
|
290603
292501
|
sessions: this.sessions,
|
|
@@ -290837,7 +292735,7 @@ class DaemonApplication {
|
|
|
290837
292735
|
const traceId = normalizeTraceId(run?.metadata.traceId);
|
|
290838
292736
|
if (traceId)
|
|
290839
292737
|
return traceId;
|
|
290840
|
-
const generated =
|
|
292738
|
+
const generated = randomUUID28();
|
|
290841
292739
|
if (run)
|
|
290842
292740
|
this.options.store.updateRun(runId, { metadata: { traceId: generated } });
|
|
290843
292741
|
return generated;
|
|
@@ -290947,6 +292845,7 @@ var init_daemon_application = __esm(() => {
|
|
|
290947
292845
|
init_daemon_control_service();
|
|
290948
292846
|
init_daemon_operation_gate();
|
|
290949
292847
|
init_session_application_service();
|
|
292848
|
+
init_session_goal_service();
|
|
290950
292849
|
init_session_maintenance_service();
|
|
290951
292850
|
init_session_run_engine();
|
|
290952
292851
|
init_session_run_executor();
|
|
@@ -291501,7 +293400,7 @@ var init_attachment4 = __esm(() => {
|
|
|
291501
293400
|
});
|
|
291502
293401
|
|
|
291503
293402
|
// ../../packages/server/src/http/routes/background-shell.ts
|
|
291504
|
-
import { randomUUID as
|
|
293403
|
+
import { randomUUID as randomUUID29 } from "node:crypto";
|
|
291505
293404
|
function createBackgroundShellRoutes(context) {
|
|
291506
293405
|
return new Hono2().post("/", async (c) => {
|
|
291507
293406
|
const body = await readJson(c);
|
|
@@ -291541,7 +293440,7 @@ function createBackgroundShellRoutes(context) {
|
|
|
291541
293440
|
}
|
|
291542
293441
|
function httpRequestId(headerValue, bodyValue) {
|
|
291543
293442
|
const supplied = headerValue?.trim() || (typeof bodyValue === "string" ? bodyValue.trim() : "");
|
|
291544
|
-
return `http:${supplied ||
|
|
293443
|
+
return `http:${supplied || randomUUID29()}`;
|
|
291545
293444
|
}
|
|
291546
293445
|
function errorMessage5(error) {
|
|
291547
293446
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -292736,6 +294635,46 @@ var init_session5 = __esm(() => {
|
|
|
292736
294635
|
init_support2();
|
|
292737
294636
|
});
|
|
292738
294637
|
|
|
294638
|
+
// ../../packages/server/src/http/routes/session-goal.ts
|
|
294639
|
+
function createSessionGoalRoutes(goals) {
|
|
294640
|
+
return new Hono2().get("/:sessionId/goal", (c) => {
|
|
294641
|
+
try {
|
|
294642
|
+
return jsonResponse({ goal: goals.get(c.req.param("sessionId")) });
|
|
294643
|
+
} catch (error) {
|
|
294644
|
+
return applicationErrorResponse(error, 400);
|
|
294645
|
+
}
|
|
294646
|
+
}).get("/:sessionId/goal-requests/:requestId", (c) => {
|
|
294647
|
+
try {
|
|
294648
|
+
return jsonResponse({ request: goals.getRequest(c.req.param("sessionId"), c.req.param("requestId")) });
|
|
294649
|
+
} catch (error) {
|
|
294650
|
+
return applicationErrorResponse(error, 400);
|
|
294651
|
+
}
|
|
294652
|
+
}).post("/:sessionId/goals", async (c) => {
|
|
294653
|
+
try {
|
|
294654
|
+
return jsonResponse({ goal: await goals.create(c.req.param("sessionId"), parseCreateSessionGoalInput(await readJson(c))) }, 201);
|
|
294655
|
+
} catch (error) {
|
|
294656
|
+
return applicationErrorResponse(error, 400);
|
|
294657
|
+
}
|
|
294658
|
+
}).patch("/:sessionId/goals/:goalId", async (c) => {
|
|
294659
|
+
try {
|
|
294660
|
+
return jsonResponse({ goal: await goals.update(c.req.param("sessionId"), c.req.param("goalId"), parseUpdateSessionGoalInput(await readJson(c))) });
|
|
294661
|
+
} catch (error) {
|
|
294662
|
+
return applicationErrorResponse(error, 400);
|
|
294663
|
+
}
|
|
294664
|
+
}).post("/:sessionId/goals/:goalId/actions", async (c) => {
|
|
294665
|
+
try {
|
|
294666
|
+
return jsonResponse({ goal: await goals.action(c.req.param("sessionId"), c.req.param("goalId"), parseGoalActionInput(await readJson(c))) });
|
|
294667
|
+
} catch (error) {
|
|
294668
|
+
return applicationErrorResponse(error, 400);
|
|
294669
|
+
}
|
|
294670
|
+
});
|
|
294671
|
+
}
|
|
294672
|
+
var init_session_goal = __esm(() => {
|
|
294673
|
+
init_dist4();
|
|
294674
|
+
init_src4();
|
|
294675
|
+
init_support2();
|
|
294676
|
+
});
|
|
294677
|
+
|
|
292739
294678
|
// ../../packages/server/src/http/routes/session-utility.ts
|
|
292740
294679
|
function maintenanceErrorResponse(error, fallbackStatus) {
|
|
292741
294680
|
return applicationErrorResponse(error, fallbackStatus);
|
|
@@ -293052,12 +294991,12 @@ var init_system = __esm(() => {
|
|
|
293052
294991
|
});
|
|
293053
294992
|
|
|
293054
294993
|
// ../../packages/server/src/http/control/request-trace-registry.ts
|
|
293055
|
-
import { randomUUID as
|
|
294994
|
+
import { randomUUID as randomUUID30 } from "node:crypto";
|
|
293056
294995
|
|
|
293057
294996
|
class RequestTraceRegistry {
|
|
293058
294997
|
traceIds = new WeakMap;
|
|
293059
294998
|
assign(request, incomingTraceId) {
|
|
293060
|
-
const traceId = normalizeTraceId(incomingTraceId) ??
|
|
294999
|
+
const traceId = normalizeTraceId(incomingTraceId) ?? randomUUID30();
|
|
293061
295000
|
this.traceIds.set(request, traceId);
|
|
293062
295001
|
return traceId;
|
|
293063
295002
|
}
|
|
@@ -293489,6 +295428,7 @@ class OpenHarnessHttpServer {
|
|
|
293489
295428
|
application: this.application.sessions,
|
|
293490
295429
|
traces: this.requestTraces
|
|
293491
295430
|
}));
|
|
295431
|
+
this.app.route("/sessions", createSessionGoalRoutes(this.application.goals));
|
|
293492
295432
|
this.app.route("/sessions", createRunExecutionRoutes({
|
|
293493
295433
|
application: this.application.sessions,
|
|
293494
295434
|
traces: this.requestTraces
|
|
@@ -293544,6 +295484,7 @@ var init_server = __esm(() => {
|
|
|
293544
295484
|
init_run_execution();
|
|
293545
295485
|
init_service();
|
|
293546
295486
|
init_session5();
|
|
295487
|
+
init_session_goal();
|
|
293547
295488
|
init_session_utility();
|
|
293548
295489
|
init_system();
|
|
293549
295490
|
init_request_trace_registry();
|
|
@@ -373393,7 +375334,7 @@ function convertClaudeAgentMarkdown(content) {
|
|
|
373393
375334
|
}
|
|
373394
375335
|
// ../../packages/plugin-converters/src/claude-code/converter.ts
|
|
373395
375336
|
init_src12();
|
|
373396
|
-
import { randomUUID as
|
|
375337
|
+
import { randomUUID as randomUUID31 } from "node:crypto";
|
|
373397
375338
|
import { access as access7, cp as cp3, mkdir as mkdir15, readFile as readFile20, rename as rename4, rm as rm8, writeFile as writeFile11 } from "node:fs/promises";
|
|
373398
375339
|
import { basename as basename14, dirname as dirname23, join as join47, relative as relative12, resolve as resolve29 } from "node:path";
|
|
373399
375340
|
var rel = (inspection, path) => relative12(inspection.root, path).replaceAll("\\", "/");
|
|
@@ -373520,7 +375461,7 @@ class ClaudeCodePluginConverter {
|
|
|
373520
375461
|
const output = resolve29(input.output);
|
|
373521
375462
|
if (await access7(output).then(() => true, () => false))
|
|
373522
375463
|
throw new Error(`Conversion output already exists: ${output}`);
|
|
373523
|
-
const temporary = `${output}.tmp-${
|
|
375464
|
+
const temporary = `${output}.tmp-${randomUUID31()}`;
|
|
373524
375465
|
await rm8(temporary, { recursive: true, force: true });
|
|
373525
375466
|
try {
|
|
373526
375467
|
await mkdir15(temporary, { recursive: true });
|
|
@@ -373584,7 +375525,7 @@ class ClaudeCodePluginConverter {
|
|
|
373584
375525
|
}
|
|
373585
375526
|
// ../../packages/plugin-converters/src/codex/converter.ts
|
|
373586
375527
|
init_src12();
|
|
373587
|
-
import { randomUUID as
|
|
375528
|
+
import { randomUUID as randomUUID33 } from "node:crypto";
|
|
373588
375529
|
import { copyFile as copyFile2, lstat as lstat10, mkdir as mkdir16, readFile as readFile23, realpath as realpath8, rename as rename5, rm as rm9, writeFile as writeFile12 } from "node:fs/promises";
|
|
373589
375530
|
import { dirname as dirname25, join as join49, relative as relative14, resolve as resolve31 } from "node:path";
|
|
373590
375531
|
|
|
@@ -373950,7 +375891,7 @@ class CodexPluginConverter {
|
|
|
373950
375891
|
metadata: { origin: "converted", sourceFormat: this.sourceFormat, converterId: this.id, converterVersion: this.version }
|
|
373951
375892
|
};
|
|
373952
375893
|
const report = { schemaVersion: 1, status: input.plan.items.some((item) => item.fidelity === "unsupported") ? "partial" : "success", items: input.plan.items, diagnostics: input.plan.diagnostics };
|
|
373953
|
-
const temporary = `${output}.tmp-${
|
|
375894
|
+
const temporary = `${output}.tmp-${randomUUID33()}`;
|
|
373954
375895
|
const copied = [];
|
|
373955
375896
|
try {
|
|
373956
375897
|
await mkdir16(temporary, { recursive: true });
|
|
@@ -375461,4 +377402,4 @@ program.command("doctor").description("Check environment and dependencies").acti
|
|
|
375461
377402
|
});
|
|
375462
377403
|
program.parse();
|
|
375463
377404
|
|
|
375464
|
-
//# debugId=
|
|
377405
|
+
//# debugId=4CB48FF1B6D52B3764756E2164756E21
|