@oxygen-agent/cli 1.1003.12 → 1.1010.1

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 (102) hide show
  1. package/README.md +1 -1
  2. package/dist/column-decision-options.d.ts +20 -0
  3. package/dist/column-decision-options.js +54 -0
  4. package/dist/command-manifest.js +15 -2
  5. package/dist/functions-commands.js +11 -11
  6. package/dist/index.js +1222 -159
  7. package/dist/search-ai-filter-notice.d.ts +17 -0
  8. package/dist/search-ai-filter-notice.js +38 -0
  9. package/dist/skills.js +34 -10
  10. package/dist/util.d.ts +9 -0
  11. package/dist/util.js +14 -0
  12. package/node_modules/@oxygen/cli-ugc/dist/commands.js +296 -140
  13. package/node_modules/@oxygen/cli-ugc/dist/field-parser.d.ts +9 -0
  14. package/node_modules/@oxygen/cli-ugc/dist/field-parser.js +34 -0
  15. package/node_modules/@oxygen/recipe-sdk/dist/index.d.ts +13 -0
  16. package/node_modules/@oxygen/shared/dist/billing.d.ts +21 -0
  17. package/node_modules/@oxygen/shared/dist/billing.js +45 -0
  18. package/node_modules/@oxygen/shared/dist/byok-connect.js +5 -0
  19. package/node_modules/@oxygen/shared/dist/capability-discovery.d.ts +10 -0
  20. package/node_modules/@oxygen/shared/dist/capability-discovery.js +223 -13
  21. package/node_modules/@oxygen/shared/dist/cli-http-error.d.ts +8 -0
  22. package/node_modules/@oxygen/shared/dist/cli-http-error.js +8 -0
  23. package/node_modules/@oxygen/shared/dist/cli-result.js +1 -0
  24. package/node_modules/@oxygen/shared/dist/column-autofill.js +5 -23
  25. package/node_modules/@oxygen/shared/dist/column-decision.d.ts +50 -0
  26. package/node_modules/@oxygen/shared/dist/column-decision.js +228 -0
  27. package/node_modules/@oxygen/shared/dist/company-enrichment-fields.d.ts +9 -4
  28. package/node_modules/@oxygen/shared/dist/company-enrichment-fields.js +11 -8
  29. package/node_modules/@oxygen/shared/dist/copilot-skills.generated.d.ts +4 -4
  30. package/node_modules/@oxygen/shared/dist/copilot-skills.generated.js +4 -4
  31. package/node_modules/@oxygen/shared/dist/cutover-freeze.d.ts +26 -0
  32. package/node_modules/@oxygen/shared/dist/cutover-freeze.js +52 -0
  33. package/node_modules/@oxygen/shared/dist/data-suppliers.d.ts +57 -0
  34. package/node_modules/@oxygen/shared/dist/data-suppliers.js +59 -0
  35. package/node_modules/@oxygen/shared/dist/enrichment-intents.d.ts +6 -2
  36. package/node_modules/@oxygen/shared/dist/enrichment-intents.js +13 -23
  37. package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +60 -4
  38. package/node_modules/@oxygen/shared/dist/hosted-ai.js +125 -10
  39. package/node_modules/@oxygen/shared/dist/index.d.ts +2 -0
  40. package/node_modules/@oxygen/shared/dist/index.js +2 -0
  41. package/node_modules/@oxygen/shared/dist/langfuse.d.ts +44 -1
  42. package/node_modules/@oxygen/shared/dist/langfuse.js +407 -14
  43. package/node_modules/@oxygen/shared/dist/linkedin-countries.d.ts +1 -0
  44. package/node_modules/@oxygen/shared/dist/linkedin-countries.js +2 -0
  45. package/node_modules/@oxygen/shared/dist/linkedin-country-timezones.d.ts +24 -0
  46. package/node_modules/@oxygen/shared/dist/linkedin-country-timezones.js +276 -0
  47. package/node_modules/@oxygen/shared/dist/linkedin-message-deletion.d.ts +2 -0
  48. package/node_modules/@oxygen/shared/dist/linkedin-message-deletion.js +5 -0
  49. package/node_modules/@oxygen/shared/dist/linkedin-post-keywords.d.ts +44 -0
  50. package/node_modules/@oxygen/shared/dist/linkedin-post-keywords.js +116 -0
  51. package/node_modules/@oxygen/shared/dist/linkedin-sequences.d.ts +96 -0
  52. package/node_modules/@oxygen/shared/dist/linkedin-sequences.js +123 -0
  53. package/node_modules/@oxygen/shared/dist/llm-durable-capture.d.ts +24 -0
  54. package/node_modules/@oxygen/shared/dist/llm-durable-capture.js +89 -0
  55. package/node_modules/@oxygen/shared/dist/llm-prompts.d.ts +75 -0
  56. package/node_modules/@oxygen/shared/dist/llm-prompts.js +161 -0
  57. package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.d.ts +90 -0
  58. package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.js +130 -0
  59. package/node_modules/@oxygen/shared/dist/operational-telemetry.d.ts +24 -0
  60. package/node_modules/@oxygen/shared/dist/operational-telemetry.js +73 -0
  61. package/node_modules/@oxygen/shared/dist/otlp-log-sink.d.ts +29 -4
  62. package/node_modules/@oxygen/shared/dist/otlp-log-sink.js +189 -36
  63. package/node_modules/@oxygen/shared/dist/product-analytics-events.d.ts +21 -2
  64. package/node_modules/@oxygen/shared/dist/product-analytics-events.js +21 -1
  65. package/node_modules/@oxygen/shared/dist/redaction.js +4 -1
  66. package/node_modules/@oxygen/shared/dist/scraper-lane-credential.d.ts +18 -0
  67. package/node_modules/@oxygen/shared/dist/scraper-lane-credential.js +23 -0
  68. package/node_modules/@oxygen/shared/dist/sequences.js +5 -1
  69. package/node_modules/@oxygen/shared/dist/signup-lead-payload.d.ts +80 -0
  70. package/node_modules/@oxygen/shared/dist/signup-lead-payload.js +198 -0
  71. package/node_modules/@oxygen/shared/dist/social-capabilities.d.ts +6 -0
  72. package/node_modules/@oxygen/shared/dist/social-capabilities.js +25 -16
  73. package/node_modules/@oxygen/shared/dist/social-post-metrics-core.d.ts +32 -0
  74. package/node_modules/@oxygen/shared/dist/social-post-metrics-core.js +32 -0
  75. package/node_modules/@oxygen/shared/dist/social-post-metrics-linkedin.d.ts +31 -0
  76. package/node_modules/@oxygen/shared/dist/social-post-metrics-linkedin.js +103 -0
  77. package/node_modules/@oxygen/shared/dist/social-post-metrics-series.d.ts +96 -0
  78. package/node_modules/@oxygen/shared/dist/social-post-metrics-series.js +213 -0
  79. package/node_modules/@oxygen/shared/dist/social-post-metrics-x.d.ts +13 -0
  80. package/node_modules/@oxygen/shared/dist/social-post-metrics-x.js +78 -0
  81. package/node_modules/@oxygen/shared/dist/social-post-metrics.d.ts +36 -0
  82. package/node_modules/@oxygen/shared/dist/social-post-metrics.js +51 -0
  83. package/node_modules/@oxygen/shared/dist/stripe-price-catalog.d.ts +36 -0
  84. package/node_modules/@oxygen/shared/dist/stripe-price-catalog.js +184 -0
  85. package/node_modules/@oxygen/shared/dist/stripe-subscription-kind.d.ts +41 -0
  86. package/node_modules/@oxygen/shared/dist/stripe-subscription-kind.js +44 -0
  87. package/node_modules/@oxygen/shared/dist/table-limits.d.ts +3 -0
  88. package/node_modules/@oxygen/shared/dist/table-limits.js +3 -0
  89. package/node_modules/@oxygen/shared/dist/telemetry-export-observer.d.ts +94 -0
  90. package/node_modules/@oxygen/shared/dist/telemetry-export-observer.js +298 -0
  91. package/node_modules/@oxygen/shared/dist/telemetry.d.ts +11 -0
  92. package/node_modules/@oxygen/shared/dist/telemetry.js +19 -1
  93. package/node_modules/@oxygen/shared/dist/ugc.d.ts +22 -11
  94. package/node_modules/@oxygen/shared/dist/ugc.js +10 -0
  95. package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -0
  96. package/node_modules/@oxygen/shared/dist/version.generated.js +2 -0
  97. package/node_modules/@oxygen/shared/dist/version.js +8 -1
  98. package/node_modules/@oxygen/shared/dist/workspace-event-catalog.js +0 -23
  99. package/node_modules/@oxygen/shared/dist/workspace-file-storage.d.ts +29 -0
  100. package/node_modules/@oxygen/shared/dist/workspace-file-storage.js +31 -0
  101. package/node_modules/@oxygen/shared/package.json +9 -0
  102. package/package.json +2 -1
