@skaile/workspaces 4.19.0 → 4.21.0

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 (159) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/app-sdk/index.js +1 -1
  3. package/dist/{asset-feeds-VXK6SHWK.js → asset-feeds-HKPNPO7N.js} +4 -4
  4. package/dist/{asset-feeds-VXK6SHWK.js.map → asset-feeds-HKPNPO7N.js.map} +1 -1
  5. package/dist/asset-manager/index.js +1 -1
  6. package/dist/bridge/drivers/claude-sdk.js +160 -5
  7. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  8. package/dist/bridge/drivers/codex.js +2 -2
  9. package/dist/bridge/drivers/continue.js +3 -3
  10. package/dist/bridge/drivers/echo.js +3 -3
  11. package/dist/bridge/drivers/gemini.js +5 -5
  12. package/dist/bridge/drivers/goose.js +3 -3
  13. package/dist/bridge/drivers/omp.js +20 -4
  14. package/dist/bridge/drivers/omp.js.map +1 -1
  15. package/dist/bridge/drivers/opencode.js +3 -3
  16. package/dist/bridge/drivers/qwen.js +5 -5
  17. package/dist/bridge/index.js +5 -5
  18. package/dist/bridge/src/drivers/claude-context-usage.d.ts +104 -0
  19. package/dist/bridge/src/drivers/claude-context-usage.d.ts.map +1 -0
  20. package/dist/bridge/src/drivers/claude-sdk.d.ts +13 -1
  21. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  22. package/dist/bridge/src/drivers/omp.d.ts +8 -1
  23. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  24. package/dist/bridge/src/types.d.ts +16 -1
  25. package/dist/bridge/src/types.d.ts.map +1 -1
  26. package/dist/{chunk-PQE2MYB6.js → chunk-5FMWNSAQ.js} +3 -3
  27. package/dist/{chunk-PQE2MYB6.js.map → chunk-5FMWNSAQ.js.map} +1 -1
  28. package/dist/{chunk-YUH46KA7.js → chunk-5YDCUHJI.js} +3 -3
  29. package/dist/{chunk-YUH46KA7.js.map → chunk-5YDCUHJI.js.map} +1 -1
  30. package/dist/{chunk-UF4AEO54.js → chunk-AEOHSR27.js} +3 -3
  31. package/dist/{chunk-UF4AEO54.js.map → chunk-AEOHSR27.js.map} +1 -1
  32. package/dist/{chunk-J3K5O6XA.js → chunk-EJU2TOGT.js} +3 -3
  33. package/dist/{chunk-J3K5O6XA.js.map → chunk-EJU2TOGT.js.map} +1 -1
  34. package/dist/{chunk-6V3DMJPL.js → chunk-ES4E6RDZ.js} +3 -3
  35. package/dist/{chunk-6V3DMJPL.js.map → chunk-ES4E6RDZ.js.map} +1 -1
  36. package/dist/{chunk-RYIWFV67.js → chunk-EUGEEYGD.js} +2 -2
  37. package/dist/{chunk-RYIWFV67.js.map → chunk-EUGEEYGD.js.map} +1 -1
  38. package/dist/{chunk-EPSCLN5W.js → chunk-FELWDKLQ.js} +3 -3
  39. package/dist/{chunk-EPSCLN5W.js.map → chunk-FELWDKLQ.js.map} +1 -1
  40. package/dist/{chunk-T6QGP5HN.js → chunk-HA674IQL.js} +6 -6
  41. package/dist/{chunk-T6QGP5HN.js.map → chunk-HA674IQL.js.map} +1 -1
  42. package/dist/{chunk-25BOOOSM.js → chunk-I4VIRPHS.js} +3 -3
  43. package/dist/{chunk-25BOOOSM.js.map → chunk-I4VIRPHS.js.map} +1 -1
  44. package/dist/{chunk-FEEAYDKF.js → chunk-IZAN5MHL.js} +3 -3
  45. package/dist/{chunk-FEEAYDKF.js.map → chunk-IZAN5MHL.js.map} +1 -1
  46. package/dist/{chunk-XAKGLR4Y.js → chunk-ODIJJXXB.js} +6 -6
  47. package/dist/{chunk-XAKGLR4Y.js.map → chunk-ODIJJXXB.js.map} +1 -1
  48. package/dist/{chunk-66MJRB6K.js → chunk-OPSKLUB4.js} +2 -2
  49. package/dist/{chunk-66MJRB6K.js.map → chunk-OPSKLUB4.js.map} +1 -1
  50. package/dist/{chunk-EBYSCP6J.js → chunk-R3EU2FFW.js} +4 -4
  51. package/dist/{chunk-EBYSCP6J.js.map → chunk-R3EU2FFW.js.map} +1 -1
  52. package/dist/{chunk-P6S5K7AI.js → chunk-RBTVXXD5.js} +3 -3
  53. package/dist/{chunk-P6S5K7AI.js.map → chunk-RBTVXXD5.js.map} +1 -1
  54. package/dist/{chunk-TOXPRXAK.js → chunk-RLACUE4X.js} +3 -3
  55. package/dist/{chunk-TOXPRXAK.js.map → chunk-RLACUE4X.js.map} +1 -1
  56. package/dist/{chunk-RGB45PIL.js → chunk-RTD5KAM4.js} +17 -2
  57. package/dist/chunk-RTD5KAM4.js.map +1 -0
  58. package/dist/{chunk-VXY6LSQ3.js → chunk-RZ2YIFT6.js} +6 -6
  59. package/dist/{chunk-VXY6LSQ3.js.map → chunk-RZ2YIFT6.js.map} +1 -1
  60. package/dist/{chunk-QQ3G5N7X.js → chunk-S5A5MVJN.js} +4 -4
  61. package/dist/chunk-S5A5MVJN.js.map +1 -0
  62. package/dist/{chunk-7WVPAQPE.js → chunk-TVLQTO7E.js} +7 -4
  63. package/dist/chunk-TVLQTO7E.js.map +1 -0
  64. package/dist/{chunk-EEODEEKX.js → chunk-XBMCUMZT.js} +4 -4
  65. package/dist/{chunk-EEODEEKX.js.map → chunk-XBMCUMZT.js.map} +1 -1
  66. package/dist/{chunk-S4R3WNRF.js → chunk-YEQ3BXOY.js} +3 -3
  67. package/dist/{chunk-S4R3WNRF.js.map → chunk-YEQ3BXOY.js.map} +1 -1
  68. package/dist/{chunk-66WUZ3XL.js → chunk-ZDSZGV5F.js} +7 -7
  69. package/dist/{chunk-66WUZ3XL.js.map → chunk-ZDSZGV5F.js.map} +1 -1
  70. package/dist/{chunk-W2SDSDR7.js → chunk-ZJEQFNKE.js} +599 -11
  71. package/dist/chunk-ZJEQFNKE.js.map +1 -0
  72. package/dist/cli/index.js +35 -35
  73. package/dist/connectors/index.js +7 -7
  74. package/dist/connectors-shared/index.js +2 -2
  75. package/dist/{ensure-sources-WYXFJWUO.js → ensure-sources-MUS622KB.js} +4 -4
  76. package/dist/{ensure-sources-WYXFJWUO.js.map → ensure-sources-MUS622KB.js.map} +1 -1
  77. package/dist/factory-assets/connectors/box.js +7 -7
  78. package/dist/factory-assets/connectors/deploy.js +7 -7
  79. package/dist/factory-assets/connectors/devserver.js +7 -7
  80. package/dist/factory-assets/connectors/flow/adapter.js +7 -7
  81. package/dist/factory-assets/connectors/flow/run-flow.js +8 -8
  82. package/dist/factory-assets/connectors/flow.js +7 -7
  83. package/dist/factory-assets/connectors/git.js +7 -7
  84. package/dist/factory-assets/connectors/gmail.js +7 -7
  85. package/dist/factory-assets/connectors/googledrive.js +7 -7
  86. package/dist/factory-assets/connectors/local.js +7 -7
  87. package/dist/factory-assets/connectors/mattermost.js +7 -7
  88. package/dist/factory-assets/connectors/memory.js +7 -7
  89. package/dist/factory-assets/connectors/minio.js +7 -7
  90. package/dist/factory-assets/connectors/postgres.js +7 -7
  91. package/dist/factory-assets/connectors/s3.js +7 -7
  92. package/dist/factory-assets/connectors/sharepoint.js +7 -7
  93. package/dist/factory-assets/connectors/sqlite.js +7 -7
  94. package/dist/factory-assets/connectors/static-server.js +7 -7
  95. package/dist/factory-assets/connectors/tunnel.js +7 -7
  96. package/dist/factory-assets/connectors/webdav.js +7 -7
  97. package/dist/factory-assets/connectors/xstate-store.js +7 -7
  98. package/dist/factory-assets/connectors/xstate.js +7 -7
  99. package/dist/{helpers-TANA2HQT.js → helpers-V3IJWB75.js} +4 -4
  100. package/dist/{helpers-TANA2HQT.js.map → helpers-V3IJWB75.js.map} +1 -1
  101. package/dist/{library-publish-JQNTMKZG.js → library-publish-TXJM76SD.js} +6 -6
  102. package/dist/{library-publish-JQNTMKZG.js.map → library-publish-TXJM76SD.js.map} +1 -1
  103. package/dist/{open-library-NKZ4HJJ6.js → open-library-ORTV2RUE.js} +5 -5
  104. package/dist/{open-library-NKZ4HJJ6.js.map → open-library-ORTV2RUE.js.map} +1 -1
  105. package/dist/{project-AEAM2ZEW.js → project-GI2A75UN.js} +5 -5
  106. package/dist/{project-AEAM2ZEW.js.map → project-GI2A75UN.js.map} +1 -1
  107. package/dist/runner/index.js +11 -11
  108. package/dist/runner/src/compaction/orchestrator.d.ts +12 -0
  109. package/dist/runner/src/compaction/orchestrator.d.ts.map +1 -1
  110. package/dist/runner/src/context-usage/collector.d.ts +83 -0
  111. package/dist/runner/src/context-usage/collector.d.ts.map +1 -0
  112. package/dist/runner/src/context-usage/compose.d.ts +51 -0
  113. package/dist/runner/src/context-usage/compose.d.ts.map +1 -0
  114. package/dist/runner/src/context-usage/estimator.d.ts +13 -0
  115. package/dist/runner/src/context-usage/estimator.d.ts.map +1 -0
  116. package/dist/runner/src/context-usage/index.d.ts +6 -0
  117. package/dist/runner/src/context-usage/index.d.ts.map +1 -0
  118. package/dist/runner/src/context-usage/skill-listings.d.ts +8 -0
  119. package/dist/runner/src/context-usage/skill-listings.d.ts.map +1 -0
  120. package/dist/runner/src/context-usage/transcript-tracker.d.ts +35 -0
  121. package/dist/runner/src/context-usage/transcript-tracker.d.ts.map +1 -0
  122. package/dist/runner/src/resource-handler.d.ts.map +1 -1
  123. package/dist/runner/src/serve.d.ts.map +1 -1
  124. package/dist/sdk/asset-manager.js +1 -1
  125. package/dist/sdk/bridge.js +5 -5
  126. package/dist/sdk/index.js +11 -11
  127. package/dist/sdk/runner.js +11 -11
  128. package/dist/sdk/session.js +2 -2
  129. package/dist/sdk/store.js +1 -1
  130. package/dist/sdk/types.js +1 -1
  131. package/dist/session/index.js +2 -2
  132. package/dist/{setup-Q7ACRV72.js → setup-GLCLE36X.js} +10 -10
  133. package/dist/{setup-Q7ACRV72.js.map → setup-GLCLE36X.js.map} +1 -1
  134. package/dist/{source-QXQ3NO46.js → source-N6EKFFH5.js} +6 -6
  135. package/dist/{source-QXQ3NO46.js.map → source-N6EKFFH5.js.map} +1 -1
  136. package/dist/{source-manifest-publish-UKWCZA2M.js → source-manifest-publish-BDMY4B4B.js} +7 -7
  137. package/dist/{source-manifest-publish-UKWCZA2M.js.map → source-manifest-publish-BDMY4B4B.js.map} +1 -1
  138. package/dist/store/index.js +1 -1
  139. package/dist/store/src/resource-client.d.ts +5 -2
  140. package/dist/store/src/resource-client.d.ts.map +1 -1
  141. package/dist/tui/index.js +11 -11
  142. package/dist/types/index.js +1 -1
  143. package/dist/types/src/context-usage.d.ts +142 -0
  144. package/dist/types/src/context-usage.d.ts.map +1 -0
  145. package/dist/types/src/events.d.ts +45 -1
  146. package/dist/types/src/events.d.ts.map +1 -1
  147. package/dist/types/src/index.d.ts +3 -2
  148. package/dist/types/src/index.d.ts.map +1 -1
  149. package/dist/types/src/protocol.d.ts +24 -4
  150. package/dist/types/src/protocol.d.ts.map +1 -1
  151. package/dist/types/src/version.d.ts +13 -1
  152. package/dist/types/src/version.d.ts.map +1 -1
  153. package/dist/workspace-plugin/adapters/mcp.js +2 -2
  154. package/dist/workspace-plugin/index.js +1 -1
  155. package/package.json +3 -3
  156. package/dist/chunk-7WVPAQPE.js.map +0 -1
  157. package/dist/chunk-QQ3G5N7X.js.map +0 -1
  158. package/dist/chunk-RGB45PIL.js.map +0 -1
  159. package/dist/chunk-W2SDSDR7.js.map +0 -1
