@ponythewhite/base-context 1.0.15 → 1.0.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/base-context-runtime/pyproject.toml +1 -1
  3. package/dist/base-context-runtime/src/rlm/bash.py +19 -0
  4. package/dist/base-context-runtime/src/rlm/job_watch.py +156 -0
  5. package/dist/base-context-runtime/src/rlm/repl.md +28 -6
  6. package/dist/base-context-runtime/src/rlm/repl.py +6 -1
  7. package/dist/base-context-runtime/test/test_bash.py +4 -4
  8. package/dist/base-context-runtime/test/test_job_watch.py +67 -0
  9. package/dist/base-context-runtime/uv.lock +1 -1
  10. package/dist/build-info.json +1 -1
  11. package/dist/bundle/{bundled-modules-O67MEO74.js → bundled-modules-2DMTK7VK.js} +2 -2
  12. package/dist/bundle/{chunk-RQFC34FM.js → chunk-MSH6QRP5.js} +1601 -820
  13. package/dist/bundle/{chunk-DGO66I3L.js → chunk-T2OK7SRV.js} +3 -2
  14. package/dist/bundle/{cli-main-2RER6PBE.js → cli-main-WL2L5IEQ.js} +2 -2
  15. package/dist/bundle/cli.js +1 -1
  16. package/dist/bundle/{main-YERLD3T4.js → main-XPIEIEQJ.js} +2 -2
  17. package/dist/core/agent-session.d.ts +2 -0
  18. package/dist/core/agent-session.d.ts.map +1 -1
  19. package/dist/core/agent-session.js +155 -9
  20. package/dist/core/agent-session.js.map +1 -1
  21. package/dist/core/history-index-worker.d.ts.map +1 -1
  22. package/dist/core/history-index-worker.js +22 -1
  23. package/dist/core/history-index-worker.js.map +1 -1
  24. package/dist/core/history-index.d.ts +2 -0
  25. package/dist/core/history-index.d.ts.map +1 -1
  26. package/dist/core/history-index.js.map +1 -1
  27. package/dist/core/job-watch.d.ts +120 -0
  28. package/dist/core/job-watch.d.ts.map +1 -0
  29. package/dist/core/job-watch.js +648 -0
  30. package/dist/core/job-watch.js.map +1 -0
  31. package/dist/core/kernel/repl-manager.d.ts +5 -1
  32. package/dist/core/kernel/repl-manager.d.ts.map +1 -1
  33. package/dist/core/kernel/repl-manager.js +52 -0
  34. package/dist/core/kernel/repl-manager.js.map +1 -1
  35. package/dist/core/kernel/shared.d.ts +12 -0
  36. package/dist/core/kernel/shared.d.ts.map +1 -1
  37. package/dist/core/kernel/shared.js.map +1 -1
  38. package/dist/core/prompts/rlm.d.ts.map +1 -1
  39. package/dist/core/prompts/rlm.js +49 -39
  40. package/dist/core/prompts/rlm.js.map +1 -1
  41. package/dist/core/session-manager.d.ts +2 -0
  42. package/dist/core/session-manager.d.ts.map +1 -1
  43. package/dist/core/session-manager.js +9 -1
  44. package/dist/core/session-manager.js.map +1 -1
  45. package/dist/core/tools/prime-context.d.ts.map +1 -1
  46. package/dist/core/tools/prime-context.js +1 -1
  47. package/dist/core/tools/prime-context.js.map +1 -1
  48. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  49. package/dist/modes/interactive/interactive-mode.js +2 -1
  50. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  51. package/dist/skills/agent-message/SKILL.md +8 -2
  52. package/dist/skills/bounded-inspect/SKILL.md +78 -0
  53. package/dist/skills/bounded-inspect/pyproject.toml +16 -0
  54. package/dist/skills/bounded-inspect/src/bounded_inspect/__init__.py +313 -0
  55. package/dist/skills/bounded-inspect/src/bounded_inspect/__main__.py +3 -0
  56. package/dist/skills/job-watch/SKILL.md +43 -0
  57. package/dist/skills/job-watch/pyproject.toml +13 -0
  58. package/dist/skills/job-watch/src/job_watch/__init__.py +61 -0
  59. package/dist/skills/rlm-heartbeat/SKILL.md +10 -6
  60. package/dist/utils/file-lines.d.ts.map +1 -1
  61. package/dist/utils/file-lines.js +6 -2
  62. package/dist/utils/file-lines.js.map +1 -1
  63. package/docs/rlm-runtime.md +4 -1
  64. package/docs/skills.md +18 -26
  65. package/package.json +4 -4
  66. package/skills/agent-message/SKILL.md +8 -2
  67. package/skills/bounded-inspect/SKILL.md +78 -0
  68. package/skills/bounded-inspect/pyproject.toml +16 -0
  69. package/skills/bounded-inspect/src/bounded_inspect/__init__.py +313 -0
  70. package/skills/bounded-inspect/src/bounded_inspect/__main__.py +3 -0
  71. package/skills/job-watch/SKILL.md +43 -0
  72. package/skills/job-watch/pyproject.toml +13 -0
  73. package/skills/job-watch/src/job_watch/__init__.py +61 -0
  74. package/skills/rlm-heartbeat/SKILL.md +10 -6