@@ -48,11 +48,68 @@ export const HOSTED_AI_MODEL_REGISTRY = {
48
48
  },
49
49
  },
50
50
  copilot: {
51
+ /**
52
+ * "Oxygen Auto" -- the only tier a new session gets, and the one the main
53
+ * conversation thread runs on for its whole life. It is NOT a router: the
54
+ * model never changes mid-session, because an OpenRouter prompt cache is
55
+ * model-scoped and a mid-turn switch would turn a ~66% cache HIT rate into a
56
+ * cache WRITE on a fresh model, ten times a turn. Models only change below
57
+ * this thread, where the context is fresh -- see COPILOT_ERRAND_LEVEL.
58
+ *
59
+ * `reasoningEffort: "medium"` is the change that made this tier worth
60
+ * shipping. Until 2026-09-21 this model was sent with NO `reasoning` field at
61
+ * all, on a registry comment asserting K3 was max-reasoning-only. Measured
62
+ * against the live API on the same prompt and tool schema, that claim was
63
+ * false and the omission was the expensive case:
64
+ *
65
+ * omitted -> 412 reasoning tokens, $0.00779, 10.0s
66
+ * low -> 206, $0.00566, 9.2s
67
+ * medium -> 124, $0.00342, 4.8s <- 56% cheaper, 2.1x faster
68
+ * high -> 528, $0.01075, 14.8s
69
+ *
70
+ * All four returned the same answer. Reasoning was 38% of output tokens on a
71
+ * surface where output is ~61% of the bill.
72
+ */
73
+ auto: {
74
+ model: "moonshotai/kimi-k3",
75
+ displayName: "Oxygen Auto",
76
+ // z-ai/glm-5.3 rather than the old moonshotai/kimi-k2.6: k2.6 advertises
77
+ // `reasoning` but NOT `reasoning_effort`, and caps at 262k context, so
78
+ // falling back to it silently dropped both the dial above and three
79
+ // quarters of the window. GLM-5.3 keeps both and caches automatically.
80
+ fallbackModels: ["z-ai/glm-5.3"],
81
+ reasoningEffort: "medium",
82
+ estPromptUsdPerM: 1.7,
83
+ estCompletionUsdPerM: 8.5,
84
+ maxOutputTokens: 8192,
85
+ },
51
86
  low: {
87
+ // The errand model: sub-agents, compaction summaries and auto-titles. A
88
+ // child builds its own Agent with its own messages, so it starts cold on
89
+ // any model -- which is why a switch is free HERE and nowhere above it.
90
+ //
91
+ // This was deepseek/deepseek-v4.1-flash for about an hour, chosen for
92
+ // being newer and measured correct on a one-tool arithmetic probe. Probed
93
+ // again against the REAL runtime tool schemas from tools.ts
94
+ // (capability_search + capability_run, nested `args`, optional approval
95
+ // fields) under the same provider.require_parameters=true the transport
96
+ // always sends, it returned `finish_reason: "error"` with zero tool calls
97
+ // on 1 of 5 attempts, every one served by the Relace endpoint. v4-flash
98
+ // went 5/5 clean on StreamLake, is CHEAPER on both axes, and is already
99
+ // what auto-titles run on -- so the newer model was worse on reliability
100
+ // and on price, and the only thing recommending it was its version number.
101
+ //
102
+ // A child that emits no tool call returns nothing for what it spent, and
103
+ // the transport does not retry `finish_reason: "error"` on the primary
104
+ // (classifyModelError sends it straight to the next model), so a 20%
105
+ // error rate here is a 20% double round trip on every delegation.
52
106
  model: "deepseek/deepseek-v4-flash",
53
107
  displayName: "DeepSeek V4 Flash",
54
- fallbackModels: [],
55
- reasoningEffort: "medium",
108
+ // v4.1-flash earns its place HERE: it works 4 times in 5 and it is a
109
+ // genuinely different endpoint on a different provider, which is the one
110
+ // thing a fallback has to be.
111
+ fallbackModels: ["deepseek/deepseek-v4.1-flash"],
112
+ reasoningEffort: "low",
56
113
  estPromptUsdPerM: 0.09,
57
114
  estCompletionUsdPerM: 0.18,
58
115
  maxOutputTokens: 8192,
@@ -66,14 +123,20 @@ export const HOSTED_AI_MODEL_REGISTRY = {
66
123
  estCompletionUsdPerM: 0.87,
67
124
  maxOutputTokens: 8192,
68
125
  },
126
+ /**
127
+ * Retained only for sessions created before "Oxygen Auto" shipped, whose
128
+ * `reasoning_level` is already 'high' on the row. Same model as `auto`, and
129
+ * it now carries the same effort dial -- the old "K3 is max-only" comment
130
+ * here was measured false (see `auto`), and an existing session should not
131
+ * keep paying for the omission just because it started earlier.
132
+ */
69
133
  high: {
70
134
  model: "moonshotai/kimi-k3",
71
135
  displayName: "Kimi K3",
72
- fallbackModels: ["moonshotai/kimi-k2.6"],
73
- // No reasoningEffort: Kimi K3 is max-only; the request builder omits the
74
- // reasoning param for this tier.
75
- estPromptUsdPerM: 3,
76
- estCompletionUsdPerM: 15,
136
+ fallbackModels: ["z-ai/glm-5.3"],
137
+ reasoningEffort: "medium",
138
+ estPromptUsdPerM: 1.7,
139
+ estCompletionUsdPerM: 8.5,
77
140
  maxOutputTokens: 8192,
78
141
  },
79
142
  },
@@ -125,13 +188,58 @@ export const MANAGED_AI_TIER_LABELS = {
125
188
  medium: "Oxygen Balanced",
126
189
  high: "Oxygen Max",
127
190
  };
128
- /** The reasoning tier the hosted copilot runs at by default. */
129
- export const COPILOT_DEFAULT_LEVEL = "high";
191
+ /**
192
+ * What the Copilot calls its tiers.
193
+ *
194
+ * Separate from MANAGED_AI_TIER_LABELS rather than folded into it because the
195
+ * Copilot's level set is not the AI column's: only the Copilot has `auto`, and
196
+ * only the Copilot has stopped offering a choice. AI columns and Agents still
197
+ * sell Fast/Balanced/Max and still mean it.
198
+ *
199
+ * Every current session reads "Oxygen Auto". The other three exist so a session
200
+ * created before 2026-09-21 still renders as the thing its owner picked, rather
201
+ * than being relabelled under them.
202
+ */
203
+ export const COPILOT_TIER_LABELS = {
204
+ ...MANAGED_AI_TIER_LABELS,
205
+ auto: "Oxygen Auto",
206
+ };
207
+ /**
208
+ * The tier every new Copilot session gets. There is no longer a picker: "Oxygen
209
+ * Auto" is the whole customer-facing choice (Philipp, 2026-09-21).
210
+ *
211
+ * It was `high` until then, which is why 83% of production sessions ran the most
212
+ * expensive tier -- 110 of 132 sessions across 69 of 81 tenants -- while the
213
+ * composer's own dropdown told the user that medium was "The default for most
214
+ * GTM work". Nobody chose that; we defaulted them into it.
215
+ */
216
+ export const COPILOT_DEFAULT_LEVEL = "auto";
217
+ /**
218
+ * The tier the Copilot's ERRANDS run at: sub-agent children, compaction
219
+ * summaries, and auto-titles.
220
+ *
221
+ * This is the only place a model may differ from the session's own, and it is
222
+ * safe for one reason: each of those builds a FRESH context rather than
223
+ * continuing the main transcript -- a child constructs its own Agent and
224
+ * messages (`packages/agent-runtime/src/subagents.ts`), and the summarizer sends
225
+ * a two-message prompt with no tools
226
+ * (`packages/agent-runtime/src/strands-runtime.ts` summarizeForCompaction). A
227
+ * cold context has no prompt cache to lose and no transcript to corrupt, so the
228
+ * switch costs nothing. Switching the main thread would cost both.
229
+ *
230
+ * It matters because delegation is habitual and currently doubles the price of a
231
+ * turn: measured over 30 days to 2026-09-21, the 26% of turns that fired
232
+ * `subagent_run` produced 45% of all Copilot credit burn (1,805 credits/turn
233
+ * against 786), because every child inherited the parent's model through the
234
+ * parent's own `callModel`.
235
+ */
236
+ export const COPILOT_ERRAND_LEVEL = "low";
130
237
  export const AGENT_DEFAULT_LEVEL = "medium";
131
238
  const LEVEL_ENV_SUFFIX = {
132
239
  low: "LOW",
133
240
  medium: "MEDIUM",
134
241
  high: "HIGH",
242
+ auto: "AUTO",
135
243
  };
136
244
  function readTrimmedEnv(env, key) {
137
245
  const raw = env[key];
@@ -181,7 +289,14 @@ export function findHostedAiModelSpec(model, preferredUseCase) {
181
289
  return null;
182
290
  }
183
291
  export function resolveHostedAiModel(input) {
184
- const base = HOSTED_AI_MODEL_REGISTRY[input.useCase][input.level];
292
+ // `auto` exists only on the copilot registry. Asking ai_column or agent for it
293
+ // is a caller bug, and resolving `undefined` here would hand the request
294
+ // builder a spec with no model id at all -- so it falls back to that use
295
+ // case's own default rather than reaching the provider with nothing.
296
+ const levels = HOSTED_AI_MODEL_REGISTRY[input.useCase];
297
+ const base = levels[input.level]
298
+ ?? levels[input.useCase === "copilot" ? COPILOT_DEFAULT_LEVEL : AGENT_DEFAULT_LEVEL]
299
+ ?? HOSTED_AI_MODEL_REGISTRY[input.useCase].medium;
185
300
  if (input.useCase === "ai_column")
186
301
  return base;
187
302
  const env = input.env ?? process.env;
@@ -95,6 +95,7 @@ export * from "./tags.js";
95
95
  export * from "./telemetry.js";
96
96
  export * from "./tenant-database-secret.js";
97
97
  export * from "./egress-transport-readiness.js";
98
+ export * from "./mailbox-egress-ownership.js";
98
99
  export * from "./rate-window.js";
99
100
  export * from "./timing.js";
100
101
  export * from "./type-guards.js";
@@ -135,5 +136,6 @@ export * from "./ugc-amplification-identity.js";
135
136
  export * from "./knowledge-repository.js";
136
137
  export * from "./knowledge-bases.js";
137
138
  export * from "./external-write-policy.js";
139
+ export * from "./cutover-freeze.js";
138
140
  export * from "./log-sink-selector.js";
139
141
  export * from "./otlp-log-sink.js";
@@ -106,6 +106,7 @@ export * from "./tags.js";
106
106
  export * from "./telemetry.js";
107
107
  export * from "./tenant-database-secret.js";
108
108
  export * from "./egress-transport-readiness.js";
109
+ export * from "./mailbox-egress-ownership.js";
109
110
  export * from "./rate-window.js";
110
111
  export * from "./timing.js";
111
112
  export * from "./type-guards.js";
@@ -171,5 +172,6 @@ export * from "./ugc-amplification-identity.js";
171
172
  export * from "./knowledge-repository.js";
172
173
  export * from "./knowledge-bases.js";
173
174
  export * from "./external-write-policy.js";
175
+ export * from "./cutover-freeze.js";
174
176
  export * from "./log-sink-selector.js";
175
177
  export * from "./otlp-log-sink.js";
@@ -1,3 +1,4 @@
1
+ import { type LlmPromptRef } from "./llm-prompts.js";
1
2
  type EnvMap = Record<string, string | undefined>;
2
3
  export type LlmObservationLevel = "DEBUG" | "DEFAULT" | "WARNING" | "ERROR";
3
4
  export type LlmTraceBody = {
@@ -45,6 +46,12 @@ export type LlmGenerationBody = LlmSpanBody & {
45
46
  completionStartTime?: Date | null;
46
47
  usageDetails?: Record<string, number>;
47
48
  costDetails?: Record<string, number>;
49
+ /**
50
+ * The template this call rendered from (`@oxygen/shared/llm-prompts`).
51
+ * Always recorded as metadata; a registered code prompt also links to its
52
+ * native Langfuse prompt version once that version has been resolved.
53
+ */
54
+ prompt?: LlmPromptRef | null;
48
55
  };
49
56
  export type LlmEventBody = {
50
57
  id: string;
@@ -137,7 +144,7 @@ export type LlmCorrelation = {
137
144
  };
138
145
  export type LlmEmission = {
139
146
  kind: LlmEmissionKind;
140
- observationId?: string;
147
+ observationId?: string | undefined;
141
148
  parentObservationId?: string;
142
149
  isRoot?: boolean;
143
150
  /** External seed (turn/run id) — hashed into the W3C trace id. */
@@ -159,6 +166,41 @@ export type LlmScorer = {
159
166
  /** Resolves true when the score was accepted. Never rejects. */
160
167
  score(body: LlmScoreBody): Promise<boolean>;
161
168
  };
169
+ type WarnFn = (error: unknown, context?: Record<string, unknown>) => void;
170
+ export type LlmExportSummary = {
171
+ /** OTLP spans Langfuse acknowledged (synthetic roots, slices and payload chunks each count). */
172
+ exported(count: number): void;
173
+ /** OTLP spans in a batch the exporter gave up on (same unit as exported). */
174
+ failed(count: number): void;
175
+ /**
176
+ * Client observations discarded before export (build error, transport
177
+ * unavailable), one per call even when it would have fanned out to several
178
+ * spans, so exported:dropped is not a like-for-like ratio.
179
+ */
180
+ dropped(count: number): void;
181
+ /** Logs the window when it is at least a minute old; otherwise no-op. */
182
+ maybeReport(): void;
183
+ /** Logs whatever is pending regardless of age (process shutdown). */
184
+ reportNow(): void;
185
+ };
186
+ export declare function createLlmExportSummary(now?: () => number): LlmExportSummary;
187
+ /**
188
+ * Resolves a registered code prompt (name + content hash) to the native
189
+ * Langfuse prompt version the deploy-time sync created for it. Synchronous
190
+ * and non-blocking: an unknown mapping returns undefined and starts one
191
+ * background lookup, so the first generation of a template in a process
192
+ * carries metadata only and later ones carry the native link.
193
+ *
194
+ * A deployed development process on the self-hosted instance also publishes a
195
+ * missing template itself (label `oxygen-<hash>` only; `latest` stays owned by
196
+ * the sync): every template change used to leave dev unlinked until someone ran
197
+ * the sync by hand. Production, Langfuse Cloud and local processes never
198
+ * publish; syncing those stays a human step.
199
+ */
200
+ export type LlmPromptVersionResolver = {
201
+ versionFor(prompt: LlmPromptRef): number | undefined;
202
+ };
203
+ export declare function createApiPromptResolver(env: EnvMap, warn: WarnFn, fetchImpl?: typeof fetch, now?: () => number): LlmPromptVersionResolver;
162
204
  /**
163
205
  * Construct a fail-open Langfuse client, or `null` when tracing is disabled or
164
206
  * misconfigured. Prefer the process-wide `getLlmTracingClient` in app code;
@@ -167,6 +209,7 @@ export type LlmScorer = {
167
209
  export declare function createLlmTracingClient(env?: EnvMap, options?: {
168
210
  emitterImpl?: LlmEmitter;
169
211
  scorerImpl?: LlmScorer;
212
+ promptResolverImpl?: LlmPromptVersionResolver;
170
213
  }): LlmTracingClient | null;
171
214
  export declare function getLlmTracingClient(env?: EnvMap): LlmTracingClient | null;
172
215
  /** Flush the singleton if it exists. Never rejects. Hang off request/cycle ends. */