@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/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 ? { intent: 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 ? { kind: 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]) => [key, deepFrozenCopy(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: { delta: event.delta, ...event.phase ? { phase: event.phase } : {} }
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 turnSystemPrompt = this.composeTurnSystemPrompt(memoryContext);
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: { name: "context_compaction", payload: event }
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 = this.visibleToolRegistry().getAll();
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 = this.visibleToolRegistry().get(toolUse.name);
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) => ({ toolUse, result: results[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.visibleToolRegistryView(),
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
- visibleToolRegistryView() {
229346
- const registry2 = this.visibleToolRegistry();
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 ? { intent: 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 ? { kind: 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: { total: workflows.length, byStatus: countByStatus(workflows) },
285207
- permissions: { total: permissions.length, byStatus: countByStatus(permissions) },
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({ sessionId, cwd: session.cwd });
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
- if ([...this.barriers.values()].some((barrier) => conflictsWithScope(barrier, scope))) {
285311
- throw new DaemonOperationUnavailableError("blocked");
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
- constructor(reason) {
285385
- super(reason === "closing" ? "Daemon is closing" : "Daemon operation is blocked by maintenance");
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
- instruction: skills.length ? `${prefix}
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 = skillInstructionPrefix(materialized.skills);
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 || !this.context.resolveSkillCatalog)
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)).instruction;
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({ sessionId: session.id, cwd: session.cwd });
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 randomUUID20 } from "node:crypto";
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) ?? randomUUID20();
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) ?? randomUUID20();
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) ?? randomUUID20();
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) ?? randomUUID20();
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) => this.context.runExecutor.execute({
287361
- sessionId: run.sessionId,
287362
- inputId,
287363
- runId: run.id
287364
- }, workContext),
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) ?? randomUUID20();
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 = hasExplicitSkills ? materializeSessionInput(admitted.items, await resolveSkillCatalog(session, this.context.resolveSkillCatalog)) : undefined;
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 randomUUID21 } from "node:crypto";
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_${randomUUID21()}`,
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 randomUUID23 } from "node:crypto";
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}:${randomUUID23()}`;
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 randomUUID24 } from "node:crypto";
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}:${randomUUID24()}`,
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 = randomUUID24();
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 randomUUID25 } from "node:crypto";
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 || randomUUID25()}`;
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 randomUUID26 } from "node:crypto";
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) ?? randomUUID26();
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 randomUUID27 } from "node:crypto";
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-${randomUUID27()}`;
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 randomUUID28 } from "node:crypto";
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-${randomUUID28()}`;
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=4BD474340A98612564756E2164756E21
377405
+ //# debugId=4CB48FF1B6D52B3764756E2164756E21