@@ -27,6 +27,7 @@ import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
27
27
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
28
28
  import { createGoalContextMessage, emptyGoalState, GOAL_CONTEXT_CUSTOM_TYPE, GOAL_CONTEXT_PREVIEW_LABEL, GOAL_SKILL_NAME, GOAL_STATE_CUSTOM_TYPE, goalHostResponse, goalTokenDeltaForUsage, isPersistedGoalState, normalizeGoalState, validateGoalBudget, validateGoalObjective, } from "./goals.js";
29
29
  import { captureNativeBranchRequests, captureNativeCompactionRequests, captureNativePlannerRequests, captureNativeReviewerRequests, InferenceCoordinator, takeNativeInferenceAuthSource, } from "./inference-coordinator.js";
30
+ import { JOB_WATCH_STATE, JobWatchController } from "./job-watch.js";
30
31
  import { snapshotPathIn } from "./kernel/state-snapshot.js";
31
32
  import { convertToLlm, createCompactionOutcomeMessage, createHeartbeatPromptMessage, createRefinementOutcomeMessage, createRlmChildFailureMessage, createRlmChildTerminalNoticeMessage, createSessionSlashCommandMessage, createSessionSlashCommandResultMessage, HARNESS_SNAPSHOT_CUSTOM_TYPE, HEARTBEAT_PROMPT_CUSTOM_TYPE, HEARTBEAT_PROMPT_PREVIEW_LABEL, IPYTHON_STATE_RESTORED_CUSTOM_TYPE, isSessionSlashCommandMessage, RLM_CHILD_FAILURE_CUSTOM_TYPE, RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE, } from "./messages.js";
32
33
  import { throwIfPromptAdmissionCancelled } from "./prompt-admission.js";