@@ -1,29 +1,29 @@
1
- import { WorkspacePlugin } from './chunk-66MJRB6K.js';
2
- import { buildWorkspaceToolDefs } from './chunk-PQE2MYB6.js';
1
+ import { WorkspacePlugin } from './chunk-OPSKLUB4.js';
2
+ import { buildWorkspaceToolDefs } from './chunk-5FMWNSAQ.js';
3
3
  import { findAiAssetsRoot } from './chunk-7IH3RKKK.js';
4
4
  import { WebSocketServerTransport } from './chunk-73ZXUUL6.js';
5
5
  import { assembleSystemPrompt, buildCapabilitiesPromptSection } from './chunk-W3UDISS2.js';
6
6
  import { prepareNativePolicy, codexInstanceEnvironment, parseCodexCredential, parseCodexRefreshInput, parseCodexRefreshResult } from './chunk-PE3A6FFW.js';
7
- import { resolveFlowPath } from './chunk-J3K5O6XA.js';
7
+ import { resolveFlowPath } from './chunk-EJU2TOGT.js';
8
8
  import { findAiAssetsRoot as findAiAssetsRoot$1, deployCatalogEntry, undeployCatalogEntry } from './chunk-Q6NDQ6BH.js';
9
- import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, buildSdkConnectorTools, buildLazySdkFlowTools, describeFlowOperations, buildConnectorToolDefs, buildFlowToolDefs, driveOrchestratorTurn, SessionNodeExecutor, SessionSubpromptRunner, ClassifierSubpromptRunner, SessionInlineSubFlowRunner, buildSdkFlowTools } from './chunk-66WUZ3XL.js';
9
+ import { registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, buildSdkConnectorTools, buildLazySdkFlowTools, describeFlowOperations, buildConnectorToolDefs, buildFlowToolDefs, driveOrchestratorTurn, SessionNodeExecutor, SessionSubpromptRunner, ClassifierSubpromptRunner, SessionInlineSubFlowRunner, buildSdkFlowTools } from './chunk-ZDSZGV5F.js';
10
10
  import { loadYamlConnectorDeclarations, withMaterializedConnectorDeclarations, SecretProviderChain, ConnectorStartupError, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, isKnownSecretRef, deriveSingleMaterializedConnectorDeclaration } from './chunk-MC2MF4U5.js';