@@ -35,6 +36,7 @@ import { appendGlobalRefinement, applyRefinementProposal, formatHarnessStateForP
35
36
  import { getRecoveryCompactionAuthorization, PublicContextBudgetError } from "./request-view-selection.js";
36
37
  import { resolveConfigValue } from "./resolve-config-value.js";
37
38
  import { assertResourceCurrent } from "./resource-view.js";
39
+ import { retainToolOutput } from "./retained-tool-output.js";
38
40
  import { createDefaultRlmSubagentSessionName, createRlmDeleteSubagentHostHandler, createRlmFindModelsHostHandler, createRlmListSubagentsHostHandler, createRlmRunHostHandler, findRlmModelMatches, normalizeRequestedRlmSubagentModel, normalizeRequestedRlmSubagentSessionName, normalizeRequestedRlmSubagentThinkingLevel, } from "./rlm-runtime.js";
39
41
  import { captureSelectedSkill, captureSkillDescriptor, readSkillSelection, sameSelectedSkills, selectedSkillBlock, selectedSkillIdentity, } from "./selected-skills.js";
40
42
  import { createNativeRecoveryRefusal, DEFAULT_NATIVE_RECOVERY_LIMITS, NativeRecoveryBudgetRefusal, NativeRecoveryCursorStore, parseNativeRecoveryInput, recoverCapturedHistory, } from "./selective-recovery.js";
@@ -328,6 +330,7 @@ export class AgentSession {
328
330
  _goalStateRevision = 0;
329
331
  _goalAccountingStartedAt = undefined;
330
332
  _goalContinuationAwaitsRlmWork = false;
333
+ _jobWatchController;
331
334
  _goalAccountedAssistantMessages = new WeakSet();
332
335
  _goalAbortInProgress = false;
333
336
  _autonomousState;
@@ -1110,6 +1113,10 @@ export class AgentSession {
1110
1113
  activeToolNames: this._initialActiveToolNames,
1111
1114
  includeAllExtensionTools: true,
1112
1115
  });
1116
+ if (bootstrap.jobWatchState)
1117
+ await this._getJobWatchController().restore(bootstrap.jobWatchState);
1118
+ if (bootstrap.jobWatchUnavailable)
1119
+ this._surfaceSessionInputError(new Error(bootstrap.jobWatchUnavailable));
1113
1120
  if (this._goalState.status === "active" &&
1114
1121
  this._includeGoals &&
1115
1122
  !this.getActiveToolNames().includes("ipython")) {
@@ -1625,8 +1632,28 @@ export class AgentSession {
1625
1632
  !isPersistedRlmMaxDepthState(hydrated.entry.data))
1626
1633
  throw new Error("Bootstrap RLM depth source is unavailable or ineligible");
1627
1634
  rlmMaxDepth = hydrated.entry.data;
1635
+ remaining -= bootstrap.rlmMaxDepth.locator.length;
1636
+ }
1637
+ let jobWatchState;
1638
+ let jobWatchUnavailable = bootstrap.jobWatchUnavailable
1639
+ ? `Monitoring unavailable: optional job-watch bootstrap candidate budget exceeded. Inspect ${this.sessionManager.getSessionFile()}; no watches were resumed.`
1640
+ : undefined;
1641
+ if (bootstrap.jobWatchState) {
1642
+ if (bootstrap.jobWatchState.locator.length >
1643
+ Math.min(remaining, 64 * 1024 + 1024, Math.floor(maxSourceBytes / 2) + 1024)) {
1644
+ jobWatchUnavailable = `Monitoring unavailable: optional job-watch state exceeds the existing source budget. Inspect ${this.sessionManager.getSessionFile()} entry ${bootstrap.jobWatchState.id}; no watches were resumed.`;
1645
+ }
1646
+ else {
1647
+ const hydrated = await view.hydrateEntry(bootstrap.jobWatchState.id, remaining);
1648
+ if (hydrated?.entry.type === "custom" &&
1649
+ hydrated.entry.customType === JOB_WATCH_STATE &&
1650
+ hydrated.source.retention !== "retained-import")
1651
+ jobWatchState = hydrated.entry.data;
1652
+ }
1628
1653
  }
1629
1654
  return {
1655
+ jobWatchState,
1656
+ jobWatchUnavailable,
1630
1657
  goalState,
1631
1658
  goalSeedable: bootstrap.goalSeedable,
1632
1659
  rlmMaxDepth,
@@ -1675,6 +1702,8 @@ export class AgentSession {
1675
1702
  return true;
1676
1703
  }
1677
1704
  async _reloadBranchRuntimeState() {
1705
+ this._jobWatchController?.dispose();
1706
+ this._jobWatchController = undefined;
1678
1707
  this._contextMode = await this._readContextMode();
1679
1708
  const bootstrap = this.sessionManager.isPersisted()
1680
1709
  ? await this._readRuntimeBootstrap()
@@ -2123,7 +2152,10 @@ export class AgentSession {
2123
2152
  async _resumeGoalContinuationAfterRlmWork() {
2124
2153
  if (!this._goalContinuationAwaitsRlmWork)
2125
2154
  return;
2126
- if (this._disposed || this._disposing || this._hasUnsettledRlmQuiescenceWork())
2155
+ if (this._disposed ||
2156
+ this._disposing ||
2157
+ this._hasUnsettledRlmQuiescenceWork() ||
2158
+ this._jobWatchController?.isParked())
2127
2159
  return;
2128
2160
  if (this._goalState.status !== "active" || !this._goalState.objective) {
2129
2161
  this._goalContinuationAwaitsRlmWork = false;
@@ -3002,7 +3034,9 @@ export class AgentSession {
3002
3034
  : undefined;
3003
3035
  }
3004
3036
  async _queueAutonomousContinuationForThresholdCompaction(message, owner = this._captureCompactionOwner(this.agent.signal), capture = this._captureThresholdAutonomousOwner()) {
3005
- if (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed())
3037
+ if (!this._isCompactionOwnerCurrent(owner) ||
3038
+ !this._contextOptimizationAllowed() ||
3039
+ this._jobWatchController?.isParked())
3006
3040
  return undefined;
3007
3041
  const queued = this._queuedAutonomousThresholdContinuations.get(message);
3008
3042
  if (queued && this._checkpointActionPending(queued))
@@ -3059,7 +3093,7 @@ export class AgentSession {
3059
3093
  return undefined;
3060
3094
  if (message.stopReason === "error" || message.stopReason === "aborted")
3061
3095
  return undefined;
3062
- if (owner.goal.status !== "active" || !owner.goal.objective)
3096
+ if (owner.goal.status !== "active" || !owner.goal.objective || this._jobWatchController?.isParked())
3063
3097
  return undefined;
3064
3098
  const queued = this._queuedGoalThresholdContinuation;
3065
3099
  if (queued && this._checkpointActionPending(queued))
@@ -3548,6 +3582,8 @@ export class AgentSession {
3548
3582
  if (this._goalState.status !== "active" || !this._goalState.objective) {
3549
3583
  return { kind: "finish" };
3550
3584
  }
3585
+ if (this._jobWatchController?.isParked())
3586
+ return { kind: "wait_for_owned_work" };
3551
3587
  // Delegating and ending the turn is correct behavior; retain the existing wakeup owner.
3552
3588
  if (this._hasUnsettledRlmQuiescenceWork()) {
3553
3589
  this._goalContinuationAwaitsRlmWork = true;
@@ -3590,6 +3626,8 @@ export class AgentSession {
3590
3626
  return this._stoppedContinuationOutcome(signal);
3591
3627
  if (this.queuedActionCount > 0)
3592
3628
  return { kind: "finish" };
3629
+ if (this._jobWatchController?.isParked())
3630
+ return { kind: "wait_for_owned_work" };
3593
3631
  const owner = this._captureGoalContinuationOwner(signal);
3594
3632
  const arrivalEpoch = this._sessionInputArrivalEpoch;
3595
3633
  const goalSnapshot = owner.goal;
@@ -4412,6 +4450,13 @@ export class AgentSession {
4412
4450
  await drain(() => this._agentEventQueue);
4413
4451
  await drain(() => this._goalResumeOperation);
4414
4452
  await drain(() => this._waitForChildUsageWrites());
4453
+ if (this._jobWatchController) {
4454
+ const undelivered = new Set(this._actionStore
4455
+ .unfinishedActions()
4456
+ .filter((action) => action.queueKey && action.payload.kind === "turn" && !primaryDeliveryRecord(action).durable)
4457
+ .map((action) => action.queueKey));
4458
+ await drain(() => this._jobWatchController?.settleShutdown(undelivered));
4459
+ }
4415
4460
  await drain(() => this.dispose());
4416
4461
  }
4417
4462
  catch (error) {
@@ -4460,6 +4505,7 @@ export class AgentSession {
4460
4505
  }
4461
4506
  this.requests.stopAdmission();
4462
4507
  this._disposed = true;
4508
+ this._jobWatchController?.dispose();
4463
4509
  for (const run of this._unsettledRlmChildRuns)
4464
4510
  run.suppressTerminalNotice = true;
4465
4511
  for (const controller of this._rlmQuiescenceWaitAborts)
@@ -4812,10 +4858,10 @@ export class AgentSession {
4812
4858
  /** Persist mutable advice before the request owner captures its source and epoch ACK boundary. */
4813
4859
  async _appendHarnessSnapshotIfChanged() {
4814
4860
  const manager = this.sessionManager;
4815
- let leafId = manager.getLeafId();
4816
- const sourceIsCurrent = manager.captureCompactionSourceOwner();
4861
+ const sourceIsCurrent = manager.captureCompactionContentOwner();
4862
+ let ownAppends = 0;
4817
4863
  const assertCurrent = () => {
4818
- if (this._disposed || this.sessionManager !== manager || !sourceIsCurrent() || manager.getLeafId() !== leafId)
4864
+ if (this._disposed || this.sessionManager !== manager || !sourceIsCurrent(ownAppends))
4819
4865
  throw new Error("Harness snapshot source changed before request ownership");
4820
4866
  };
4821
4867
  let previous;
@@ -4844,8 +4890,9 @@ export class AgentSession {
4844
4890
  });
4845
4891
  if (previous === content)
4846
4892
  return assertCurrent;
4847
- const entryId = await manager.appendCustomMessageEntryWithRollback(HARNESS_SNAPSHOT_CUSTOM_TYPE, content, false);
4848
- if (this._disposed || this.sessionManager !== manager || !sourceIsCurrent() || manager.getLeafId() !== entryId)
4893
+ await manager.appendCustomMessageEntryWithRollback(HARNESS_SNAPSHOT_CUSTOM_TYPE, content, false);
4894
+ ownAppends++;
4895
+ if (this._disposed || this.sessionManager !== manager || !sourceIsCurrent(ownAppends))
4849
4896
  throw new Error("Harness snapshot source changed during append");
4850
4897
  if (!manager.isPersisted())
4851
4898
  this.agent.state.messages.push({
@@ -4855,7 +4902,6 @@ export class AgentSession {
4855
4902
  display: false,
4856
4903
  timestamp: Date.now(),
4857
4904
  });
4858
- leafId = entryId;
4859
4905
  return assertCurrent;
4860
4906
  }
4861
4907
  _refreshExtensionSystemPrompt(extensionPrompt, baseSnapshot) {
@@ -7065,6 +7111,7 @@ export class AgentSession {
7065
7111
  this._advanceCheckpointPauseEpoch();
7066
7112
  this._notifySessionInputCheckpointChange();
7067
7113
  this._flushDeferredRlmTerminalNotices();
7114
+ void this._jobWatchController?.flushPending().catch((error) => this._surfaceSessionInputError(error));
7068
7115
  this._scheduleGoalContinuationAfterRlmWork();
7069
7116
  this._scheduleSessionInputPump();
7070
7117
  },
@@ -7181,6 +7228,7 @@ export class AgentSession {
7181
7228
  this._sessionInputPumpEpoch++;
7182
7229
  this._notifySessionInputCheckpointChange();
7183
7230
  this._flushDeferredRlmTerminalNotices();
7231
+ void this._jobWatchController?.flushPending().catch((error) => this._surfaceSessionInputError(error));
7184
7232
  }
7185
7233
  /** Resume the scheduler after requestAbort/abortForUpdateRestart suspended it; owned pause leases are unaffected. */
7186
7234
  resumeQueuedWork() {
@@ -10027,6 +10075,75 @@ export class AgentSession {
10027
10075
  return createNativeRecoveryRefusal("unavailable", "captured_history_unavailable", responseBytes);
10028
10076
  }
10029
10077
  }
10078
+ _getJobWatchController() {
10079
+ if (this._jobWatchController?.isCurrent())
10080
+ return this._jobWatchController;
10081
+ this._jobWatchController?.dispose();
10082
+ const manager = this.sessionManager;
10083
+ const ownsSource = manager.captureCompactionSourceOwner();
10084
+ const controller = new JobWatchController({
10085
+ sessionId: manager.getSessionId(),
10086
+ sessionFile: manager.getSessionFile(),
10087
+ current: () => !this._disposed && !this._disposing && this.sessionManager === manager && ownsSource(),
10088
+ goalId: () => this._goalState.goalId,
10089
+ persist: async (state) => {
10090
+ if (this.sessionManager !== manager || !ownsSource())
10091
+ return;
10092
+ await manager.appendCustomEntry(JOB_WATCH_STATE, state);
10093
+ },
10094
+ waitForDelivery: true,
10095
+ stateBudgetBytes: Math.min(64 * 1024, Math.floor(this.settingsManager.getCanonicalContextLimits().maxSourceBytes / 2)),
10096
+ probe: async (request) => {
10097
+ const kernel = await this._ipythonKernelProvisioner?.ensure();
10098
+ if (!kernel?.jobWatchProbe)
10099
+ throw new Error("Kernel job_watch_probe_v1 is unavailable");
10100
+ const result = await kernel.jobWatchProbe({
10101
+ watchId: request.id,
10102
+ generation: request.generation,
10103
+ resourceId: request.resource_id,
10104
+ jobId: request.job_id,
10105
+ completionSource: request.completion_source,
10106
+ command: request.command ?? null,
10107
+ timeoutMs: request.timeout_ms,
10108
+ });
10109
+ await controller.observe({ id: request.id, generation: request.generation, ...result });
10110
+ },
10111
+ cancelProbe: (id) => this._ipythonKernelProvisioner?.manager?.cancelJobWatchProbe?.(id),
10112
+ retain: async (output) => {
10113
+ const directory = manager.getSessionArtifactDir();
10114
+ if (!directory)
10115
+ return undefined;
10116
+ const retained = await retainToolOutput(directory, [output], false);
10117
+ return join(directory, retained.artifactId);
10118
+ },
10119
+ onError: (error) => this._surfaceSessionInputError(error),
10120
+ admit: (text, eventId) => {
10121
+ if (this._sessionInputAdmissionPauses.size)
10122
+ return false;
10123
+ const content = `[job-watch] ${text}`;
10124
+ const admission = this._admitSessionInput(this._createPreparedTurnAction("followUp", content, undefined, {
10125
+ message: {
10126
+ role: "custom",
10127
+ customType: "job_watch_event",
10128
+ content,
10129
+ display: true,
10130
+ timestamp: Date.now(),
10131
+ },
10132
+ queueKey: eventId,
10133
+ resumeIfIdle: !this._sessionInputPumpSuspended,
10134
+ }), { wake: !this._sessionInputPumpSuspended });
10135
+ if (admission.ticket)
10136
+ void admission.ticket.delivered
10137
+ .then((outcome) => outcome.status === "delivered"
10138
+ ? controller.acknowledge(eventId)
10139
+ : controller.releaseDelivery(eventId, true), () => controller.releaseDelivery(eventId, false))
10140
+ .catch((error) => this._surfaceSessionInputError(error));
10141
+ return admission.accepted;
10142
+ },
10143
+ });
10144
+ this._jobWatchController = controller;
10145
+ return controller;
10146
+ }
10030
10147
  _createKernelHostHandlers() {
10031
10148
  const handlers = {
10032
10149
  prime_context: async (payload, context) => {
@@ -10073,6 +10190,35 @@ export class AgentSession {
10073
10190
  handlers[type] = async (payload) => this.handleRlmHeartbeatHostRequest(type, payload);
10074
10191
  }
10075
10192
  }
10193
+ for (const type of ["watch", "status", "park", "unregister", "observation"]) {
10194
+ handlers[`job_watch.${type}`] = async (payload) => {
10195
+ if (this._disposed || this._disposing)
10196
+ throw new Error("Job watch source owner changed");
10197
+ if (type === "observation" && !this._jobWatchController?.isCurrent())
10198
+ return { ignored: true };
10199
+ const controller = this._getJobWatchController();
10200
+ switch (type) {
10201
+ case "watch":
10202
+ return { ...(await controller.watch(payload)) };
10203
+ case "status":
10204
+ return controller.status(typeof payload.id === "string" ? payload.id : undefined);
10205
+ case "park":
10206
+ if (!Array.isArray(payload.ids) || !payload.ids.every((id) => typeof id === "string"))
10207
+ throw new Error("park requires watch ids");
10208
+ return controller.park(payload.ids);
10209
+ case "unregister":
10210
+ return controller.unregister(String(payload.id));
10211
+ default:
10212
+ if (typeof payload.id !== "string" ||
10213
+ typeof payload.generation !== "string" ||
10214
+ !payload.result ||
10215
+ typeof payload.result !== "object")
10216
+ throw new Error("Invalid job watch observation");
10217
+ await controller.observe({ ...payload.result, id: payload.id, generation: payload.generation });
10218
+ return {};
10219
+ }
10220
+ };
10221
+ }
10076
10222
  const visibleKernelSkillNames = new Set(this._modelVisibleSkills()
10077
10223
  .filter((skill) => !skill.disableModelInvocation)
10078
10224
  .map((skill) => skill.name));