11
- import { EventNormalizer } from './chunk-EEODEEKX.js';
11
+ import { EventNormalizer } from './chunk-XBMCUMZT.js';
12
12
  import { probeResumeTranscript, transcriptStoreForRuntime } from './chunk-6S5KL76M.js';
13
13
  import { CodexNativeStateUnavailable } from './chunk-LOO5CB5M.js';
14
- import { dispatchCapability } from './chunk-TOXPRXAK.js';
14
+ import { dispatchCapability } from './chunk-RLACUE4X.js';
15
15
  import { classifyClaudeSdkError } from './chunk-BGY4KTU6.js';
16
16
  import { agentExecRequested } from './chunk-YROR332M.js';
17
- import { createDriver, catalogLayer, providerCredentialEnvName, toMergedRegistry, registryCredentialEnv, AI_PROVIDER_PRESETS } from './chunk-RGB45PIL.js';
17
+ import { createDriver, catalogLayer, providerCredentialEnvName, toMergedRegistry, registryCredentialEnv, AI_PROVIDER_PRESETS } from './chunk-RTD5KAM4.js';
18
18
  import { loadFlow } from './chunk-KTCMBEEB.js';
19
19
  import { parseFlowDefinition } from './chunk-ALLCAFHQ.js';
20
20
  import { renderStimulusPrompt } from './chunk-RQLL7L72.js';
21
- import { withActivityLabelJsonSchema, TOOL_ACTIVITY_PROMPT_SECTION, SESSION_ROOT_CONNECTOR_ID, PROTOCOL_VERSION } from './chunk-QQ3G5N7X.js';
21
+ import { withActivityLabelJsonSchema, TOOL_ACTIVITY_PROMPT_SECTION, SESSION_ROOT_CONNECTOR_ID, PROTOCOL_VERSION } from './chunk-S5A5MVJN.js';
22
22
  import { resolveSettings, loadProviderRegistry } from './chunk-UWU572Q6.js';
23
23
  import { resolveRuntimeAssets } from './chunk-5RHPNNWP.js';
24
24
  import { resolveDriverPaths } from './chunk-K5GBV4SA.js';
25
25
  import { resolveSkWorkspaceConfig, resolveAgentDir, loadMcpServerDeclarations, COMPACTION_DEFAULTS, resolveCompactionThresholdPercent, validateAssetRecipeAttr, deriveSingleMaterializedMcpDeclaration, stageMaterializedSkills, readSkillAllowList, isStagedSkillMarkerFor, unstageSkill } from './chunk-DF7C3KZK.js';
26
- import { withFsDeadline, FsDeadlineError, fsDeadlineMs, tryWithFsDeadline } from './chunk-2FBPAR2V.js';
26
+ import { withFsDeadline, FsDeadlineError, fsDeadlineMs, parseFrontmatter, tryWithFsDeadline } from './chunk-2FBPAR2V.js';
27
27
  import { parseAssetRef } from './chunk-GEEW6SY2.js';
28
28
  import { resolveLogStoreConfig, createLogStoreFromConfig, OnLogBridgeSink, WsLogSink, resolveLogsRetention, enforceLogsRetention } from './chunk-JMKB7IB4.js';
29
29
  import { registryEntries, resolveEntryBaseUrl, parseModelRef, isEntryEnabled, parseCredentialRef } from './chunk-GZZPKAV5.js';
@@ -3816,12 +3816,19 @@ async function handleMountResourceRequest(command, manager, emit) {
3816
3816
  }
3817
3817
  const padding = nulTailPaddingLength(bytes);
3818
3818
  const body = bytes.subarray(0, bytes.length - padding);
3819
+ const wantsBytes = options?.encoding === "binary";
3819
3820
  if (padding > 0 && body.length === 0 || isBinaryBuffer(body)) {
3820
3821
  data = {
3821
3822
  data: bytes.toString("base64"),
3822
3823
  contentType,
3823
3824
  encoding: "binary"
3824
3825
  };
3826
+ } else if (wantsBytes) {
3827
+ data = {
3828
+ data: body.toString("base64"),
3829
+ contentType,
3830
+ encoding: "binary"
3831
+ };
3825
3832
  } else {
3826
3833
  data = {
3827
3834
  data: body.toString("utf-8"),
@@ -5040,6 +5047,12 @@ function resolveContextWindow(driverWindow, model) {
5040
5047
  }
5041
5048
  return driverWindow || DEFAULT_CONTEXT_WINDOW;
5042
5049
  }
5050
+ function reportedContextWindow(driverWindow, model) {
5051
+ if (model && ONE_MILLION_ALIAS_PATTERN.test(model)) {
5052
+ return Math.max(driverWindow ?? 0, ONE_MILLION_CONTEXT_WINDOW);
5053
+ }
5054
+ return driverWindow && driverWindow > 0 ? driverWindow : null;
5055
+ }
5043
5056
  function detectRateLimitInSummary(text2) {
5044
5057
  if (text2.length > RATE_LIMIT_TEXT_MAX_CHARS) return false;
5045
5058
  return RATE_LIMIT_TEXT_PATTERNS.some((p) => p.test(text2));
@@ -5090,6 +5103,20 @@ var CompactionOrchestrator = class {
5090
5103
  contextFill(usage) {
5091
5104
  return this.driver.getContextTokens?.() ?? contextTokens(usage);
5092
5105
  }
5106
+ /**
5107
+ * The context fill, in tokens, at which auto-compaction triggers — the same
5108
+ * window and tier {@link shouldCompact} uses. `null` when compaction is off.
5109
+ */
5110
+ compactAtTokens() {
5111
+ if (!this.config.enabled) return null;
5112
+ const contextWindow = resolveContextWindow(
5113
+ this.driver.getContextWindow(),
5114
+ this.driver.getModel() ?? null
5115
+ );
5116
+ return Math.round(
5117
+ contextWindow * resolveCompactionThresholdPercent(contextWindow, this.config) / 100
5118
+ );
5119
+ }
5093
5120
  trackMessage(seq) {
5094
5121
  this.currentSeq = seq;
5095
5122
  this.messagesSinceCompaction++;
@@ -5777,6 +5804,517 @@ function readCurrentClaudeAccessToken(home) {
5777
5804
  return typeof raw === "string" && raw.length > 0 ? raw : null;
5778
5805
  }
5779
5806
 
5807
+ // runner/src/context-usage/estimator.ts
5808
+ var CHARS_PER_TEXT_TOKEN = 4;
5809
+ var CHARS_PER_JSON_TOKEN = 2;
5810
+ var defaultTokenEstimator = {
5811
+ text(value) {
5812
+ return value.length === 0 ? 0 : Math.ceil(value.length / CHARS_PER_TEXT_TOKEN);
5813
+ },
5814
+ json(value) {
5815
+ if (value === void 0) return 0;
5816
+ let serialized;
5817
+ try {
5818
+ serialized = typeof value === "string" ? value : JSON.stringify(value) ?? "";
5819
+ } catch {
5820
+ return 0;
5821
+ }
5822
+ return serialized.length === 0 ? 0 : Math.ceil(serialized.length / CHARS_PER_JSON_TOKEN);
5823
+ }
5824
+ };
5825
+
5826
+ // runner/src/context-usage/compose.ts
5827
+ var SKAILE_LABELS = /* @__PURE__ */ new Set([
5828
+ "context",
5829
+ "environment",
5830
+ "resources",
5831
+ "mcp-guidance",
5832
+ "tool-activity",
5833
+ "home"
5834
+ ]);
5835
+ var BUCKET_ORDER = [
5836
+ "provider-system",
5837
+ "skaile-system",
5838
+ "agent-prompt",
5839
+ "memory",
5840
+ "skills",
5841
+ "mcp-tools",
5842
+ "builtin-tools",
5843
+ "subagents",
5844
+ "content",
5845
+ "free",
5846
+ "compaction-buffer"
5847
+ ];
5848
+ var MEASURED_DRIFT_TOLERANCE = 0.02;
5849
+ function composeContextUsageSnapshot(input) {
5850
+ const estimator = input.estimator ?? defaultTokenEstimator;
5851
+ const report = input.report;
5852
+ const fresh = report !== null && input.reportFresh;
5853
+ const driverFidelity = report?.breakdownFidelity ?? "measured";
5854
+ const buckets = /* @__PURE__ */ new Map();
5855
+ const sectionItems = input.systemPromptSections.map((s) => ({
5856
+ label: s.label,
5857
+ item: {
5858
+ name: s.label,
5859
+ tokens: estimator.text(s.value),
5860
+ ...s.source ? { source: s.source } : {}
5861
+ }
5862
+ }));
5863
+ const appended = report?.appendedSystemPromptTokens;
5864
+ if (appended !== void 0) {
5865
+ const shares = apportion(
5866
+ sectionItems.map((s) => s.item.tokens),
5867
+ appended
5868
+ );
5869
+ sectionItems.forEach((s, i) => {
5870
+ s.item.tokens = shares[i] ?? 0;
5871
+ });
5872
+ }
5873
+ const skaileItems = sectionItems.filter((s) => SKAILE_LABELS.has(s.label)).map((s) => s.item);
5874
+ const agentItems = sectionItems.filter((s) => !SKAILE_LABELS.has(s.label)).map((s) => s.item);
5875
+ buckets.set("skaile-system", itemBucket("skaile-system", skaileItems, "estimated"));
5876
+ buckets.set("agent-prompt", itemBucket("agent-prompt", agentItems, "estimated"));
5877
+ const runnerSectionTokens = sumTokens(skaileItems) + sumTokens(agentItems);
5878
+ let providerPending = false;
5879
+ if (report?.systemPromptTokens !== void 0) {
5880
+ const isolated = appended !== void 0;
5881
+ buckets.set("provider-system", {
5882
+ id: "provider-system",
5883
+ tokens: Math.max(0, report.systemPromptTokens - (isolated ? appended : runnerSectionTokens)),
5884
+ fidelity: driverFidelity === "estimated" ? "estimated" : isolated ? "measured" : "derived",
5885
+ ...report.systemPromptSections?.length ? { items: report.systemPromptSections } : {}
5886
+ });
5887
+ } else {
5888
+ providerPending = true;
5889
+ }
5890
+ setStatic(buckets, "memory", report?.memory, null, driverFidelity);
5891
+ setStatic(buckets, "skills", report?.skills, input.skills, driverFidelity);
5892
+ setStatic(buckets, "mcp-tools", report?.mcpTools, input.mcpTools, driverFidelity);
5893
+ setStatic(buckets, "builtin-tools", report?.builtinTools, null, driverFidelity);
5894
+ setStatic(buckets, "subagents", report?.subagents, null, driverFidelity);
5895
+ let contentPending = false;
5896
+ if (fresh && report.content) {
5897
+ buckets.set("content", reportBucket("content", report.content, driverFidelity));
5898
+ } else if (input.content?.complete) {
5899
+ buckets.set("content", itemBucket("content", input.content.items, "estimated"));
5900
+ } else {
5901
+ contentPending = true;
5902
+ }
5903
+ let used = null;
5904
+ let totalFidelity = "estimated";
5905
+ if (fresh && typeof report.usedTokens === "number") {
5906
+ used = report.usedTokens;
5907
+ totalFidelity = "measured";
5908
+ } else if (input.contextTokens !== null && input.contextTokens > 0) {
5909
+ used = input.contextTokens;
5910
+ totalFidelity = "measured";
5911
+ }
5912
+ if (used !== null) {
5913
+ const pinned = new Set(
5914
+ appended !== void 0 ? ["skaile-system", "agent-prompt"] : []
5915
+ );
5916
+ fitEstimatesWithin(buckets, used, pinned);
5917
+ const remaining = used - sumBuckets(buckets);
5918
+ if (contentPending) {
5919
+ buckets.set("content", {
5920
+ id: "content",
5921
+ tokens: Math.max(0, remaining),
5922
+ fidelity: "derived"
5923
+ });
5924
+ if (providerPending) buckets.set("provider-system", unknownBucket("provider-system"));
5925
+ } else if (providerPending) {
5926
+ buckets.set("provider-system", {
5927
+ id: "provider-system",
5928
+ tokens: Math.max(0, remaining),
5929
+ fidelity: "derived"
5930
+ });
5931
+ } else if (remaining !== 0) {
5932
+ absorbDrift(buckets, remaining, used);
5933
+ }
5934
+ } else {
5935
+ if (contentPending) buckets.set("content", unknownBucket("content"));
5936
+ if (providerPending) buckets.set("provider-system", unknownBucket("provider-system"));
5937
+ used = sumBuckets(buckets);
5938
+ totalFidelity = used > 0 ? "estimated" : "unknown";
5939
+ }
5940
+ const window = input.contextWindow ?? (fresh ? report.contextWindow ?? null : null);
5941
+ if (window !== null && window > 0) {
5942
+ const threshold = input.autoCompactAt !== null ? Math.min(input.autoCompactAt, window) : window;
5943
+ buckets.set("free", {
5944
+ id: "free",
5945
+ tokens: Math.max(0, threshold - used),
5946
+ fidelity: totalFidelity
5947
+ });
5948
+ if (input.autoCompactAt !== null) {
5949
+ buckets.set("compaction-buffer", {
5950
+ id: "compaction-buffer",
5951
+ tokens: Math.max(0, window - Math.max(used, threshold)),
5952
+ fidelity: totalFidelity
5953
+ });
5954
+ }
5955
+ }
5956
+ return {
5957
+ provider: input.provider,
5958
+ model: input.model,
5959
+ contextWindow: window !== null && window > 0 ? window : null,
5960
+ usedTokens: used,
5961
+ totalFidelity,
5962
+ autoCompactAt: input.autoCompactAt,
5963
+ buckets: BUCKET_ORDER.flatMap((id) => {
5964
+ const bucket = buckets.get(id);
5965
+ return bucket ? [bucket] : [];
5966
+ }),
5967
+ capturedAt: input.capturedAt,
5968
+ trigger: input.trigger
5969
+ };
5970
+ }
5971
+ function setStatic(buckets, id, reported, estimatedItems, reportedFidelity) {
5972
+ if (reported) buckets.set(id, reportBucket(id, reported, reportedFidelity));
5973
+ else if (estimatedItems) buckets.set(id, itemBucket(id, estimatedItems, "estimated"));
5974
+ else buckets.set(id, unknownBucket(id));
5975
+ }
5976
+ function reportBucket(id, reported, fidelity) {
5977
+ return {
5978
+ id,
5979
+ tokens: reported.tokens,
5980
+ fidelity,
5981
+ ...reported.items ? { items: reported.items } : {},
5982
+ ...reported.deferredTokens ? { deferredTokens: reported.deferredTokens } : {}
5983
+ };
5984
+ }
5985
+ function itemBucket(id, items, fidelity) {
5986
+ const deferred = sumTokens(items.filter((i) => i.deferred));
5987
+ return {
5988
+ id,
5989
+ tokens: sumTokens(items.filter((i) => !i.deferred)),
5990
+ fidelity,
5991
+ items,
5992
+ ...deferred > 0 ? { deferredTokens: deferred } : {}
5993
+ };
5994
+ }
5995
+ function unknownBucket(id) {
5996
+ return { id, tokens: 0, fidelity: "unknown" };
5997
+ }
5998
+ function fitEstimatesWithin(buckets, used, pinned) {
5999
+ const estimated = [...buckets.values()].filter(
6000
+ (b) => b.fidelity === "estimated" && !pinned.has(b.id)
6001
+ );
6002
+ const estimatedTotal = sumTokens(estimated);
6003
+ const fixedTotal = sumBuckets(buckets) - estimatedTotal;
6004
+ if (estimatedTotal === 0 || fixedTotal + estimatedTotal <= used) return;
6005
+ const budget = Math.max(0, used - fixedTotal);
6006
+ const shares = apportion(
6007
+ estimated.map((b) => b.tokens),
6008
+ budget
6009
+ );
6010
+ estimated.forEach((bucket, i) => {
6011
+ const target = shares[i] ?? 0;
6012
+ if (bucket.items) {
6013
+ const inWindow = bucket.items.filter((it) => !it.deferred);
6014
+ const itemShares = apportion(
6015
+ inWindow.map((it) => it.tokens),
6016
+ target
6017
+ );
6018
+ const scaled = new Map(inWindow.map((it, j) => [it, itemShares[j] ?? 0]));
6019
+ bucket.items = bucket.items.map(
6020
+ (it) => scaled.has(it) ? { ...it, tokens: scaled.get(it) ?? 0 } : it
6021
+ );
6022
+ }
6023
+ bucket.tokens = target;
6024
+ });
6025
+ }
6026
+ function absorbDrift(buckets, remaining, used) {
6027
+ const content = buckets.get("content");
6028
+ if (!content) return;
6029
+ content.tokens = Math.max(0, content.tokens + remaining);
6030
+ if (content.fidelity === "measured" && Math.abs(remaining) > used * MEASURED_DRIFT_TOLERANCE) {
6031
+ content.fidelity = "derived";
6032
+ delete content.items;
6033
+ }
6034
+ }
6035
+ function sumBuckets(buckets) {
6036
+ let total = 0;
6037
+ for (const b of buckets.values()) {
6038
+ if (b.id !== "free" && b.id !== "compaction-buffer") total += b.tokens;
6039
+ }
6040
+ return total;
6041
+ }
6042
+ function sumTokens(items) {
6043
+ return items.reduce((sum, i) => sum + i.tokens, 0);
6044
+ }
6045
+ function apportion(weights, total) {
6046
+ if (weights.length === 0) return [];
6047
+ const target = Math.max(0, Math.round(total));
6048
+ const weightSum = weights.reduce((sum, w) => sum + Math.max(0, w), 0);
6049
+ const raw = weights.map(
6050
+ (w) => weightSum > 0 ? Math.max(0, w) / weightSum * target : target / weights.length
6051
+ );
6052
+ const parts = raw.map(Math.floor);
6053
+ let leftover = target - parts.reduce((sum, p) => sum + p, 0);
6054
+ const byRemainder = raw.map((r, i) => ({ i, rem: r - Math.floor(r) })).sort((a, b) => b.rem - a.rem);
6055
+ for (const { i } of byRemainder) {
6056
+ if (leftover <= 0) break;
6057
+ parts[i] = (parts[i] ?? 0) + 1;
6058
+ leftover--;
6059
+ }
6060
+ return parts;
6061
+ }
6062
+
6063
+ // runner/src/context-usage/transcript-tracker.ts
6064
+ var USER = "User messages";
6065
+ var ASSISTANT = "Assistant messages";
6066
+ var SUMMARY = "Compaction summary";
6067
+ var TranscriptTokenTracker = class {
6068
+ constructor(estimator = defaultTokenEstimator) {
6069
+ this.estimator = estimator;
6070
+ }
6071
+ estimator;
6072
+ // Keyed by group and name, so a tool called "User messages" cannot merge into the user line.
6073
+ totals = /* @__PURE__ */ new Map();
6074
+ complete = false;
6075
+ /** Start over for a freshly built driver; `resuming` marks history we never saw. */
6076
+ reset(opts) {
6077
+ this.totals.clear();
6078
+ this.complete = !opts.resuming;
6079
+ }
6080
+ /** A compaction replaced the conversation with its summary. */
6081
+ resetToSummary(summary) {
6082
+ this.totals.clear();
6083
+ this.add(SUMMARY, "messages", this.estimator.text(summary));
6084
+ this.complete = true;
6085
+ }
6086
+ observeUserPrompt(text2) {
6087
+ this.add(USER, "messages", this.estimator.text(text2));
6088
+ }
6089
+ observe(event) {
6090
+ switch (event.type) {
6091
+ case "text":
6092
+ this.add(ASSISTANT, "messages", this.estimator.text(event.content));
6093
+ break;
6094
+ case "text_retract":
6095
+ this.add(ASSISTANT, "messages", -this.estimator.text(event.content));
6096
+ break;
6097
+ case "tool_call":
6098
+ if (event.parentToolUseId) return;
6099
+ this.add(event.tool, "tools", this.estimator.json(event.input));
6100
+ break;
6101
+ case "tool_result":
6102
+ if (event.parentToolUseId) return;
6103
+ this.add(
6104
+ event.tool,
6105
+ "tools",
6106
+ typeof event.output === "string" ? this.estimator.text(event.output) : this.estimator.json(event.output)
6107
+ );
6108
+ break;
6109
+ }
6110
+ }
6111
+ estimate() {
6112
+ const items = [...this.totals.values()].filter((v) => v.tokens > 0).map((v) => ({ name: v.name, tokens: v.tokens, group: v.group })).sort((a, b) => b.tokens - a.tokens);
6113
+ return {
6114
+ tokens: items.reduce((sum, i) => sum + i.tokens, 0),
6115
+ items,
6116
+ complete: this.complete
6117
+ };
6118
+ }
6119
+ add(name, group, tokens) {
6120
+ if (tokens === 0) return;
6121
+ const key = `${group}\0${name}`;
6122
+ const current = this.totals.get(key);
6123
+ this.totals.set(key, { name, group, tokens: Math.max(0, (current?.tokens ?? 0) + tokens) });
6124
+ }
6125
+ };
6126
+
6127
+ // runner/src/context-usage/collector.ts
6128
+ var DEFAULT_MEASURE_TIMEOUT_MS = 3e4;
6129
+ var SKILL_READ_TIMEOUT_MS = 5e3;
6130
+ var ContextUsageCollector = class {
6131
+ constructor(deps) {
6132
+ this.deps = deps;
6133
+ this.estimator = deps.estimator ?? defaultTokenEstimator;
6134
+ this.tracker = new TranscriptTokenTracker(this.estimator);
6135
+ }
6136
+ deps;
6137
+ tracker;
6138
+ estimator;
6139
+ lastReport = null;
6140
+ inflight = /* @__PURE__ */ new Map();
6141
+ skills = null;
6142
+ capabilityMemo = null;
6143
+ /** A driver was (re)built; everything measured or cached about the old one is void. */
6144
+ onDriverBuilt(opts) {
6145
+ this.tracker.reset(opts);
6146
+ this.lastReport = null;
6147
+ this.skills = null;
6148
+ this.inflight.clear();
6149
+ }
6150
+ onCompaction(summary) {
6151
+ this.tracker.resetToSummary(summary);
6152
+ }
6153
+ observeUserPrompt(text2) {
6154
+ this.tracker.observeUserPrompt(text2);
6155
+ }
6156
+ observeEvent(event) {
6157
+ this.tracker.observe(event);
6158
+ }
6159
+ async collect(opts) {
6160
+ try {
6161
+ return await this.collectUnsafe(opts);
6162
+ } catch (err) {
6163
+ return {
6164
+ snapshot: {
6165
+ provider: safeCall(() => this.deps.provider(), "unknown"),
6166
+ model: safeCall(() => this.deps.driver()?.getModel?.() ?? "", ""),
6167
+ contextWindow: null,
6168
+ usedTokens: 0,
6169
+ totalFidelity: "unknown",
6170
+ autoCompactAt: null,
6171
+ buckets: [],
6172
+ capturedAt: (this.deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
6173
+ trigger: opts.trigger
6174
+ },
6175
+ error: `context usage unavailable: ${err instanceof Error ? err.message : String(err)}`
6176
+ };
6177
+ }
6178
+ }
6179
+ async collectUnsafe(opts) {
6180
+ const driver = this.deps.driver();
6181
+ let error;
6182
+ let report = null;
6183
+ let reportFresh = false;
6184
+ if (opts.measure && driver?.getContextUsageReport) {
6185
+ try {
6186
+ const detail = opts.measure;
6187
+ const measure = driver.getContextUsageReport.bind(driver);
6188
+ report = await this.sharedMeasurement(detail, () => measure({ detail }));
6189
+ if (report) {
6190
+ this.lastReport = report;
6191
+ reportFresh = true;
6192
+ }
6193
+ } catch (err) {
6194
+ error = `measurement failed: ${err instanceof Error ? err.message : String(err)}`;
6195
+ }
6196
+ }
6197
+ report ??= this.lastReport;
6198
+ const model = driver?.getModel?.() ?? "";
6199
+ const usage = driver?.getTokenUsage() ?? null;
6200
+ const perCall = driver?.getContextTokens?.() ?? null;
6201
+ const fill = opts.trigger === "compaction" ? null : perCall ?? (usage ? contextTokens(usage) : null);
6202
+ const snapshot = composeContextUsageSnapshot({
6203
+ provider: this.deps.provider(),
6204
+ model,
6205
+ trigger: opts.trigger,
6206
+ capturedAt: (this.deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
6207
+ contextTokens: fill,
6208
+ contextWindow: driver ? reportedContextWindow(driver.getContextWindow(), model || null) : null,
6209
+ autoCompactAt: this.deps.autoCompactAt(),
6210
+ systemPromptSections: this.deps.systemPromptSections(),
6211
+ report,
6212
+ reportFresh,
6213
+ skills: report?.skills ? null : await this.skillItems(),
6214
+ mcpTools: report?.mcpTools ? null : this.capabilityItems(),
6215
+ content: this.tracker.estimate(),
6216
+ estimator: this.estimator
6217
+ });
6218
+ return error ? { snapshot, error } : { snapshot };
6219
+ }
6220
+ /**
6221
+ * One driver measurement per detail level at a time: a second request that
6222
+ * lands while a `full` count is running (two panels, a double click) shares
6223
+ * it instead of paying for another round of `count_tokens` calls.
6224
+ */
6225
+ sharedMeasurement(detail, measure) {
6226
+ const running = this.inflight.get(detail);
6227
+ if (running) return running;
6228
+ const measurement = withTimeout(
6229
+ measure(),
6230
+ this.deps.measureTimeoutMs ?? DEFAULT_MEASURE_TIMEOUT_MS
6231
+ ).finally(() => {
6232
+ if (this.inflight.get(detail) === measurement) this.inflight.delete(detail);
6233
+ });
6234
+ this.inflight.set(detail, measurement);
6235
+ return measurement;
6236
+ }
6237
+ skillItems() {
6238
+ this.skills ??= withTimeout(this.deps.readSkills(), SKILL_READ_TIMEOUT_MS).then(
6239
+ (skills) => skills.map((s) => ({
6240
+ name: s.name,
6241
+ tokens: this.estimator.text(s.frontmatter),
6242
+ ...s.source ? { source: s.source } : {}
6243
+ })),
6244
+ () => null
6245
+ );
6246
+ return this.skills;
6247
+ }
6248
+ capabilityItems() {
6249
+ const caps = this.deps.modelCapabilities();
6250
+ const key = caps.map((c) => c.name).join("\n");
6251
+ if (this.capabilityMemo?.key === key) return this.capabilityMemo.items;
6252
+ const items = caps.map((c) => ({
6253
+ name: c.name,
6254
+ tokens: this.estimator.text(c.name) + this.estimator.text(c.description) + this.estimator.json(c.inputSchema),
6255
+ group: capabilityGroup(c.origin)
6256
+ }));
6257
+ this.capabilityMemo = { key, items };
6258
+ return items;
6259
+ }
6260
+ };
6261
+ function capabilityGroup(origin) {
6262
+ switch (origin.kind) {
6263
+ case "mcp":
6264
+ return origin.serverId;
6265
+ case "connector":
6266
+ return origin.connectorId;
6267
+ case "mount":
6268
+ return origin.mountId;
6269
+ case "skill":
6270
+ return origin.skillId;
6271
+ case "flow":
6272
+ return origin.flowId;
6273
+ case "app":
6274
+ return origin.appId;
6275
+ default:
6276
+ return origin.kind;
6277
+ }
6278
+ }
6279
+ function safeCall(fn, fallback) {
6280
+ try {
6281
+ return fn();
6282
+ } catch {
6283
+ return fallback;
6284
+ }
6285
+ }
6286
+ function withTimeout(promise, ms) {
6287
+ let timer;
6288
+ const timeout2 = new Promise((_, reject) => {
6289
+ timer = setTimeout(() => reject(new Error(`timed out after ${ms} ms`)), ms);
6290
+ timer.unref?.();
6291
+ });
6292
+ return Promise.race([promise, timeout2]).finally(() => clearTimeout(timer));
6293
+ }
6294
+ var MAX_SKILLS = 500;
6295
+ async function readSkillListings(skillsDir) {
6296
+ let entries;
6297
+ try {
6298
+ entries = (await readdir(skillsDir, { withFileTypes: true })).filter((e) => e.isDirectory() || e.isSymbolicLink()).map((e) => e.name).slice(0, MAX_SKILLS);
6299
+ } catch {
6300
+ return [];
6301
+ }
6302
+ const listings = await Promise.all(
6303
+ entries.map(async (dir) => {
6304
+ const path6 = join(skillsDir, dir, "SKILL.md");
6305
+ try {
6306
+ const { data } = parseFrontmatter(await readFile(path6, "utf8"));
6307
+ const name = typeof data.name === "string" ? data.name : dir;
6308
+ const description = typeof data.description === "string" ? data.description : "";
6309
+ return { name, frontmatter: `${name}: ${description}`, source: path6 };
6310
+ } catch {
6311
+ return null;
6312
+ }
6313
+ })
6314
+ );
6315
+ return listings.filter((l) => l !== null);
6316
+ }
6317
+
5780
6318
  // runner/src/lifecycle-handler.ts
5781
6319
  function raiseHookFailures(phase, results, log) {
5782
6320
  const failed = results.filter((r) => !r.ok);
@@ -7643,6 +8181,19 @@ async function startAgentServer(opts) {
7643
8181
  });
7644
8182
  let sessionConfig;
7645
8183
  let agentSession;
8184
+ const contextUsage = new ContextUsageCollector({
8185
+ driver: () => driver,
8186
+ provider: () => agentSession?.driverType ?? "unknown",
8187
+ systemPromptSections: () => agentSession?.systemPromptSections ?? [],
8188
+ modelCapabilities: () => capabilityRegistry.list().filter(
8189
+ (cap) => (cap.audience ?? ["llm", "user"]).includes("llm") && !cap.name.startsWith("host.") && !cap.name.startsWith("runner.")
8190
+ ),
8191
+ readSkills: () => readSkillListings(join(opts.projectDir, activeSkillsDir())),
8192
+ autoCompactAt: () => compactionOrchestrator?.compactAtTokens() ?? null
8193
+ });
8194
+ function noteAgentSessionBuilt(resumeSessionId2) {
8195
+ contextUsage.onDriverBuilt({ resuming: !!resumeSessionId2 || !!managedCodex });
8196
+ }
7646
8197
  let flowToolsBaked = false;
7647
8198
  let secretProvider;
7648
8199
  let runtimeIdentity;
@@ -7722,6 +8273,7 @@ async function startAgentServer(opts) {
7722
8273
  sessionConfig = buildSessionConfig();
7723
8274
  agentSession = await createAgentSession(sessionConfig);
7724
8275
  emitSystemPromptComposed(agentSession, sendEvent);
8276
+ noteAgentSessionBuilt(sessionConfig.resumeSessionId);
7725
8277
  registerSessionComposition(agentSession);
7726
8278
  resolveSessionReady();
7727
8279
  captureBakedMcpServers();
@@ -7811,12 +8363,14 @@ async function startAgentServer(opts) {
7811
8363
  const normalizer = new EventNormalizer();
7812
8364
  function forwardNormalizedEvent(event) {
7813
8365
  if (compacting) return;
8366
+ contextUsage.observeEvent(event);
7814
8367
  const isTransient = event.type === "status" || event.type === "sync_status" || event.type === "resources_available" || event.type === "resource_response" || event.type === "commands_available";
7815
8368
  if (!isTransient) {
7816
8369
  eventSeq++;
7817
8370
  compactionOrchestrator?.trackMessage(eventSeq);
7818
8371
  }
7819
8372
  if (event.type === "finished") {
8373
+ scheduleContextUsageEmit("turn-end");
7820
8374
  if (!compacting && compactionOrchestrator?.shouldCompact()) {
7821
8375
  const compactionTimer = setTimeout(() => {
7822
8376
  if (compacting || !compactionOrchestrator?.shouldCompact()) return;
@@ -7887,6 +8441,16 @@ async function startAgentServer(opts) {
7887
8441
  let suppressedBy = null;
7888
8442
  let compactionOrchestrator = null;
7889
8443
  const compactionConfig = wsConfig.compaction;
8444
+ function scheduleContextUsageEmit(trigger) {
8445
+ const timer = setTimeout(() => {
8446
+ void contextUsage.collect({ trigger, measure: trigger === "turn-end" ? "summary" : false }).then(({ snapshot, error }) => {
8447
+ sendEvent({ type: "context_usage", snapshot, ...error ? { error } : {} });
8448
+ }).catch((err) => {
8449
+ serverLog.debug(`[serve] context_usage emit failed: ${String(err)}`);
8450
+ });
8451
+ }, 0);
8452
+ timer.unref?.();
8453
+ }
7890
8454
  function rebuildCompactionOrchestrator() {
7891
8455
  if (!driver) return;
7892
8456
  let gateHold = null;
@@ -7902,6 +8466,8 @@ async function startAgentServer(opts) {
7902
8466
  },
7903
8467
  onSnapshot: (snapshot) => {
7904
8468
  sendEvent(snapshot);
8469
+ contextUsage.onCompaction(snapshot.summary);
8470
+ scheduleContextUsageEmit("compaction");
7905
8471
  },
7906
8472
  onCompactionAttempt: (event) => {
7907
8473
  sendEvent(event);
@@ -8390,6 +8956,7 @@ async function startAgentServer(opts) {
8390
8956
  throw new Error("CODEX_RUNTIME_UNSUPPORTED");
8391
8957
  }
8392
8958
  emitSystemPromptComposed(agentSession, sendEvent);
8959
+ noteAgentSessionBuilt(sessionConfig.resumeSessionId);
8393
8960
  resourceManager = agentSession.resourceManager;
8394
8961
  driver = agentSession.driver;
8395
8962
  rebuildCompactionOrchestrator();
@@ -8464,6 +9031,7 @@ async function startAgentServer(opts) {
8464
9031
  resuming: !!overrides.resumeSessionId
8465
9032
  });
8466
9033
  emitSystemPromptComposed(agentSession, sendEvent);
9034
+ noteAgentSessionBuilt({ ...sessionConfig, ...overrides }.resumeSessionId);
8467
9035
  swapDriver();
8468
9036
  rebuildCompactionOrchestrator();
8469
9037
  captureBakedMcpServers();
@@ -9002,6 +9570,7 @@ async function startAgentServer(opts) {
9002
9570
  return;
9003
9571
  }
9004
9572
  log(`[serve] prompt: ${cmd.prompt.slice(0, 80)}...`);
9573
+ contextUsage.observeUserPrompt(cmd.prompt);
9005
9574
  await driverSwapGate.awaitSwap();
9006
9575
  if (!await awaitCompactionIdle("prompt")) return;
9007
9576
  await restageMaterializedSkills(true);
@@ -9243,6 +9812,22 @@ async function startAgentServer(opts) {
9243
9812
  }
9244
9813
  sendEvent({ type: "debug_result", query: cmd.query, data: result });
9245
9814
  }
9815
+ async function handleGetContextUsage(cmd) {
9816
+ try {
9817
+ await sessionReady;
9818
+ } catch {
9819
+ }
9820
+ const { snapshot, error } = await contextUsage.collect({
9821
+ trigger: "request",
9822
+ measure: cmd.detail === "estimated" ? "summary" : "full"
9823
+ });
9824
+ sendEvent({
9825
+ type: "context_usage",
9826
+ requestId: cmd.requestId,
9827
+ snapshot,
9828
+ ...error ? { error } : {}
9829
+ });
9830
+ }
9246
9831
  async function handleShutdown() {
9247
9832
  log("[serve] shutdown requested");
9248
9833
  await cleanup();
@@ -9363,6 +9948,9 @@ async function startAgentServer(opts) {
9363
9948
  case "debug":
9364
9949
  await handleDebug(cmd);
9365
9950
  break;
9951
+ case "get_context_usage":
9952
+ await handleGetContextUsage(cmd);
9953
+ break;
9366
9954
  // -----------------------------------------------------------------------
9367
9955
  // -----------------------------------------------------------------------
9368
9956
  // v3: add_resource, remove_resource, remount_mount, set_log_level,
@@ -9624,5 +10212,5 @@ function touchSession(state) {
9624
10212
  }
9625
10213
 
9626
10214
  export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS, MOUNT_LIST_MAX_DEPTH, MOUNT_LIST_MAX_ENTRIES, MOUNT_READ_DEADLINE_FACTOR, MOUNT_STAT_BUDGET_MS, MOUNT_STAT_MAX_ENTRIES, MOUNT_TREE_OP_DEADLINE_FACTOR, MarkdownStreamer, PreInitRingSink, ResourceOperationError, SESSION_ROOT_WRITABLE_DIRS, SESSION_ROOT_WRITABLE_FILES, WS_AUTH_TOKEN_ENV, WS_AUTH_TOKEN_FILE_ENV, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, computeDirectoryTotals, connectorRefreshKind, createAgentSession, createFlowConnectorReadiness, createManagedCodexSubpromptDriver, createSessionStimulusBus, defineCapability, deleteSession, dispatchResourceRequest, dispatchRunnerCapabilityInvocation, emitSystemPromptComposed, ensureClaudeSettingsDisablesConnectors, ensureGitConfigInclude, executeConnectorMutate, extractClaudeAiOauthExpiresAt, flowStartNeedsDriverRestart, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, handleSessionRootResourceRequest, hasNonTerminalFlow, hostOpResumeStimulus, installPreInitRingSink, isSessionRootPathAllowed, isTerminalFlowStatus, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadManagedCodexHostConfig, loadSession, loadSessionById, mcpAuthSecretKey, newSession, nulTailPaddingLength, pickFlowToolTarget, pickRepointedManager, planFlowMutate, prepareCodexTools, reconcilePendingDecisions, registerActiveFlow, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveFlowMutateConnectorWaitMs, resolveMixin, runAgentChat, saveSession, setCurrentSession, setUpFlowConnector, startAgentServer, stimulusFromMetas, supportsLiveToolUpdates, takeRunnerWsAuthToken, touchSession, validateInputResponse, writeClaudeCodeCredentialsFile };
9627
- //# sourceMappingURL=chunk-W2SDSDR7.js.map
9628
- //# sourceMappingURL=chunk-W2SDSDR7.js.map
10215
+ //# sourceMappingURL=chunk-ZJEQFNKE.js.map
10216
+ //# sourceMappingURL=chunk-ZJEQFNKE.js.map