@bike4mind/cli 3.3.0 → 4.0.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.
- package/README.md +139 -37
- package/bin/bike4mind-cli.mjs +55 -1
- package/bin/hearth-hook.mjs +53 -7
- package/dist/{AgentHistoryStore-CLidbOHG.mjs → AgentHistoryStore-DgqmcVLN.mjs} +5597 -5568
- package/dist/ApiClient-_JrM_xWw.mjs +133 -0
- package/dist/{ConfigStore-DUATzLxB.mjs → ConfigStore-BwqsQ0U9.mjs} +1409 -189
- package/dist/RemoteSkillSource-qTvRkaNA.mjs +455 -0
- package/dist/{WorkItemsClient-BSoOblGp.mjs → WorkItemsClient-CERTDrhT.mjs} +1 -1
- package/dist/{buildAgent-DyZWK0LW.mjs → buildToolSearch-D9GEK91u.mjs} +406 -47
- package/dist/commands/acpCommand.mjs +13 -13
- package/dist/commands/apiCommand.mjs +1 -1
- package/dist/commands/doctorCommand.mjs +1 -1
- package/dist/commands/envCommand.mjs +1 -1
- package/dist/commands/headlessCommand.mjs +5 -4
- package/dist/commands/mcpCommand.mjs +4 -3
- package/dist/commands/pluginCommand.mjs +1 -1
- package/dist/commands/skillsCommand.mjs +259 -0
- package/dist/commands/updateCommand.mjs +1 -1
- package/dist/{dist-DPP7UmK9.mjs → dist-Ul2qwn5x.mjs} +17 -132
- package/dist/index.mjs +171 -48
- package/dist/{package-DYPVrada.mjs → package-CQaam4Dq.mjs} +1 -1
- package/dist/{serve-w6v3rZiR.mjs → serve-CFxUhjml.mjs} +657 -27
- package/dist/store-BYeE0shc.mjs +2 -0
- package/dist/{store-BxmPEI3v.mjs → store-BbvSi3KK.mjs} +26 -2
- package/package.json +11 -10
- package/dist/store-BkMur6uk.mjs +0 -2
|
@@ -22,6 +22,49 @@ import { homedir as homedir$1 } from "node:os";
|
|
|
22
22
|
const APP_NAME = process.env.APP_NAME || "";
|
|
23
23
|
const WEBSITE_URL = process.env.WEBSITE_URL || "";
|
|
24
24
|
//#endregion
|
|
25
|
+
//#region ../../b4m-core/common/dist/skillMdSource-CNWRf6Lw.mjs
|
|
26
|
+
/**
|
|
27
|
+
* The marker an exported SKILL.md carries so Bike4Mind can recognize its own exports. The B4M
|
|
28
|
+
* CLI/desktop loader (packages/cli CustomCommandStore) skips stamped files, and a future CLI sync
|
|
29
|
+
* keys off it to find files it owns - keep the `# Bike4Mind-Source: <url>` line format stable.
|
|
30
|
+
*
|
|
31
|
+
* Deliberately import-free so the stamp check never needs a YAML parser. skillMd.ts, which does need
|
|
32
|
+
* one, sits behind `@bike4mind/common/utils/skillMd` rather than the barrel the CLI imports.
|
|
33
|
+
*/
|
|
34
|
+
const SKILL_MD_SOURCE_MARKER = "Bike4Mind-Source:";
|
|
35
|
+
/** Opening `---<lang>` fence, the frontmatter text, then the closing `---` line. */
|
|
36
|
+
const FRONTMATTER = /^---([^\r\n]*)\r?\n(?:([\s\S]*?)\r?\n)?---[ \t]*(?:\r?\n|$)/;
|
|
37
|
+
const SOURCE_LINE = new RegExp(`^[ \\t]*#[ \\t]*${SKILL_MD_SOURCE_MARKER}[ \\t]*(\\S+)`);
|
|
38
|
+
/** Splits a SKILL.md into its raw frontmatter and the rest; null when there is no closed fence. */
|
|
39
|
+
function splitSkillMdFrontmatter(text) {
|
|
40
|
+
if (text.charCodeAt(0) === 65279) text = text.slice(1);
|
|
41
|
+
const match = text.match(FRONTMATTER);
|
|
42
|
+
if (!match) return null;
|
|
43
|
+
return {
|
|
44
|
+
lang: match[1].trim().toLowerCase(),
|
|
45
|
+
frontmatter: match[2] ?? "",
|
|
46
|
+
rest: text.slice(match[0].length)
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** The source URL in the leading comment header, before any YAML data or scalar content. */
|
|
50
|
+
function readSkillMdSourceUrl(frontmatter) {
|
|
51
|
+
for (const line of frontmatter.split(/\r?\n/)) {
|
|
52
|
+
const trimmed = line.trim();
|
|
53
|
+
if (!trimmed) continue;
|
|
54
|
+
if (!trimmed.startsWith("#")) return void 0;
|
|
55
|
+
const match = line.match(SOURCE_LINE);
|
|
56
|
+
if (match) return match[1];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* True when the file's frontmatter carries the source stamp. Reads the raw fence text because the
|
|
61
|
+
* stamp is a YAML comment, which every YAML parser (gray-matter included) discards.
|
|
62
|
+
*/
|
|
63
|
+
function frontmatterHasSourceStamp(text) {
|
|
64
|
+
const split = splitSkillMdFrontmatter(text);
|
|
65
|
+
return !!split && readSkillMdSourceUrl(split.frontmatter) !== void 0;
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
25
68
|
//#region ../../b4m-core/hearth/dist/index.mjs
|
|
26
69
|
/**
|
|
27
70
|
* Zod validation for data crossing the Hearth boundary (API routes, CLI
|
|
@@ -354,6 +397,7 @@ const b4mLLMTools = z$1.enum([
|
|
|
354
397
|
"retrieve_knowledge_content",
|
|
355
398
|
"count_knowledge_base",
|
|
356
399
|
"describe_knowledge_base",
|
|
400
|
+
"decide",
|
|
357
401
|
"list_my_data_lakes",
|
|
358
402
|
"create_data_lake",
|
|
359
403
|
"save_content_to_data_lake",
|
|
@@ -747,6 +791,22 @@ const CHAT_HISTORY_ITEM_TYPES = [
|
|
|
747
791
|
"system",
|
|
748
792
|
"voice_transcript"
|
|
749
793
|
];
|
|
794
|
+
/**
|
|
795
|
+
* Why a turn's LLM call was retried. Timeouts we raise ourselves are classified ahead of
|
|
796
|
+
* overload so they never read as a provider fault (older backends worded them "may be
|
|
797
|
+
* overloaded"). Must stay in sync with classifyTurnRetryReason in @bike4mind/services.
|
|
798
|
+
*/
|
|
799
|
+
const TURN_RETRY_REASONS = [
|
|
800
|
+
"stream_idle_timeout",
|
|
801
|
+
"stream_truncated",
|
|
802
|
+
"request_timeout",
|
|
803
|
+
"rate_limit",
|
|
804
|
+
"overloaded",
|
|
805
|
+
"server_error",
|
|
806
|
+
"transport",
|
|
807
|
+
"tool_pairing",
|
|
808
|
+
"other"
|
|
809
|
+
];
|
|
750
810
|
/** Where a session was created. Absent on sessions that predate the field; render those as 'web'. */
|
|
751
811
|
const SESSION_ORIGIN_CHANNELS = [
|
|
752
812
|
"web",
|
|
@@ -805,6 +865,12 @@ function parseClaudeModelId(modelId) {
|
|
|
805
865
|
minor: minor === void 0 ? null : Number(minor)
|
|
806
866
|
};
|
|
807
867
|
}
|
|
868
|
+
/** `opus-4-5` for `claude-opus-4-5-20251101` or `global.anthropic.claude-opus-4-5-...`; null otherwise. */
|
|
869
|
+
function claudeFamilyVersion(modelId) {
|
|
870
|
+
const parsed = parseClaudeModelId(modelId);
|
|
871
|
+
if (!parsed) return null;
|
|
872
|
+
return parsed.minor === null ? `${parsed.family}-${parsed.major}` : `${parsed.family}-${parsed.major}-${parsed.minor}`;
|
|
873
|
+
}
|
|
808
874
|
/**
|
|
809
875
|
* Model backends
|
|
810
876
|
*/
|
|
@@ -978,6 +1044,7 @@ let ChatModels = /* @__PURE__ */ function(ChatModels) {
|
|
|
978
1044
|
ChatModels["TINYLLAMA"] = "tinyllama";
|
|
979
1045
|
ChatModels["DEEPSEEK_R1_BEDROCK"] = "us.deepseek.r1-v1:0";
|
|
980
1046
|
ChatModels["DEEPSEEK_V3_1"] = "deepseek.v3-v1:0";
|
|
1047
|
+
ChatModels["NOVA_PRO_BEDROCK"] = "us.amazon.nova-pro-v1:0";
|
|
981
1048
|
ChatModels["TITAN_TEXT_G1_LITE"] = "amazon.titan-text-lite-v1";
|
|
982
1049
|
ChatModels["TITAN_TEXT_G1_EXPRESS"] = "amazon.titan-text-express-v1";
|
|
983
1050
|
ChatModels["CLAUDE_3_HAIKU_BEDROCK"] = "anthropic.claude-3-haiku-20240307-v1:0";
|
|
@@ -1105,6 +1172,173 @@ z$1.enum({
|
|
|
1105
1172
|
...ImageModels,
|
|
1106
1173
|
...SpeechToTextModels
|
|
1107
1174
|
});
|
|
1175
|
+
let ApiKeyScope = /* @__PURE__ */ function(ApiKeyScope) {
|
|
1176
|
+
ApiKeyScope["READ_NOTEBOOKS"] = "notebooks:read";
|
|
1177
|
+
ApiKeyScope["WRITE_NOTEBOOKS"] = "notebooks:write";
|
|
1178
|
+
ApiKeyScope["READ_FILES"] = "files:read";
|
|
1179
|
+
ApiKeyScope["WRITE_FILES"] = "files:write";
|
|
1180
|
+
ApiKeyScope["AI_GENERATE"] = "ai:generate";
|
|
1181
|
+
/**
|
|
1182
|
+
* Only the Decisions API (`POST /api/v1/decisions`, `GET /api/v1/decision-models`): typed questions answered
|
|
1183
|
+
* with probabilities. `ai:generate` also opens these routes. Not confined, so like `me:read` it also passes
|
|
1184
|
+
* scope-less routes; an image sent by `file_id` additionally needs `files:read`.
|
|
1185
|
+
*/
|
|
1186
|
+
ApiKeyScope["AI_DECIDE"] = "ai:decide";
|
|
1187
|
+
ApiKeyScope["AI_CHAT"] = "ai:chat";
|
|
1188
|
+
ApiKeyScope["READ_PROJECTS"] = "projects:read";
|
|
1189
|
+
ApiKeyScope["WRITE_PROJECTS"] = "projects:write";
|
|
1190
|
+
/** List and read the key owner's agents (and agents shared with them). */
|
|
1191
|
+
ApiKeyScope["READ_AGENTS"] = "agents:read";
|
|
1192
|
+
/**
|
|
1193
|
+
* Create, update, delete and fund agents, manage their embed keys, and run the
|
|
1194
|
+
* agent-authoring assistants (description/avatar/system-prompt/field generation),
|
|
1195
|
+
* which spend the owner's credits on the agent's behalf.
|
|
1196
|
+
*/
|
|
1197
|
+
ApiKeyScope["WRITE_AGENTS"] = "agents:write";
|
|
1198
|
+
/** Authorizes only the cc-bridge WS actions (cc_agent_register /
|
|
1199
|
+
* cc_agent_event / cc_agent_disconnect). Keys with this scope CANNOT
|
|
1200
|
+
* call chat/completions - a leaked bridge key has the narrow blast
|
|
1201
|
+
* radius of a sprite-spawning credential, not a billable AI key. */
|
|
1202
|
+
ApiKeyScope["CC_BRIDGE"] = "cc-bridge:connect";
|
|
1203
|
+
/**
|
|
1204
|
+
* Read the key owner's OWN commercial state - tier, credit balance, entitlement
|
|
1205
|
+
* keys - via `GET /api/v1/me`. Split from the AI scopes on purpose: a key minted
|
|
1206
|
+
* to generate text has no business enumerating what its owner has paid for. It
|
|
1207
|
+
* reaches only `GET /api/v1/me` and its balance-only subset `GET /api/v1/credits`
|
|
1208
|
+
* (which the AI scopes also open, since spend needs a pre-flight check), so it
|
|
1209
|
+
* carries the `:read` suffix that puts it in the New-Key modal's read-only preset.
|
|
1210
|
+
*/
|
|
1211
|
+
ApiKeyScope["ME_READ"] = "me:read";
|
|
1212
|
+
ApiKeyScope["ADMIN"] = "admin:*";
|
|
1213
|
+
ApiKeyScope["MARKETING_REPORTS_READ"] = "marketing-reports:read";
|
|
1214
|
+
ApiKeyScope["MARKETING_REPORTS_WRITE"] = "marketing-reports:write";
|
|
1215
|
+
/** Server-to-server ingest scope for Overwatch analytics. Admin-provisioned only - never shown in user-facing key creation UI. */
|
|
1216
|
+
ApiKeyScope["OVERWATCH_INGEST_WRITE"] = "overwatch-ingest:write";
|
|
1217
|
+
/** Authorizes only embedded-widget chat against the single agent the key is
|
|
1218
|
+
* bound to (`agentId`). Like CC_BRIDGE, a leaked embed key has a narrow blast
|
|
1219
|
+
* radius: it can talk to one agent from allow-listed origins, nothing else. */
|
|
1220
|
+
ApiKeyScope["EMBED_CHAT"] = "embed:chat";
|
|
1221
|
+
/** Read a Hearth channel list and replay its events. Read-only: it cannot
|
|
1222
|
+
* advance an actor cursor, because consuming events out from under a
|
|
1223
|
+
* legitimate agent reader is a denial of context, not a read. */
|
|
1224
|
+
ApiKeyScope["HEARTH_READ"] = "hearth:read";
|
|
1225
|
+
/** Append Hearth events, create channels, and advance actor cursors. */
|
|
1226
|
+
ApiKeyScope["HEARTH_WRITE"] = "hearth:write";
|
|
1227
|
+
/**
|
|
1228
|
+
* Read OptiHashi problems, runs, and run artifacts. Deliberately split from
|
|
1229
|
+
* {@link OPTIHASHI_COMPUTE}: a key that only inspects results is structurally
|
|
1230
|
+
* unable to start a billable solve, so an agent-held key can be handed the
|
|
1231
|
+
* read half alone. Like every scope, it authorizes but never entitles - the
|
|
1232
|
+
* OptiHashi entitlement check still runs and can refuse on its own.
|
|
1233
|
+
*/
|
|
1234
|
+
ApiKeyScope["OPTIHASHI_READ"] = "optihashi:read";
|
|
1235
|
+
/**
|
|
1236
|
+
* Submit OptiHashi compute (solve/decompose/schedule) and cancel a run. This
|
|
1237
|
+
* is the spend half of the OptiHashi pair: it commissions external compute
|
|
1238
|
+
* that costs real money, so it is never implied by {@link OPTIHASHI_READ}.
|
|
1239
|
+
*/
|
|
1240
|
+
ApiKeyScope["OPTIHASHI_COMPUTE"] = "optihashi:compute";
|
|
1241
|
+
/**
|
|
1242
|
+
* Read data lakes and their contents: list/browse lakes (including keyword search over
|
|
1243
|
+
* articles), read a lake's health, spend, batches, and access view. Split from
|
|
1244
|
+
* {@link DATALAKE_WRITE} so a key handed to an agent can look at a lake without being able to
|
|
1245
|
+
* change one. A retrieval query that spends LLM/search budget (semantic search, the RLM answer
|
|
1246
|
+
* endpoint) needs {@link DATALAKE_QUERY} instead: this scope does not imply it, though a
|
|
1247
|
+
* {@link DATALAKE_QUERY} key does gain this one (it has to, to reach the read-gated routes its
|
|
1248
|
+
* own retrieval tools call back into).
|
|
1249
|
+
*/
|
|
1250
|
+
ApiKeyScope["DATALAKE_READ"] = "datalake:read";
|
|
1251
|
+
/**
|
|
1252
|
+
* Change what is IN a lake or how it behaves: create/update/archive a lake,
|
|
1253
|
+
* attach, detach, retag, or purge its files, run converge/rechunk/research,
|
|
1254
|
+
* and manage upload batches. Deliberately does NOT carry
|
|
1255
|
+
* {@link DATALAKE_SHARE}: adding files to a lake is a different privilege
|
|
1256
|
+
* from handing the lake to someone else.
|
|
1257
|
+
*/
|
|
1258
|
+
ApiKeyScope["DATALAKE_WRITE"] = "datalake:write";
|
|
1259
|
+
/**
|
|
1260
|
+
* Change WHO can reach a lake: its visibility and its ownership (and the
|
|
1261
|
+
* grant/revoke door). Never implied by {@link DATALAKE_WRITE} - re-sharing a
|
|
1262
|
+
* lake widens the blast radius of every document already in it, which is not
|
|
1263
|
+
* what a key minted to keep a lake's files current asked for.
|
|
1264
|
+
*/
|
|
1265
|
+
ApiKeyScope["DATALAKE_SHARE"] = "datalake:share";
|
|
1266
|
+
/**
|
|
1267
|
+
* Run a retrieval query that spends LLM/search budget against a lake: semantic search and the
|
|
1268
|
+
* RLM answer endpoint. Deliberately NOT suffixed `:read` - {@link DATALAKE_READ} feeds the
|
|
1269
|
+
* New-Key modal's "Read-only" preset (`s.value.endsWith(':read')`), and a key an operator mints
|
|
1270
|
+
* expecting that preset to be free must not auto-join a scope that commissions billable work.
|
|
1271
|
+
* Mirrors {@link OPTIHASHI_COMPUTE}'s split from {@link OPTIHASHI_READ}. Never implied by
|
|
1272
|
+
* {@link DATALAKE_READ} or {@link DATALAKE_WRITE} - spend on a lake is opt-in on its own. The
|
|
1273
|
+
* implication runs the other way for gating purposes: a key holding only this scope also passes
|
|
1274
|
+
* {@link DATALAKE_READ}'s gate, because the RLM answer endpoint's in-REPL tools call back into
|
|
1275
|
+
* read-gated routes (e.g. GET /api/data-lakes/articles) with the caller's own credential.
|
|
1276
|
+
*/
|
|
1277
|
+
ApiKeyScope["DATALAKE_QUERY"] = "datalake:query";
|
|
1278
|
+
/**
|
|
1279
|
+
* Read the Overwatch analytics surface - the cross-product overview, product
|
|
1280
|
+
* inventory and config, first-party metrics, product-stat history, funnel,
|
|
1281
|
+
* and pipeline freshness. Exists so an agent can be handed a credential that
|
|
1282
|
+
* can only *look*: it is deliberately NOT the read half of
|
|
1283
|
+
* {@link OVERWATCH_INGEST_WRITE}, which is a per-product ingest credential
|
|
1284
|
+
* bound to one `productId` and able to write that product's numbers. Handing
|
|
1285
|
+
* an explorer the ingest key would let it fabricate the very stats it reports
|
|
1286
|
+
* on, so the two are separate scopes rather than a read/write pair.
|
|
1287
|
+
*
|
|
1288
|
+
* Like every scope, it authorizes but never entitles - the Overwatch access
|
|
1289
|
+
* check (`requestHasOverwatchAccess`: admin OR developer OR `overwatch:pro`)
|
|
1290
|
+
* still runs against the key's owner and can refuse on its own. A key minted
|
|
1291
|
+
* with this scope by a user who does not hold Overwatch access opens nothing.
|
|
1292
|
+
* That check and the routes it guards live in the Overwatch overlay package;
|
|
1293
|
+
* neither has an implementation in this repository, so nothing here verifies
|
|
1294
|
+
* the claim - it is a property of the consumer, recorded for the reader.
|
|
1295
|
+
*/
|
|
1296
|
+
ApiKeyScope["OVERWATCH_READ"] = "overwatch:read";
|
|
1297
|
+
/**
|
|
1298
|
+
* CI-to-server ingest of Playwright runs for the admin /status page
|
|
1299
|
+
* (`POST /api/qa/uploads`, `POST /api/qa/runs`). Admin-provisioned only,
|
|
1300
|
+
* and confined like {@link OVERWATCH_INGEST_WRITE}: a leaked CI key reaches the
|
|
1301
|
+
* two ingest routes and nothing else. The routes also require the key's owner
|
|
1302
|
+
* to carry the `qa-ingest` user tag (QA_INGEST_USER_TAG in schemas/qa.ts).
|
|
1303
|
+
*/
|
|
1304
|
+
ApiKeyScope["QA_INGEST"] = "qa:ingest";
|
|
1305
|
+
/**
|
|
1306
|
+
* List and download the Claude Code plugin feed of an org's approved Skill Market listings
|
|
1307
|
+
* (`/api/v1/skills/market/*`). Confined: the key ends up in plaintext in `~/.claude/settings.json`,
|
|
1308
|
+
* so it must reach nothing else. Minted from the Skill Market's "Use in Claude Code" dialog.
|
|
1309
|
+
*/
|
|
1310
|
+
ApiKeyScope["SKILLS_READ"] = "skills:read";
|
|
1311
|
+
/**
|
|
1312
|
+
* Release-note automation: find a release note and set its video, and upload the What's New
|
|
1313
|
+
* media for it. Admin-provisioned and confined so the job needs no `admin:*`
|
|
1314
|
+
* key: it reaches only the routes that name it, and those still require a platform-admin owner.
|
|
1315
|
+
*/
|
|
1316
|
+
ApiKeyScope["RELEASE_NOTES_WRITE"] = "release-notes:write";
|
|
1317
|
+
/**
|
|
1318
|
+
* Read the key owner's own Bob results: single-site reads, two-site comparisons and
|
|
1319
|
+
* re-checks, the recent-reports list, and how many runs are left. It starts nothing and
|
|
1320
|
+
* spends nothing, so the `:read` suffix that puts it in the New-Key modal's Read-only
|
|
1321
|
+
* preset is deliberate, and safe there because every read is scoped to the key's owner.
|
|
1322
|
+
* Split from {@link BOB_RUN} so an agent can be handed the read half alone.
|
|
1323
|
+
*
|
|
1324
|
+
* Like every scope, it authorizes but never entitles. The Bob routes, and the gate that
|
|
1325
|
+
* decides which of the two scopes each one accepts, live in the Bob overlay package and
|
|
1326
|
+
* have no implementation in this repository, so nothing here verifies either claim.
|
|
1327
|
+
*/
|
|
1328
|
+
ApiKeyScope["BOB_READ"] = "bob:read";
|
|
1329
|
+
/**
|
|
1330
|
+
* Start a Bob site read, a two-site comparison or a re-check. This is the spend half of
|
|
1331
|
+
* the Bob pair: it spends the key owner's credits and publishes a report as them, so it
|
|
1332
|
+
* is never implied by {@link BOB_READ}, and it is deliberately unsuffixed so it stays out
|
|
1333
|
+
* of the Read-only and Read & write presets, as {@link OPTIHASHI_COMPUTE} does. Nor does
|
|
1334
|
+
* it imply {@link BOB_READ} at this repository's scope gate.
|
|
1335
|
+
*
|
|
1336
|
+
* Authorizes without entitling, like {@link BOB_READ}: the gate that enforces it lives in
|
|
1337
|
+
* the Bob overlay package, with no implementation here.
|
|
1338
|
+
*/
|
|
1339
|
+
ApiKeyScope["BOB_RUN"] = "bob:run";
|
|
1340
|
+
return ApiKeyScope;
|
|
1341
|
+
}({});
|
|
1108
1342
|
Object.freeze({
|
|
1109
1343
|
requestsPerMinute: 60,
|
|
1110
1344
|
requestsPerDay: 1e3
|
|
@@ -1236,6 +1470,42 @@ const GenericCreditAddTransaction = BaseCreditTransaction.extend({
|
|
|
1236
1470
|
transactionId: z$1.string().optional()
|
|
1237
1471
|
});
|
|
1238
1472
|
/**
|
|
1473
|
+
* Built-in reasons for generic credit deductions; they seed the registry below.
|
|
1474
|
+
* A package that needs a new reason registers it with registerGenericDeductReason
|
|
1475
|
+
* rather than extending this list.
|
|
1476
|
+
*/
|
|
1477
|
+
const GenericDeductReasons = [
|
|
1478
|
+
"dispute_clawback",
|
|
1479
|
+
"refund_clawback",
|
|
1480
|
+
"payment_failed_clawback",
|
|
1481
|
+
"notebook_curation",
|
|
1482
|
+
"manual",
|
|
1483
|
+
"admin_adjustment",
|
|
1484
|
+
"refund_adjustment",
|
|
1485
|
+
"optihashi_reservation",
|
|
1486
|
+
"optihashi_cost_chargeup",
|
|
1487
|
+
"credit_expiry"
|
|
1488
|
+
];
|
|
1489
|
+
const GENERIC_DEDUCT_REASON_PATTERN = /^[a-z][a-z0-9_]*$/;
|
|
1490
|
+
const GENERIC_DEDUCT_REASON_REGISTRY_KEY = Symbol.for("b4m.credit.genericDeductReasons");
|
|
1491
|
+
let seededRegistry;
|
|
1492
|
+
function genericDeductReasonRegistry() {
|
|
1493
|
+
const holder = globalThis;
|
|
1494
|
+
let registry = holder[GENERIC_DEDUCT_REASON_REGISTRY_KEY];
|
|
1495
|
+
if (!registry) {
|
|
1496
|
+
registry = /* @__PURE__ */ new Set();
|
|
1497
|
+
holder[GENERIC_DEDUCT_REASON_REGISTRY_KEY] = registry;
|
|
1498
|
+
}
|
|
1499
|
+
if (seededRegistry !== registry) {
|
|
1500
|
+
for (const reason of GenericDeductReasons) registry.add(reason);
|
|
1501
|
+
seededRegistry = registry;
|
|
1502
|
+
}
|
|
1503
|
+
return registry;
|
|
1504
|
+
}
|
|
1505
|
+
function isGenericDeductReason(value) {
|
|
1506
|
+
return typeof value === "string" && GENERIC_DEDUCT_REASON_PATTERN.test(value) && genericDeductReasonRegistry().has(value);
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1239
1509
|
* Generic credit deduction transaction for legacy data and flexible use cases
|
|
1240
1510
|
* Represents any credit deduction that doesn't fit specific categories
|
|
1241
1511
|
* (e.g., admin adjustments, legacy usage, manual deductions)
|
|
@@ -1247,20 +1517,10 @@ const GenericCreditDeductTransaction = BaseCreditTransaction.extend({
|
|
|
1247
1517
|
*/
|
|
1248
1518
|
userId: z$1.string().optional(),
|
|
1249
1519
|
/**
|
|
1250
|
-
* Reason/source for the transaction
|
|
1520
|
+
* Reason/source for the transaction: a built-in GenericDeductReasons value or one added with
|
|
1521
|
+
* registerGenericDeductReason.
|
|
1251
1522
|
*/
|
|
1252
|
-
reason: z$1.
|
|
1253
|
-
"dispute_clawback",
|
|
1254
|
-
"refund_clawback",
|
|
1255
|
-
"payment_failed_clawback",
|
|
1256
|
-
"notebook_curation",
|
|
1257
|
-
"manual",
|
|
1258
|
-
"admin_adjustment",
|
|
1259
|
-
"refund_adjustment",
|
|
1260
|
-
"optihashi_reservation",
|
|
1261
|
-
"optihashi_cost_chargeup",
|
|
1262
|
-
"credit_expiry"
|
|
1263
|
-
]).optional(),
|
|
1523
|
+
reason: z$1.custom(isGenericDeductReason, { error: (issue) => typeof issue.input === "string" ? "Unregistered generic deduct reason" : `Expected a generic deduct reason string, received ${issue.input === null ? "null" : typeof issue.input}` }).optional(),
|
|
1264
1524
|
/**
|
|
1265
1525
|
* Stripe dispute ID - set for dispute clawback transactions.
|
|
1266
1526
|
* Used for idempotency (unique sparse index prevents duplicate clawbacks).
|
|
@@ -1428,6 +1688,25 @@ const USAGE_EVENT_STATUSES = [
|
|
|
1428
1688
|
"refusal",
|
|
1429
1689
|
"degenerate"
|
|
1430
1690
|
];
|
|
1691
|
+
/** Where a UsageEvent's rates came from: a ModelPrice catalog row, or the adapter literal fallback. */
|
|
1692
|
+
const USAGE_PRICE_SOURCES = ["catalog", "literal"];
|
|
1693
|
+
/** USD per token for the pricing tier that priced a call (see AppliedRates in models.ts). */
|
|
1694
|
+
const UsageEventRates = z$1.object({
|
|
1695
|
+
/** The pricing-map key (input-token threshold) of the tier applied. */
|
|
1696
|
+
tierKey: z$1.number(),
|
|
1697
|
+
input: z$1.number(),
|
|
1698
|
+
output: z$1.number(),
|
|
1699
|
+
cacheRead: z$1.number().optional(),
|
|
1700
|
+
cacheWrite: z$1.number().optional()
|
|
1701
|
+
});
|
|
1702
|
+
/** One provider request of a multi-turn completion, with the tier it was priced on. */
|
|
1703
|
+
const UsageEventTurn = z$1.object({
|
|
1704
|
+
inputTokens: z$1.number(),
|
|
1705
|
+
outputTokens: z$1.number(),
|
|
1706
|
+
cacheReadTokens: z$1.number().optional(),
|
|
1707
|
+
cacheWriteTokens: z$1.number().optional(),
|
|
1708
|
+
tierKey: z$1.number()
|
|
1709
|
+
});
|
|
1431
1710
|
z$1.object({
|
|
1432
1711
|
id: z$1.string().optional(),
|
|
1433
1712
|
/** App-level correlation id: questId for chat/image/video, session/run id otherwise. */
|
|
@@ -1473,6 +1752,30 @@ z$1.object({
|
|
|
1473
1752
|
source: z$1.enum(COMPLETION_SOURCES).optional(),
|
|
1474
1753
|
/** API key that authed the call; present only for API-key-authed usage. */
|
|
1475
1754
|
apiKeyId: z$1.string().optional(),
|
|
1755
|
+
/** 'catalog' when a ModelPrice row priced the call, 'literal' when the adapter literal did. */
|
|
1756
|
+
priceSource: z$1.enum(USAGE_PRICE_SOURCES).optional(),
|
|
1757
|
+
/** The ModelPrice row in force; set only when priceSource is 'catalog'. */
|
|
1758
|
+
priceRowId: z$1.string().optional(),
|
|
1759
|
+
/**
|
|
1760
|
+
* Rates of the tier applied. A multi-turn row whose turns hit different tiers carries the
|
|
1761
|
+
* tier of its largest turn; turnUsage has each turn's own tierKey, but not that tier's rates,
|
|
1762
|
+
* so only a single-tier text charge is recomputable from its own fields. Provider-basis chat
|
|
1763
|
+
* rows use providerInputTokens/providerOutputTokens plus the cache buckets. Local-estimate chat
|
|
1764
|
+
* rows use input * (inputTokens - cachedInputTokens) + cacheRead * cachedInputTokens
|
|
1765
|
+
* + output * outputTokens. Operational and CLI rows use disjoint input/cache buckets instead:
|
|
1766
|
+
* input * inputTokens + cacheRead * cachedInputTokens + cacheWrite * cacheWriteTokens
|
|
1767
|
+
* + output * outputTokens, even when settledBasis is 'local' or unset.
|
|
1768
|
+
* Local-estimate chat rows are inexact when a fallback uses a different tokenEstimateMultiplier:
|
|
1769
|
+
* inputTokens remains in the requested model's units. Tool spend on other models is not covered.
|
|
1770
|
+
*/
|
|
1771
|
+
rates: UsageEventRates.optional(),
|
|
1772
|
+
/**
|
|
1773
|
+
* Per-turn usage, written only when the completion settled over more than one provider
|
|
1774
|
+
* request (tool loops bill turn by turn). Capped at USAGE_EVENT_TURN_USAGE_CAP entries.
|
|
1775
|
+
*/
|
|
1776
|
+
turnUsage: z$1.array(UsageEventTurn).optional(),
|
|
1777
|
+
/** True when turnUsage was capped: its last entry is the sum of every turn from there on. */
|
|
1778
|
+
turnUsageTruncated: z$1.boolean().optional(),
|
|
1476
1779
|
createdAt: z$1.date(),
|
|
1477
1780
|
updatedAt: z$1.date()
|
|
1478
1781
|
});
|
|
@@ -1545,6 +1848,7 @@ const ADAPTER_FAMILIES = [
|
|
|
1545
1848
|
"bedrock-moonshot",
|
|
1546
1849
|
"bedrock-jurassic",
|
|
1547
1850
|
"bedrock-titan",
|
|
1851
|
+
"bedrock-converse",
|
|
1548
1852
|
"gemini",
|
|
1549
1853
|
"xai",
|
|
1550
1854
|
"kimi",
|
|
@@ -1616,6 +1920,8 @@ const LIFECYCLE_STATUSES = [...[
|
|
|
1616
1920
|
"retired"
|
|
1617
1921
|
], "unlisted"];
|
|
1618
1922
|
const LifecycleWrite = z$1.strictObject({
|
|
1923
|
+
/** Absent on v1 rows means current; true folds the model without disabling it. */
|
|
1924
|
+
isSuperseded: z$1.boolean().optional(),
|
|
1619
1925
|
status: z$1.enum(LIFECYCLE_STATUSES),
|
|
1620
1926
|
deprecationDate: CALENDAR_DATE.optional(),
|
|
1621
1927
|
retirementDate: CALENDAR_DATE.optional(),
|
|
@@ -1799,6 +2105,7 @@ const MODEL_INFO_FIELD_GROUP_OF = {
|
|
|
1799
2105
|
supportsTools: "modalities",
|
|
1800
2106
|
supportsImageVariation: "modalities",
|
|
1801
2107
|
supportsSafetyTolerance: "modalities",
|
|
2108
|
+
isSuperseded: "lifecycle",
|
|
1802
2109
|
deprecationDate: "lifecycle",
|
|
1803
2110
|
replacedBy: "lifecycle",
|
|
1804
2111
|
adapterFamily: "dispatch",
|
|
@@ -2324,6 +2631,59 @@ z$1.object({
|
|
|
2324
2631
|
summary: z$1.string(),
|
|
2325
2632
|
counts: orgFeedbackSummaryCountsSchema
|
|
2326
2633
|
});
|
|
2634
|
+
const MODAL_MEDIA_HOST_SUFFIXES = [".amazonaws.com", ".cloudfront.net"];
|
|
2635
|
+
const MODAL_MEDIA_URL_MAX_LENGTH = 2048;
|
|
2636
|
+
const MODAL_MEDIA_URL_HINT = "Upload the file, or paste an https URL on amazonaws.com or cloudfront.net";
|
|
2637
|
+
function isAllowedModalMediaUrl(url, policy = {}) {
|
|
2638
|
+
if (url.length > MODAL_MEDIA_URL_MAX_LENGTH) return false;
|
|
2639
|
+
if (policy.allowedUrls?.has(url)) return true;
|
|
2640
|
+
try {
|
|
2641
|
+
const { protocol, hostname, origin, port } = new URL(url);
|
|
2642
|
+
if (policy.extraOrigins?.includes(origin)) return true;
|
|
2643
|
+
return protocol === "https:" && port === "" && MODAL_MEDIA_HOST_SUFFIXES.some((suffix) => hostname.endsWith(suffix));
|
|
2644
|
+
} catch {
|
|
2645
|
+
return false;
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
/** Per-field problems with a modal video, empty when it is valid. Shared by the admin form and the API. */
|
|
2649
|
+
function getModalVideoErrors(video, policy = {}) {
|
|
2650
|
+
const errors = {};
|
|
2651
|
+
if (!video) return errors;
|
|
2652
|
+
for (const field of [
|
|
2653
|
+
"landscapeUrl",
|
|
2654
|
+
"landscapePosterUrl",
|
|
2655
|
+
"portraitUrl",
|
|
2656
|
+
"portraitPosterUrl"
|
|
2657
|
+
]) {
|
|
2658
|
+
const url = video[field];
|
|
2659
|
+
if (url && !isAllowedModalMediaUrl(url, policy)) errors[field] = MODAL_MEDIA_URL_HINT;
|
|
2660
|
+
}
|
|
2661
|
+
if (video.landscapePosterUrl && !video.landscapeUrl) errors.landscapePosterUrl ??= "A 16:9 poster needs its 16:9 video";
|
|
2662
|
+
if (video.portraitPosterUrl && !video.portraitUrl) errors.portraitPosterUrl ??= "A 9:16 poster needs its 9:16 video";
|
|
2663
|
+
return errors;
|
|
2664
|
+
}
|
|
2665
|
+
/** The video's fields with no host check, for reading stored or upstream data written under another policy. */
|
|
2666
|
+
const ModalVideoShapeSchema = z$1.object({
|
|
2667
|
+
landscapeUrl: z$1.string().nullable().optional(),
|
|
2668
|
+
landscapePosterUrl: z$1.string().nullable().optional(),
|
|
2669
|
+
portraitUrl: z$1.string().nullable().optional(),
|
|
2670
|
+
portraitPosterUrl: z$1.string().nullable().optional()
|
|
2671
|
+
});
|
|
2672
|
+
/**
|
|
2673
|
+
* Product video for a modal slide. Landscape is the 16:9 cut shown on desktop, portrait the 9:16 cut
|
|
2674
|
+
* shown on mobile; the slider falls back to the other orientation when one is missing. The API passes
|
|
2675
|
+
* its deployment's extra origins; the bare `ModalVideoSchema` allows only the static host list.
|
|
2676
|
+
*/
|
|
2677
|
+
function createModalVideoSchema(policy = {}) {
|
|
2678
|
+
return ModalVideoShapeSchema.superRefine((video, ctx) => {
|
|
2679
|
+
for (const [field, message] of Object.entries(getModalVideoErrors(video, policy))) ctx.addIssue({
|
|
2680
|
+
code: "custom",
|
|
2681
|
+
path: [field],
|
|
2682
|
+
message
|
|
2683
|
+
});
|
|
2684
|
+
});
|
|
2685
|
+
}
|
|
2686
|
+
createModalVideoSchema();
|
|
2327
2687
|
/**
|
|
2328
2688
|
* Check if a value is a placeholder (not configured or SST default).
|
|
2329
2689
|
* Uses case-insensitive comparison and trims whitespace to prevent bypass attempts.
|
|
@@ -2940,18 +3300,21 @@ const AuditChangeSchema = z$1.object({
|
|
|
2940
3300
|
before: z$1.unknown(),
|
|
2941
3301
|
after: z$1.unknown()
|
|
2942
3302
|
});
|
|
3303
|
+
/** Sources a stored AdminAuditLog row can carry; the write input and the filters stay inside this set. */
|
|
3304
|
+
const StoredAuditContextSourceSchema = z$1.enum([
|
|
3305
|
+
"admin_ui",
|
|
3306
|
+
"api_key",
|
|
3307
|
+
"script",
|
|
3308
|
+
"worker"
|
|
3309
|
+
]);
|
|
3310
|
+
/** Read-side context: 'user' is the account holder's own session, which only the security-store adapters emit. */
|
|
2943
3311
|
const AuditContextSchema = z$1.object({
|
|
2944
3312
|
ip: z$1.string().optional(),
|
|
2945
3313
|
userAgent: z$1.string().optional(),
|
|
2946
3314
|
requestId: z$1.string().optional(),
|
|
2947
|
-
source:
|
|
2948
|
-
"admin_ui",
|
|
2949
|
-
"api_key",
|
|
2950
|
-
"script",
|
|
2951
|
-
"worker"
|
|
2952
|
-
]),
|
|
3315
|
+
source: StoredAuditContextSourceSchema,
|
|
2953
3316
|
route: z$1.string().optional()
|
|
2954
|
-
});
|
|
3317
|
+
}).extend({ source: z$1.union([StoredAuditContextSourceSchema, z$1.literal("user")]) });
|
|
2955
3318
|
const AdminAuditCategorySchema = z$1.enum([
|
|
2956
3319
|
"credits",
|
|
2957
3320
|
"access",
|
|
@@ -2992,6 +3355,268 @@ z$1.object({
|
|
|
2992
3355
|
}).optional(),
|
|
2993
3356
|
backfilled: z$1.boolean().optional()
|
|
2994
3357
|
});
|
|
3358
|
+
z$1.string({ error: "A reason is required" }).trim().min(5, `A reason of at least 5 characters is required`).max(500);
|
|
3359
|
+
/** App defaults for the AdminSettings grant thresholds (AdminAuditCriticalGrantCredits / AdminAuditDailyGrantCredits). */
|
|
3360
|
+
const ADMIN_AUDIT_DEFAULT_CRITICAL_GRANT_CREDITS = 5e4;
|
|
3361
|
+
const ADMIN_AUDIT_DEFAULT_DAILY_GRANT_CREDITS = 2e5;
|
|
3362
|
+
const ADMIN_AUDIT_CATALOGUE = {
|
|
3363
|
+
"org.credits.granted": {
|
|
3364
|
+
category: "credits",
|
|
3365
|
+
severity: "notice",
|
|
3366
|
+
write: "strict",
|
|
3367
|
+
escalatesAboveGrantThreshold: true
|
|
3368
|
+
},
|
|
3369
|
+
"org.credits.topped_up": {
|
|
3370
|
+
category: "credits",
|
|
3371
|
+
severity: "notice",
|
|
3372
|
+
write: "strict",
|
|
3373
|
+
escalatesAboveGrantThreshold: true
|
|
3374
|
+
},
|
|
3375
|
+
"org.credits.adjusted": {
|
|
3376
|
+
category: "credits",
|
|
3377
|
+
severity: "notice",
|
|
3378
|
+
write: "strict",
|
|
3379
|
+
escalatesAboveGrantThreshold: true
|
|
3380
|
+
},
|
|
3381
|
+
"org.credits.refunded": {
|
|
3382
|
+
category: "credits",
|
|
3383
|
+
severity: "notice",
|
|
3384
|
+
write: "strict",
|
|
3385
|
+
escalatesAboveGrantThreshold: true
|
|
3386
|
+
},
|
|
3387
|
+
"user.subscription.granted": {
|
|
3388
|
+
category: "credits",
|
|
3389
|
+
severity: "notice",
|
|
3390
|
+
write: "strict"
|
|
3391
|
+
},
|
|
3392
|
+
"user.credits.adjusted": {
|
|
3393
|
+
category: "credits",
|
|
3394
|
+
severity: "notice",
|
|
3395
|
+
write: "strict",
|
|
3396
|
+
escalatesAboveGrantThreshold: true
|
|
3397
|
+
},
|
|
3398
|
+
"user.credits.denied": {
|
|
3399
|
+
category: "credits",
|
|
3400
|
+
severity: "critical",
|
|
3401
|
+
write: "bestEffort"
|
|
3402
|
+
},
|
|
3403
|
+
"user.subscription.denied": {
|
|
3404
|
+
category: "credits",
|
|
3405
|
+
severity: "critical",
|
|
3406
|
+
write: "bestEffort"
|
|
3407
|
+
},
|
|
3408
|
+
"user.role.admin_granted": {
|
|
3409
|
+
category: "access",
|
|
3410
|
+
severity: "critical",
|
|
3411
|
+
write: "strict"
|
|
3412
|
+
},
|
|
3413
|
+
"user.role.admin_revoked": {
|
|
3414
|
+
category: "access",
|
|
3415
|
+
severity: "critical",
|
|
3416
|
+
write: "strict"
|
|
3417
|
+
},
|
|
3418
|
+
"user.role.denied": {
|
|
3419
|
+
category: "access",
|
|
3420
|
+
severity: "critical",
|
|
3421
|
+
write: "bestEffort"
|
|
3422
|
+
},
|
|
3423
|
+
"user.impersonation.started": {
|
|
3424
|
+
category: "access",
|
|
3425
|
+
severity: "critical",
|
|
3426
|
+
write: "strict"
|
|
3427
|
+
},
|
|
3428
|
+
"user.impersonation.ended": {
|
|
3429
|
+
category: "access",
|
|
3430
|
+
severity: "info",
|
|
3431
|
+
write: "bestEffort"
|
|
3432
|
+
},
|
|
3433
|
+
"user.impersonation.denied": {
|
|
3434
|
+
category: "access",
|
|
3435
|
+
severity: "critical",
|
|
3436
|
+
write: "bestEffort"
|
|
3437
|
+
},
|
|
3438
|
+
"user.deleted": {
|
|
3439
|
+
category: "account",
|
|
3440
|
+
severity: "critical",
|
|
3441
|
+
write: "strict"
|
|
3442
|
+
},
|
|
3443
|
+
"user.deletion.denied": {
|
|
3444
|
+
category: "account",
|
|
3445
|
+
severity: "critical",
|
|
3446
|
+
write: "bestEffort"
|
|
3447
|
+
},
|
|
3448
|
+
"user.profile.updated": {
|
|
3449
|
+
category: "account",
|
|
3450
|
+
severity: "notice",
|
|
3451
|
+
write: "bestEffort"
|
|
3452
|
+
},
|
|
3453
|
+
"org.seats.changed": {
|
|
3454
|
+
category: "org",
|
|
3455
|
+
severity: "notice",
|
|
3456
|
+
write: "bestEffort"
|
|
3457
|
+
},
|
|
3458
|
+
"org.seats.ceiling_raised": {
|
|
3459
|
+
category: "org",
|
|
3460
|
+
severity: "info",
|
|
3461
|
+
write: "bestEffort"
|
|
3462
|
+
},
|
|
3463
|
+
"org.conversion.initiated": {
|
|
3464
|
+
category: "org",
|
|
3465
|
+
severity: "notice",
|
|
3466
|
+
write: "bestEffort"
|
|
3467
|
+
},
|
|
3468
|
+
"org.revoked": {
|
|
3469
|
+
category: "org",
|
|
3470
|
+
severity: "notice",
|
|
3471
|
+
write: "strict"
|
|
3472
|
+
},
|
|
3473
|
+
"org.group_types.updated": {
|
|
3474
|
+
category: "org",
|
|
3475
|
+
severity: "info",
|
|
3476
|
+
write: "bestEffort"
|
|
3477
|
+
},
|
|
3478
|
+
"org.admins.updated": {
|
|
3479
|
+
category: "org",
|
|
3480
|
+
severity: "notice",
|
|
3481
|
+
write: "bestEffort"
|
|
3482
|
+
},
|
|
3483
|
+
"org.group_member.assigned": {
|
|
3484
|
+
category: "org",
|
|
3485
|
+
severity: "info",
|
|
3486
|
+
write: "bestEffort"
|
|
3487
|
+
},
|
|
3488
|
+
"org.group_member.unassigned": {
|
|
3489
|
+
category: "org",
|
|
3490
|
+
severity: "info",
|
|
3491
|
+
write: "bestEffort"
|
|
3492
|
+
},
|
|
3493
|
+
"org.invite.created": {
|
|
3494
|
+
category: "org",
|
|
3495
|
+
severity: "info",
|
|
3496
|
+
write: "bestEffort"
|
|
3497
|
+
},
|
|
3498
|
+
"org.member_budget.updated": {
|
|
3499
|
+
category: "org",
|
|
3500
|
+
severity: "notice",
|
|
3501
|
+
write: "bestEffort"
|
|
3502
|
+
},
|
|
3503
|
+
"settings.admin_settings.updated": {
|
|
3504
|
+
category: "settings",
|
|
3505
|
+
severity: "notice",
|
|
3506
|
+
write: "strict"
|
|
3507
|
+
},
|
|
3508
|
+
"settings.whats_new.updated": {
|
|
3509
|
+
category: "settings",
|
|
3510
|
+
severity: "info",
|
|
3511
|
+
write: "bestEffort"
|
|
3512
|
+
},
|
|
3513
|
+
"settings.whats_new.synced": {
|
|
3514
|
+
category: "settings",
|
|
3515
|
+
severity: "info",
|
|
3516
|
+
write: "bestEffort"
|
|
3517
|
+
},
|
|
3518
|
+
"settings.whats_new.generation_triggered": {
|
|
3519
|
+
category: "settings",
|
|
3520
|
+
severity: "info",
|
|
3521
|
+
write: "bestEffort"
|
|
3522
|
+
},
|
|
3523
|
+
"settings.security_scan.enabled": {
|
|
3524
|
+
category: "settings",
|
|
3525
|
+
severity: "notice",
|
|
3526
|
+
write: "bestEffort"
|
|
3527
|
+
},
|
|
3528
|
+
"settings.security_scan.disabled": {
|
|
3529
|
+
category: "settings",
|
|
3530
|
+
severity: "notice",
|
|
3531
|
+
write: "bestEffort"
|
|
3532
|
+
},
|
|
3533
|
+
"settings.security_scan.triggered": {
|
|
3534
|
+
category: "settings",
|
|
3535
|
+
severity: "notice",
|
|
3536
|
+
write: "bestEffort"
|
|
3537
|
+
},
|
|
3538
|
+
"security.attack_simulation.run": {
|
|
3539
|
+
category: "settings",
|
|
3540
|
+
severity: "notice",
|
|
3541
|
+
write: "bestEffort"
|
|
3542
|
+
},
|
|
3543
|
+
"oauth_client.created": {
|
|
3544
|
+
category: "settings",
|
|
3545
|
+
severity: "notice",
|
|
3546
|
+
write: "bestEffort"
|
|
3547
|
+
},
|
|
3548
|
+
"oauth_client.secret_rotated": {
|
|
3549
|
+
category: "settings",
|
|
3550
|
+
severity: "notice",
|
|
3551
|
+
write: "bestEffort"
|
|
3552
|
+
},
|
|
3553
|
+
"oauth_client.updated": {
|
|
3554
|
+
category: "settings",
|
|
3555
|
+
severity: "notice",
|
|
3556
|
+
write: "bestEffort"
|
|
3557
|
+
},
|
|
3558
|
+
"oauth_client.activated": {
|
|
3559
|
+
category: "settings",
|
|
3560
|
+
severity: "notice",
|
|
3561
|
+
write: "bestEffort"
|
|
3562
|
+
},
|
|
3563
|
+
"oauth_client.deactivated": {
|
|
3564
|
+
category: "settings",
|
|
3565
|
+
severity: "notice",
|
|
3566
|
+
write: "bestEffort"
|
|
3567
|
+
},
|
|
3568
|
+
"system_health.test_run": {
|
|
3569
|
+
category: "settings",
|
|
3570
|
+
severity: "info",
|
|
3571
|
+
write: "bestEffort"
|
|
3572
|
+
},
|
|
3573
|
+
"user.email.verified": {
|
|
3574
|
+
category: "identity",
|
|
3575
|
+
severity: "info",
|
|
3576
|
+
write: "bestEffort"
|
|
3577
|
+
},
|
|
3578
|
+
"user.email.unverified": {
|
|
3579
|
+
category: "identity",
|
|
3580
|
+
severity: "info",
|
|
3581
|
+
write: "bestEffort"
|
|
3582
|
+
},
|
|
3583
|
+
"user.email.verification_resent": {
|
|
3584
|
+
category: "identity",
|
|
3585
|
+
severity: "info",
|
|
3586
|
+
write: "bestEffort"
|
|
3587
|
+
},
|
|
3588
|
+
"user.email.change_resent": {
|
|
3589
|
+
category: "identity",
|
|
3590
|
+
severity: "info",
|
|
3591
|
+
write: "bestEffort"
|
|
3592
|
+
},
|
|
3593
|
+
"user.email.change_cancelled": {
|
|
3594
|
+
category: "identity",
|
|
3595
|
+
severity: "info",
|
|
3596
|
+
write: "bestEffort"
|
|
3597
|
+
},
|
|
3598
|
+
"user.sessions.revoked": {
|
|
3599
|
+
category: "identity",
|
|
3600
|
+
severity: "notice",
|
|
3601
|
+
write: "bestEffort"
|
|
3602
|
+
},
|
|
3603
|
+
"user.mfa.reset": {
|
|
3604
|
+
category: "identity",
|
|
3605
|
+
severity: "notice",
|
|
3606
|
+
write: "strict"
|
|
3607
|
+
},
|
|
3608
|
+
"user.mfa.denied": {
|
|
3609
|
+
category: "identity",
|
|
3610
|
+
severity: "critical",
|
|
3611
|
+
write: "bestEffort"
|
|
3612
|
+
},
|
|
3613
|
+
"audit.exported": {
|
|
3614
|
+
category: "support",
|
|
3615
|
+
severity: "info",
|
|
3616
|
+
write: "bestEffort"
|
|
3617
|
+
}
|
|
3618
|
+
};
|
|
3619
|
+
Object.keys(ADMIN_AUDIT_CATALOGUE).filter((action) => "escalatesAboveGrantThreshold" in ADMIN_AUDIT_CATALOGUE[action]);
|
|
2995
3620
|
z$1.object({
|
|
2996
3621
|
category: AdminAuditCategorySchema.optional(),
|
|
2997
3622
|
severity: AdminAuditSeveritySchema.optional(),
|
|
@@ -3000,13 +3625,14 @@ z$1.object({
|
|
|
3000
3625
|
actorUserId: z$1.string().min(1).optional(),
|
|
3001
3626
|
targetKind: AuditTargetSchema.shape.kind.optional(),
|
|
3002
3627
|
targetId: z$1.string().min(1).optional(),
|
|
3003
|
-
source:
|
|
3628
|
+
source: StoredAuditContextSourceSchema.optional(),
|
|
3004
3629
|
actorScope: AuditActorSchema.shape.scope.optional(),
|
|
3005
3630
|
from: z$1.iso.datetime().optional(),
|
|
3006
3631
|
to: z$1.iso.datetime().optional(),
|
|
3007
3632
|
requestId: z$1.string().min(1).optional(),
|
|
3008
3633
|
impersonationSessionId: z$1.string().min(1).optional()
|
|
3009
3634
|
});
|
|
3635
|
+
z$1.enum(["target", "actor"]);
|
|
3010
3636
|
let SupportedFabFileMimeTypes = /* @__PURE__ */ function(SupportedFabFileMimeTypes) {
|
|
3011
3637
|
SupportedFabFileMimeTypes["PDF"] = "application/pdf";
|
|
3012
3638
|
SupportedFabFileMimeTypes["DOCX"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
|
@@ -3052,6 +3678,26 @@ let SupportedFabFileMimeTypes = /* @__PURE__ */ function(SupportedFabFileMimeTyp
|
|
|
3052
3678
|
return SupportedFabFileMimeTypes;
|
|
3053
3679
|
}({});
|
|
3054
3680
|
new Set(Object.values(SupportedFabFileMimeTypes));
|
|
3681
|
+
/**
|
|
3682
|
+
* Known MIME types emitted by the generated-audio endpoints (TTS + sound
|
|
3683
|
+
* effects). Deliberately SEPARATE from SupportedFabFileMimeTypes: that set is
|
|
3684
|
+
* the ingest pipeline's chunk+vectorize allowlist, and audio is intentionally
|
|
3685
|
+
* NOT vectorizable and NOT attachable to a chat completion (no model accepts
|
|
3686
|
+
* audio input). Kept only for extension mapping / documentation; the runtime
|
|
3687
|
+
* guard below matches any `audio/*` so unusual provider subtypes are still
|
|
3688
|
+
* treated as audio (i.e. still excluded from every LLM path).
|
|
3689
|
+
*/
|
|
3690
|
+
let AudioMimeType = /* @__PURE__ */ function(AudioMimeType) {
|
|
3691
|
+
AudioMimeType["MP3"] = "audio/mpeg";
|
|
3692
|
+
AudioMimeType["WAV"] = "audio/wav";
|
|
3693
|
+
AudioMimeType["OPUS"] = "audio/opus";
|
|
3694
|
+
AudioMimeType["AAC"] = "audio/aac";
|
|
3695
|
+
AudioMimeType["FLAC"] = "audio/flac";
|
|
3696
|
+
AudioMimeType["PCM"] = "audio/pcm";
|
|
3697
|
+
AudioMimeType["OGG"] = "audio/ogg";
|
|
3698
|
+
AudioMimeType["WEBM"] = "audio/webm";
|
|
3699
|
+
return AudioMimeType;
|
|
3700
|
+
}({});
|
|
3055
3701
|
/** Reads back the classifier set by the tagged-error helpers above; `undefined` for untagged errors. */
|
|
3056
3702
|
function getQuestErrorCode(error) {
|
|
3057
3703
|
const code = error?.additionalInfo?.errorCode;
|
|
@@ -3188,6 +3834,49 @@ const PROMPT_META_MODEL_TYPES = [
|
|
|
3188
3834
|
"image",
|
|
3189
3835
|
"video"
|
|
3190
3836
|
];
|
|
3837
|
+
/**
|
|
3838
|
+
* Native Anthropic tool capabilities, by Claude family and version. Allow-lists rather than a
|
|
3839
|
+
* version comparison, so an older or not-yet-reviewed id (a preview, a new family) reads false.
|
|
3840
|
+
* Sources: the tool search tool and mid-conversation system messages pages of the Claude docs.
|
|
3841
|
+
*/
|
|
3842
|
+
const TOOL_SEARCH_VERSIONS = /* @__PURE__ */ new Set([
|
|
3843
|
+
"opus-4-5",
|
|
3844
|
+
"opus-4-6",
|
|
3845
|
+
"opus-4-7",
|
|
3846
|
+
"opus-4-8",
|
|
3847
|
+
"opus-5",
|
|
3848
|
+
"opus-5-5",
|
|
3849
|
+
"sonnet-4-5",
|
|
3850
|
+
"sonnet-4-6",
|
|
3851
|
+
"sonnet-5",
|
|
3852
|
+
"sonnet-5-5",
|
|
3853
|
+
"haiku-4-5",
|
|
3854
|
+
"haiku-5-5",
|
|
3855
|
+
"fable-5",
|
|
3856
|
+
"fable-5-1",
|
|
3857
|
+
"mythos-5",
|
|
3858
|
+
"mythos-5-1"
|
|
3859
|
+
]);
|
|
3860
|
+
function servedNatively(model, versions) {
|
|
3861
|
+
if (model.backend !== "anthropic" && model.backend !== "bedrock") return false;
|
|
3862
|
+
const version = claudeFamilyVersion(model.id);
|
|
3863
|
+
return version !== null && versions.has(version);
|
|
3864
|
+
}
|
|
3865
|
+
/** Whether the model accepts the tool search server tool and `defer_loading` on tool definitions. */
|
|
3866
|
+
function supportsToolSearch(model) {
|
|
3867
|
+
return servedNatively(model, TOOL_SEARCH_VERSIONS);
|
|
3868
|
+
}
|
|
3869
|
+
function servedByDirectAnthropic(model) {
|
|
3870
|
+
return model.adapterFamily ? model.adapterFamily === "anthropic-messages" : model.backend === "anthropic";
|
|
3871
|
+
}
|
|
3872
|
+
function servedByClaudeAdapter(model) {
|
|
3873
|
+
if (servedByDirectAnthropic(model)) return true;
|
|
3874
|
+
return model.adapterFamily ? model.adapterFamily === "bedrock-anthropic" : model.backend === "bedrock";
|
|
3875
|
+
}
|
|
3876
|
+
/** supportsToolSearch, narrowed to models whose `/api/ai/v1/completions` adapter actually forwards it. */
|
|
3877
|
+
function completionsSupportsToolSearch(model) {
|
|
3878
|
+
return servedByClaudeAdapter(model) && supportsToolSearch(model);
|
|
3879
|
+
}
|
|
3191
3880
|
const DEFAULT_PRICE_MARGIN = 1.2;
|
|
3192
3881
|
const DEFAULT_USD_TO_CREDITS_RATE = 6e-4;
|
|
3193
3882
|
/**
|
|
@@ -3803,7 +4492,7 @@ const CompletionCustomToolSchema = z$1.object({
|
|
|
3803
4492
|
required: z$1.array(z$1.string()).optional()
|
|
3804
4493
|
}).passthrough(),
|
|
3805
4494
|
strict: z$1.boolean().optional(),
|
|
3806
|
-
defer_loading: z$1.boolean().optional().describe("Keep this definition out of the model context until the tool search server tool (or a `tool_reference`) loads it. Honoured only on models
|
|
4495
|
+
defer_loading: z$1.boolean().optional().describe("Keep this definition out of the model context until the tool search server tool (or a `tool_reference`) loads it. Honoured only on Claude models (direct Anthropic or Bedrock) whose `supports_tool_search` is true; on every other model it is ignored and the tool is sent as usual. At least one tool, or a `serverTool` entry, must stay non-deferred (`errorCode: \"all_tools_deferred\"`)."),
|
|
3807
4496
|
cache_control: z$1.unknown().optional().describe("Accepted for validation only and not forwarded. Rejected on a deferred tool (`errorCode: \"deferred_tool_cache_control\"`).")
|
|
3808
4497
|
}),
|
|
3809
4498
|
_isMcpTool: z$1.boolean().optional()
|
|
@@ -3816,7 +4505,7 @@ const ToolSearchServerToolSchema = z$1.discriminatedUnion("type", [z$1.object({
|
|
|
3816
4505
|
type: z$1.literal("tool_search_tool_bm25_20251119"),
|
|
3817
4506
|
name: z$1.literal("tool_search_tool_bm25")
|
|
3818
4507
|
})]);
|
|
3819
|
-
const CompletionServerToolSchema = z$1.object({ serverTool: ToolSearchServerToolSchema.describe("A provider-run tool, sent to the provider as `{ type, name }`. Only the Anthropic tool search tools exist today, and only on models
|
|
4508
|
+
const CompletionServerToolSchema = z$1.object({ serverTool: ToolSearchServerToolSchema.describe("A provider-run tool, sent to the provider as `{ type, name }`. Only the Anthropic tool search tools exist today, and only on Claude models (direct Anthropic or Bedrock) whose `supports_tool_search` is true; any other model is refused with `errorCode: \"tool_search_unsupported\"` rather than run without it.") });
|
|
3820
4509
|
/** One `tools[]` entry: a caller-defined tool, or a provider-run server tool. */
|
|
3821
4510
|
const CompletionToolSchema = z$1.union([CompletionCustomToolSchema, CompletionServerToolSchema]);
|
|
3822
4511
|
/**
|
|
@@ -3885,7 +4574,7 @@ const CompletionMessageSchema = z$1.object({
|
|
|
3885
4574
|
*/
|
|
3886
4575
|
const CompletionRequestSchema = z$1.object({
|
|
3887
4576
|
model: z$1.string().max(256),
|
|
3888
|
-
messages: z$1.array(CompletionMessageSchema),
|
|
4577
|
+
messages: z$1.array(CompletionMessageSchema).min(1),
|
|
3889
4578
|
response_format: ResponseFormatSchema.optional(),
|
|
3890
4579
|
stream: z$1.boolean().optional(),
|
|
3891
4580
|
tools: z$1.array(CompletionToolSchema).optional(),
|
|
@@ -3946,6 +4635,7 @@ const CompletionContentEventSchema = z$1.object({
|
|
|
3946
4635
|
*/
|
|
3947
4636
|
const COMPLETION_SSE_ERROR_CODES = [
|
|
3948
4637
|
...QUEST_ERROR_CODES,
|
|
4638
|
+
"invalid_request",
|
|
3949
4639
|
"provider_error",
|
|
3950
4640
|
"provider_rejected",
|
|
3951
4641
|
"content_blocked"
|
|
@@ -3956,9 +4646,9 @@ const COMPLETION_SSE_ERROR_CODES = [
|
|
|
3956
4646
|
* real status instead; see completions.contract.ts.
|
|
3957
4647
|
*
|
|
3958
4648
|
* `code` is the machine-readable classifier: a billing code when settlement runs out mid-generation,
|
|
3959
|
-
* `
|
|
3960
|
-
*
|
|
3961
|
-
* `message`.
|
|
4649
|
+
* `invalid_request` when the provider rejects caller-controlled input, `provider_rejected` /
|
|
4650
|
+
* `provider_error` when the model provider fails, `content_blocked` when the model's safety classifier
|
|
4651
|
+
* declined the request. Optional; callers must never match on the prose `message`.
|
|
3962
4652
|
*
|
|
3963
4653
|
* The field is `code` rather than the conventions' `errorCode` because this frame shipped that way
|
|
3964
4654
|
* and is a published wire shape.
|
|
@@ -5083,9 +5773,9 @@ const RetrievalSummarySchema = z$1.object({
|
|
|
5083
5773
|
* `citables` and `retrieval` - this field needs no merge case in applyQuestStatusChanges: a
|
|
5084
5774
|
* later tool-arm write that omits it is preserved by the one-level spread.
|
|
5085
5775
|
*
|
|
5086
|
-
* `reasons` is
|
|
5087
|
-
*
|
|
5088
|
-
*
|
|
5776
|
+
* `reasons` is reader-facing prose with no document ids or internal limits, shown behind a
|
|
5777
|
+
* disclosure in the chat notice. The diagnostic version (ids, caps, counts) lives only in the
|
|
5778
|
+
* `warnings` entry. A supersession collapse alone does not produce this field at all.
|
|
5089
5779
|
*/
|
|
5090
5780
|
const RetrievalCoverageSchema = z$1.object({
|
|
5091
5781
|
/** Always true - see the presence contract above. */
|
|
@@ -5415,10 +6105,14 @@ const StorageLimitErrorSchema = ApiErrorSchema.extend(StorageLimitErrorInfoSchem
|
|
|
5415
6105
|
/** 503 when this deployment has no usable key for a provider the request needs (data-lake search, voice). */
|
|
5416
6106
|
const ProviderNotConfiguredErrorSchema = ApiErrorSchema.extend({ errorCode: z$1.literal("provider_not_configured").optional() });
|
|
5417
6107
|
/**
|
|
5418
|
-
* 400 for a `model` the caller cannot use, or a refused tool search
|
|
5419
|
-
* other 400s (e.g. malformed JSON).
|
|
6108
|
+
* 400 for provider-rejected caller input, a `model` the caller cannot use, or a refused tool search
|
|
6109
|
+
* request; `errorCode` is absent on the other 400s (e.g. malformed JSON).
|
|
5420
6110
|
*/
|
|
5421
|
-
const CompletionsBadRequestErrorSchema = ApiErrorSchema.extend({ errorCode: z$1.enum([
|
|
6111
|
+
const CompletionsBadRequestErrorSchema = ApiErrorSchema.extend({ errorCode: z$1.enum([
|
|
6112
|
+
"invalid_request",
|
|
6113
|
+
UNKNOWN_MODEL_ERROR_CODE,
|
|
6114
|
+
...COMPLETION_TOOL_ERROR_CODES
|
|
6115
|
+
]).optional() });
|
|
5422
6116
|
/**
|
|
5423
6117
|
* Error envelope for the 403 apiKeyAuth (apps/client/server/middlewares/apiKeyAuth.ts)
|
|
5424
6118
|
* throws when an API key lacks a route's scopes. It names what the ROUTE requires,
|
|
@@ -5431,8 +6125,9 @@ const ScopeForbiddenErrorSchema = ApiErrorSchema.extend({
|
|
|
5431
6125
|
also_required_scopes: z$1.array(z$1.string()).optional().describe("API key scopes this route also requires. Every one must be held, on top of `required_scopes`.")
|
|
5432
6126
|
});
|
|
5433
6127
|
/**
|
|
5434
|
-
* 403 on the v1 media create routes: the scope refusal above, or an
|
|
5435
|
-
* another billing organization
|
|
6128
|
+
* 403 on the v1 media create routes and POST /api/v1/agent-executions: the scope refusal above, or an
|
|
6129
|
+
* organization-billed API key sent with another billing organization
|
|
6130
|
+
* (apps/client/server/billing/resolveMediaBillingOrgId.ts).
|
|
5436
6131
|
*/
|
|
5437
6132
|
const BillingOrganizationForbiddenErrorSchema = ScopeForbiddenErrorSchema.extend({ errorCode: z$1.literal(BILLING_ORGANIZATION_MISMATCH_ERROR_CODE).optional() });
|
|
5438
6133
|
const supportedVoiceGenerationVendor = z.enum(["openai", "elevenlabs"]);
|
|
@@ -5445,10 +6140,11 @@ const voiceOutputFormatSchema = z.enum([
|
|
|
5445
6140
|
"flac",
|
|
5446
6141
|
"pcm"
|
|
5447
6142
|
]);
|
|
5448
|
-
const
|
|
6143
|
+
const TTS_MAX_INPUT_CHARS = {
|
|
5449
6144
|
openai: 4096,
|
|
5450
6145
|
elevenlabs: 1e4
|
|
5451
|
-
}
|
|
6146
|
+
};
|
|
6147
|
+
const TTS_ABSOLUTE_MAX_INPUT_CHARS = Math.max(...Object.values(TTS_MAX_INPUT_CHARS));
|
|
5452
6148
|
const ttsLanguageCodeSchema = z.string().regex(/^[a-z]{2}$/, "languageCode must be a lowercase ISO 639-1 code, e.g. \"en\" or \"ja\"");
|
|
5453
6149
|
const ttsRequestSchema = z.object({
|
|
5454
6150
|
text: z.string().min(1).max(TTS_ABSOLUTE_MAX_INPUT_CHARS),
|
|
@@ -5540,12 +6236,30 @@ const ttsResponseTooLargeSchema = generatedAudioTooLargeSchema.extend({
|
|
|
5540
6236
|
fabFileId: z.string().optional(),
|
|
5541
6237
|
fileUrl: z.string().optional()
|
|
5542
6238
|
});
|
|
6239
|
+
/**
|
|
6240
|
+
* The model each vendor's service synthesizes and bills with when the caller
|
|
6241
|
+
* names none. Read by OpenAIVoiceService / ElevenLabsVoiceService in
|
|
6242
|
+
* @bike4mind/utils, so a pre-flight estimate prices the model the charge will use
|
|
6243
|
+
* when the requested vendor serves the call. The TTS route reserves the highest
|
|
6244
|
+
* estimate across its candidate vendors, using these defaults for alternates,
|
|
6245
|
+
* then settles the actual vendor's cost and refunds the difference.
|
|
6246
|
+
*/
|
|
6247
|
+
const TTS_DEFAULT_MODEL = {
|
|
6248
|
+
openai: "tts-1",
|
|
6249
|
+
elevenlabs: "eleven_multilingual_v2"
|
|
6250
|
+
};
|
|
5543
6251
|
const GENERATION_OUTPUT_AVAILABILITIES = [
|
|
5544
6252
|
"ready",
|
|
5545
6253
|
"pending_scan",
|
|
5546
6254
|
"unavailable"
|
|
5547
6255
|
];
|
|
5548
6256
|
const VIDEO_MODES = ["text_to_video", "image_to_video"];
|
|
6257
|
+
const VIDEO_INPUT_ROLES = [
|
|
6258
|
+
"first_frame",
|
|
6259
|
+
"last_frame",
|
|
6260
|
+
"reference",
|
|
6261
|
+
"style"
|
|
6262
|
+
];
|
|
5549
6263
|
const ASPECT_RATIOS = [
|
|
5550
6264
|
"16:9",
|
|
5551
6265
|
"9:16",
|
|
@@ -5569,6 +6283,13 @@ const VideoModelIdSchema = z$1.enum([
|
|
|
5569
6283
|
"grok-imagine-video-1.5",
|
|
5570
6284
|
"veo-3.1-fast-generate-preview"
|
|
5571
6285
|
]);
|
|
6286
|
+
const VideoInputSchema = z$1.union([z$1.strictObject({
|
|
6287
|
+
role: z$1.enum(VIDEO_INPUT_ROLES),
|
|
6288
|
+
fileId: z$1.string().min(1)
|
|
6289
|
+
}), z$1.strictObject({
|
|
6290
|
+
role: z$1.enum(VIDEO_INPUT_ROLES),
|
|
6291
|
+
generatedImageKey: z$1.string().min(1)
|
|
6292
|
+
})]);
|
|
5572
6293
|
z$1.object({
|
|
5573
6294
|
model: VideoModelIdSchema,
|
|
5574
6295
|
mode: z$1.enum(VIDEO_MODES),
|
|
@@ -5576,6 +6297,7 @@ z$1.object({
|
|
|
5576
6297
|
durationSeconds: z$1.number().positive(),
|
|
5577
6298
|
aspectRatio: z$1.enum(ASPECT_RATIOS),
|
|
5578
6299
|
resolution: z$1.enum(RESOLUTION_TIERS),
|
|
6300
|
+
inputs: z$1.array(VideoInputSchema).max(8).optional(),
|
|
5579
6301
|
inputImageFileId: z$1.string().min(1).optional(),
|
|
5580
6302
|
inputGeneratedImageKey: z$1.string().min(1).optional(),
|
|
5581
6303
|
audio: z$1.boolean().optional()
|
|
@@ -5587,6 +6309,7 @@ const VIDEO_VALIDATION_ERROR_CODES = [
|
|
|
5587
6309
|
"unsupported_mode",
|
|
5588
6310
|
"missing_input_image",
|
|
5589
6311
|
"unexpected_input_image",
|
|
6312
|
+
"unsupported_input_role",
|
|
5590
6313
|
"unsupported_audio_option"
|
|
5591
6314
|
];
|
|
5592
6315
|
const MAX_MUSIC_LYRICS_CHARS = 1e4;
|
|
@@ -5808,6 +6531,7 @@ z$2.object({
|
|
|
5808
6531
|
]),
|
|
5809
6532
|
slackSettings: redactedSubdocument([
|
|
5810
6533
|
"slackUserId",
|
|
6534
|
+
"slackTeamId",
|
|
5811
6535
|
"defaultNotebookId",
|
|
5812
6536
|
"autoCreateNotebook",
|
|
5813
6537
|
"notebookNamePrefix",
|
|
@@ -5828,7 +6552,10 @@ z$2.object({
|
|
|
5828
6552
|
"connectedAt"
|
|
5829
6553
|
])
|
|
5830
6554
|
}).extend({
|
|
5831
|
-
securityQuestions:
|
|
6555
|
+
securityQuestions: z$2.array(z$2.object({
|
|
6556
|
+
question: z$2.string(),
|
|
6557
|
+
answer: z$2.literal("")
|
|
6558
|
+
})).nullable().optional(),
|
|
5832
6559
|
userNotes: passthroughField
|
|
5833
6560
|
});
|
|
5834
6561
|
/**
|
|
@@ -5848,7 +6575,6 @@ const INTEGRATION_IDS = [
|
|
|
5848
6575
|
"mcp-cli",
|
|
5849
6576
|
"atlassian",
|
|
5850
6577
|
"notion",
|
|
5851
|
-
"google-calendar",
|
|
5852
6578
|
"slack",
|
|
5853
6579
|
"email",
|
|
5854
6580
|
"linkedin",
|
|
@@ -6021,20 +6747,6 @@ const INTEGRATION_CATALOG = {
|
|
|
6021
6747
|
mcpServer: "notion"
|
|
6022
6748
|
}]
|
|
6023
6749
|
},
|
|
6024
|
-
"google-calendar": {
|
|
6025
|
-
name: "Google Calendar",
|
|
6026
|
-
description: "Book briefing calls into open slots on a shared Bike4Mind calendar, not your own.",
|
|
6027
|
-
category: "productivity",
|
|
6028
|
-
logo: "google-calendar",
|
|
6029
|
-
stage: "beta",
|
|
6030
|
-
flag: "enableGoogleCalendar",
|
|
6031
|
-
capabilities: [{
|
|
6032
|
-
id: "calendar-booking",
|
|
6033
|
-
label: "Book briefings on a shared calendar",
|
|
6034
|
-
kind: "notifications",
|
|
6035
|
-
stage: "beta"
|
|
6036
|
-
}]
|
|
6037
|
-
},
|
|
6038
6750
|
slack: {
|
|
6039
6751
|
name: "Slack",
|
|
6040
6752
|
description: "Chat with Bike4Mind in Slack and send threads and files to a data lake.",
|
|
@@ -6609,7 +7321,7 @@ let OllamaEmbeddingModel = /* @__PURE__ */ function(OllamaEmbeddingModel) {
|
|
|
6609
7321
|
*
|
|
6610
7322
|
* Deliberately answers from the ENVIRONMENT only, and deliberately does NOT try to answer "can this
|
|
6611
7323
|
* deployment actually reach that model". It cannot: on a hosted stage an SST secret arrives as a
|
|
6612
|
-
* linked Resource, never as process.env (see
|
|
7324
|
+
* linked Resource, never as process.env (see packages/server-utils/src/modelDiscovery/adapters.ts), so an
|
|
6613
7325
|
* absent OPENAI_API_KEY here means "unknown", not "no key" - it is absent on production too. This
|
|
6614
7326
|
* function is also bundled into the browser via settingsMap, where every env read is undefined, so
|
|
6615
7327
|
* any answer it gives must be one that is safe as a stage-neutral constant.
|
|
@@ -6718,6 +7430,7 @@ z$1.object({
|
|
|
6718
7430
|
status: ReleaseNoteStatusSchema,
|
|
6719
7431
|
publishAt: z$1.coerce.date(),
|
|
6720
7432
|
editedAt: z$1.coerce.date().nullable(),
|
|
7433
|
+
video: ModalVideoShapeSchema.nullable().optional(),
|
|
6721
7434
|
schemaVersion: z$1.number().int()
|
|
6722
7435
|
});
|
|
6723
7436
|
const ReleaseNotesJobPrSchema = z$1.object({
|
|
@@ -6745,6 +7458,22 @@ const ReleaseNotesConfigSchema = z$1.object({
|
|
|
6745
7458
|
slackTeamId: z$1.string().optional(),
|
|
6746
7459
|
slackChannelId: z$1.string().optional()
|
|
6747
7460
|
});
|
|
7461
|
+
/** A release note video on the public wire: ModalVideo with snake_case keys. */
|
|
7462
|
+
const PublicReleaseNoteVideoSchema = z$1.object({
|
|
7463
|
+
landscape_url: z$1.string().nullable().optional(),
|
|
7464
|
+
landscape_poster_url: z$1.string().nullable().optional(),
|
|
7465
|
+
portrait_url: z$1.string().nullable().optional(),
|
|
7466
|
+
portrait_poster_url: z$1.string().nullable().optional()
|
|
7467
|
+
});
|
|
7468
|
+
const ReleaseNoteMediaParamsSchema = z$1.object({
|
|
7469
|
+
id: z$1.string().min(1),
|
|
7470
|
+
asset: z$1.enum(Object.keys({
|
|
7471
|
+
landscape: "landscapeUrl",
|
|
7472
|
+
"landscape-poster": "landscapePosterUrl",
|
|
7473
|
+
portrait: "portraitUrl",
|
|
7474
|
+
"portrait-poster": "portraitPosterUrl"
|
|
7475
|
+
}))
|
|
7476
|
+
});
|
|
6748
7477
|
/**
|
|
6749
7478
|
* A release note as GET /api/v1/whats-new serves it. An allowlist: provenance (sourcePrs, deployedSha),
|
|
6750
7479
|
* workflow state (status, editedAt) and storage fields never reach the public wire.
|
|
@@ -6759,7 +7488,8 @@ const PublicReleaseNoteSchema = z$1.object({
|
|
|
6759
7488
|
category: ReleaseNoteCategorySchema,
|
|
6760
7489
|
text: z$1.string(),
|
|
6761
7490
|
importance: z$1.number().int().min(1).max(3)
|
|
6762
|
-
}))
|
|
7491
|
+
})),
|
|
7492
|
+
video: PublicReleaseNoteVideoSchema.nullable().optional()
|
|
6763
7493
|
});
|
|
6764
7494
|
/**
|
|
6765
7495
|
* The measured per-space floors, rendered for an admin-facing description (e.g. "75 for
|
|
@@ -7054,6 +7784,7 @@ z$1.enum([
|
|
|
7054
7784
|
"serverStatus",
|
|
7055
7785
|
"defaultSeats",
|
|
7056
7786
|
"CSMandCTAFlag",
|
|
7787
|
+
"showDesktopAppPromo",
|
|
7057
7788
|
"SystemFiles",
|
|
7058
7789
|
"OpenWeatherKey",
|
|
7059
7790
|
"SerperKey",
|
|
@@ -7069,6 +7800,9 @@ z$1.enum([
|
|
|
7069
7800
|
"MaxActiveDungeons",
|
|
7070
7801
|
"DungeonSpawnIntervalHeartbeats",
|
|
7071
7802
|
"DungeonTTLMinutes",
|
|
7803
|
+
"EnableStudioCreateV2",
|
|
7804
|
+
"EnableStudioImage",
|
|
7805
|
+
"EnableStudioProductions",
|
|
7072
7806
|
"VectorThreshold",
|
|
7073
7807
|
"bflApiKey",
|
|
7074
7808
|
"EnableMCPServer",
|
|
@@ -7102,10 +7836,6 @@ z$1.enum([
|
|
|
7102
7836
|
"teamPlanCreditsPerSeat",
|
|
7103
7837
|
"lowCreditsThreshold",
|
|
7104
7838
|
"syntheticUserEmailDomains",
|
|
7105
|
-
"enableGoogleCalendar",
|
|
7106
|
-
"googleCalendarServiceAccountEmail",
|
|
7107
|
-
"googleCalendarServiceAccountSecret",
|
|
7108
|
-
"googleCalendarOrganizerEmail",
|
|
7109
7839
|
"EnableWeatherService",
|
|
7110
7840
|
"WeatherUnits",
|
|
7111
7841
|
"defaultEmbeddingModel",
|
|
@@ -7151,6 +7881,9 @@ z$1.enum([
|
|
|
7151
7881
|
"SlackFeedbackWebhookUrl",
|
|
7152
7882
|
"SlackNonProdFeedbackWebhookUrl",
|
|
7153
7883
|
"SlackEmailAuditWebhookUrl",
|
|
7884
|
+
"SlackSecurityAlertsWebhookUrl",
|
|
7885
|
+
"AdminAuditCriticalGrantCredits",
|
|
7886
|
+
"AdminAuditDailyGrantCredits",
|
|
7154
7887
|
"slackSigningSecret",
|
|
7155
7888
|
"slackBotToken",
|
|
7156
7889
|
"enforceMFA",
|
|
@@ -7395,15 +8128,17 @@ function makeNumberSetting(config) {
|
|
|
7395
8128
|
schema: z$1.preprocess((val) => isBlankSettingValue(val) ? void 0 : val, numberSchema.prefault(config.defaultValue ?? 0))
|
|
7396
8129
|
};
|
|
7397
8130
|
}
|
|
7398
|
-
function makeBooleanSetting(config) {
|
|
8131
|
+
function makeBooleanSetting({ acceptNumeric = false, ...config }) {
|
|
7399
8132
|
return {
|
|
7400
8133
|
...config,
|
|
7401
8134
|
type: "boolean",
|
|
7402
8135
|
schema: z$1.preprocess((val) => {
|
|
7403
8136
|
if (typeof val === "string") {
|
|
7404
|
-
if (val.toLowerCase() === "true") return true;
|
|
7405
|
-
if (val.toLowerCase() === "false") return false;
|
|
8137
|
+
if (val.toLowerCase() === "true" || acceptNumeric && val === "1") return true;
|
|
8138
|
+
if (val.toLowerCase() === "false" || acceptNumeric && val === "0") return false;
|
|
7406
8139
|
}
|
|
8140
|
+
if (acceptNumeric && val === 1) return true;
|
|
8141
|
+
if (acceptNumeric && val === 0) return false;
|
|
7407
8142
|
return val;
|
|
7408
8143
|
}, z$1.boolean()).prefault(config.defaultValue ?? false)
|
|
7409
8144
|
};
|
|
@@ -8345,30 +9080,6 @@ const API_SERVICE_GROUPS = {
|
|
|
8345
9080
|
}
|
|
8346
9081
|
]
|
|
8347
9082
|
},
|
|
8348
|
-
CALENDAR: {
|
|
8349
|
-
id: "calendarAPIService",
|
|
8350
|
-
name: "Google Calendar",
|
|
8351
|
-
description: "Google Calendar integration settings",
|
|
8352
|
-
icon: "CalendarMonth",
|
|
8353
|
-
settings: [
|
|
8354
|
-
{
|
|
8355
|
-
key: "enableGoogleCalendar",
|
|
8356
|
-
order: 1
|
|
8357
|
-
},
|
|
8358
|
-
{
|
|
8359
|
-
key: "googleCalendarServiceAccountEmail",
|
|
8360
|
-
order: 2
|
|
8361
|
-
},
|
|
8362
|
-
{
|
|
8363
|
-
key: "googleCalendarServiceAccountSecret",
|
|
8364
|
-
order: 3
|
|
8365
|
-
},
|
|
8366
|
-
{
|
|
8367
|
-
key: "googleCalendarOrganizerEmail",
|
|
8368
|
-
order: 4
|
|
8369
|
-
}
|
|
8370
|
-
]
|
|
8371
|
-
},
|
|
8372
9083
|
FEEDBACK: {
|
|
8373
9084
|
id: "feedbackService",
|
|
8374
9085
|
name: "Feedback System",
|
|
@@ -8690,6 +9401,18 @@ const API_SERVICE_GROUPS = {
|
|
|
8690
9401
|
{
|
|
8691
9402
|
key: "DungeonTTLMinutes",
|
|
8692
9403
|
order: 293
|
|
9404
|
+
},
|
|
9405
|
+
{
|
|
9406
|
+
key: "EnableStudioCreateV2",
|
|
9407
|
+
order: 300
|
|
9408
|
+
},
|
|
9409
|
+
{
|
|
9410
|
+
key: "EnableStudioImage",
|
|
9411
|
+
order: 301
|
|
9412
|
+
},
|
|
9413
|
+
{
|
|
9414
|
+
key: "EnableStudioProductions",
|
|
9415
|
+
order: 302
|
|
8693
9416
|
}
|
|
8694
9417
|
]
|
|
8695
9418
|
},
|
|
@@ -8728,10 +9451,6 @@ const API_SERVICE_GROUPS = {
|
|
|
8728
9451
|
{
|
|
8729
9452
|
key: "defaultTags",
|
|
8730
9453
|
order: 5
|
|
8731
|
-
},
|
|
8732
|
-
{
|
|
8733
|
-
key: "enforceCredits",
|
|
8734
|
-
order: 6
|
|
8735
9454
|
}
|
|
8736
9455
|
]
|
|
8737
9456
|
},
|
|
@@ -8742,36 +9461,16 @@ const API_SERVICE_GROUPS = {
|
|
|
8742
9461
|
icon: "Payments",
|
|
8743
9462
|
settings: [
|
|
8744
9463
|
{
|
|
8745
|
-
key: "
|
|
9464
|
+
key: "billOperationalUsage",
|
|
8746
9465
|
order: 1
|
|
8747
9466
|
},
|
|
8748
9467
|
{
|
|
8749
|
-
key: "
|
|
9468
|
+
key: "blockDisposableEmails",
|
|
8750
9469
|
order: 2
|
|
8751
9470
|
},
|
|
8752
9471
|
{
|
|
8753
|
-
key: "
|
|
9472
|
+
key: "syntheticUserEmailDomains",
|
|
8754
9473
|
order: 3
|
|
8755
|
-
},
|
|
8756
|
-
{
|
|
8757
|
-
key: "enableTeamPlan",
|
|
8758
|
-
order: 4
|
|
8759
|
-
},
|
|
8760
|
-
{
|
|
8761
|
-
key: "teamPlanMinSeats",
|
|
8762
|
-
order: 5
|
|
8763
|
-
},
|
|
8764
|
-
{
|
|
8765
|
-
key: "teamPlanMaxSeats",
|
|
8766
|
-
order: 6
|
|
8767
|
-
},
|
|
8768
|
-
{
|
|
8769
|
-
key: "teamPlanCreditsPerSeat",
|
|
8770
|
-
order: 7
|
|
8771
|
-
},
|
|
8772
|
-
{
|
|
8773
|
-
key: "lowCreditsThreshold",
|
|
8774
|
-
order: 8
|
|
8775
9474
|
}
|
|
8776
9475
|
]
|
|
8777
9476
|
},
|
|
@@ -8849,6 +9548,10 @@ const API_SERVICE_GROUPS = {
|
|
|
8849
9548
|
{
|
|
8850
9549
|
key: "RedditLink",
|
|
8851
9550
|
order: 8
|
|
9551
|
+
},
|
|
9552
|
+
{
|
|
9553
|
+
key: "showDesktopAppPromo",
|
|
9554
|
+
order: 9
|
|
8852
9555
|
}
|
|
8853
9556
|
]
|
|
8854
9557
|
},
|
|
@@ -9544,7 +10247,7 @@ const settingsMap = {
|
|
|
9544
10247
|
key: "SkillMarketUrlAllowlist",
|
|
9545
10248
|
name: "Skill Market URL Allowlist",
|
|
9546
10249
|
defaultValue: "",
|
|
9547
|
-
description: "Comma-separated host names a Skill Market skill may reference without a finding (subdomains included). Any other URL holds a
|
|
10250
|
+
description: "Comma-separated host names a Skill Market skill may reference without a finding (subdomains included). Any other URL holds a listing for review at every visibility.",
|
|
9548
10251
|
category: "AI Moderation"
|
|
9549
10252
|
}),
|
|
9550
10253
|
SkillMarketClassifierMinConfidence: makeNumberSetting({
|
|
@@ -9679,9 +10382,7 @@ const settingsMap = {
|
|
|
9679
10382
|
name: "Price Per Credit",
|
|
9680
10383
|
defaultValue: 50,
|
|
9681
10384
|
description: `The price in USD of one credit bought pay-as-you-go. Cannot be set below ${formatUsdPerCredit(MIN_PRICE_PER_CREDIT_USD)}, the per-credit sale price including markup.`,
|
|
9682
|
-
category: "Users"
|
|
9683
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
9684
|
-
order: 1
|
|
10385
|
+
category: "Users"
|
|
9685
10386
|
}),
|
|
9686
10387
|
apiRateLimitFreePerMin: makeNumberSetting({
|
|
9687
10388
|
key: "apiRateLimitFreePerMin",
|
|
@@ -9887,6 +10588,32 @@ const settingsMap = {
|
|
|
9887
10588
|
order: 8,
|
|
9888
10589
|
isSensitive: true
|
|
9889
10590
|
}),
|
|
10591
|
+
SlackSecurityAlertsWebhookUrl: makeStringSetting({
|
|
10592
|
+
key: "SlackSecurityAlertsWebhookUrl",
|
|
10593
|
+
name: "Security Alerts Channel Webhook URL",
|
|
10594
|
+
defaultValue: "",
|
|
10595
|
+
description: "Incoming-webhook URL for the security Slack channel that receives critical Admin Audit Log entries and credit-grant bursts. Leave empty to turn alerts off; the Audit Log page then shows a banner. It never falls back to the default webhook.",
|
|
10596
|
+
category: "SecOps",
|
|
10597
|
+
isSensitive: true
|
|
10598
|
+
}),
|
|
10599
|
+
AdminAuditCriticalGrantCredits: makeNumberSetting({
|
|
10600
|
+
key: "AdminAuditCriticalGrantCredits",
|
|
10601
|
+
name: "Critical Single Credit Grant",
|
|
10602
|
+
defaultValue: ADMIN_AUDIT_DEFAULT_CRITICAL_GRANT_CREDITS,
|
|
10603
|
+
min: 1,
|
|
10604
|
+
int: true,
|
|
10605
|
+
description: "An admin credit grant above this many credits is recorded as critical in the Admin Audit Log and alerts the security channel.",
|
|
10606
|
+
category: "SecOps"
|
|
10607
|
+
}),
|
|
10608
|
+
AdminAuditDailyGrantCredits: makeNumberSetting({
|
|
10609
|
+
key: "AdminAuditDailyGrantCredits",
|
|
10610
|
+
name: "Critical Daily Credit Grants per Admin",
|
|
10611
|
+
defaultValue: ADMIN_AUDIT_DEFAULT_DAILY_GRANT_CREDITS,
|
|
10612
|
+
min: 1,
|
|
10613
|
+
int: true,
|
|
10614
|
+
description: "A grant that takes one admin past this many credits granted in the last 24 hours is recorded as critical in the Admin Audit Log and alerts the security channel.",
|
|
10615
|
+
category: "SecOps"
|
|
10616
|
+
}),
|
|
9890
10617
|
liveFeedbackEmail: makeStringSetting({
|
|
9891
10618
|
key: "liveFeedbackEmail",
|
|
9892
10619
|
name: "Live Feedback Email",
|
|
@@ -10025,51 +10752,12 @@ const settingsMap = {
|
|
|
10025
10752
|
description: "The default number of seats for new organizations.",
|
|
10026
10753
|
category: "Users"
|
|
10027
10754
|
}),
|
|
10028
|
-
enableGoogleCalendar: makeBooleanSetting({
|
|
10029
|
-
key: "enableGoogleCalendar",
|
|
10030
|
-
name: "Enable Google Calendar Integration",
|
|
10031
|
-
defaultValue: false,
|
|
10032
|
-
description: "Whether to enable scheduling of briefing/advisory using google calendar",
|
|
10033
|
-
category: "Calendar",
|
|
10034
|
-
group: API_SERVICE_GROUPS.CALENDAR.id,
|
|
10035
|
-
order: 1,
|
|
10036
|
-
userReadable: true
|
|
10037
|
-
}),
|
|
10038
|
-
googleCalendarServiceAccountEmail: makeStringSetting({
|
|
10039
|
-
key: "googleCalendarServiceAccountEmail",
|
|
10040
|
-
name: "Service Account Email",
|
|
10041
|
-
defaultValue: "",
|
|
10042
|
-
description: "The service account email address that has access to google calendar API.",
|
|
10043
|
-
category: "Calendar",
|
|
10044
|
-
group: API_SERVICE_GROUPS.CALENDAR.id,
|
|
10045
|
-
order: 2
|
|
10046
|
-
}),
|
|
10047
|
-
googleCalendarServiceAccountSecret: makeStringSetting({
|
|
10048
|
-
key: "googleCalendarServiceAccountSecret",
|
|
10049
|
-
name: "Service Account Secret",
|
|
10050
|
-
defaultValue: "",
|
|
10051
|
-
description: "The base64 encoded service account secret that is associated with the service account email.",
|
|
10052
|
-
category: "Calendar",
|
|
10053
|
-
group: API_SERVICE_GROUPS.CALENDAR.id,
|
|
10054
|
-
order: 3,
|
|
10055
|
-
isSensitive: true
|
|
10056
|
-
}),
|
|
10057
|
-
googleCalendarOrganizerEmail: makeStringSetting({
|
|
10058
|
-
key: "googleCalendarOrganizerEmail",
|
|
10059
|
-
name: "Organizer Email",
|
|
10060
|
-
defaultValue: "",
|
|
10061
|
-
description: "The organizer email for creating events.",
|
|
10062
|
-
category: "Calendar",
|
|
10063
|
-
group: API_SERVICE_GROUPS.CALENDAR.id,
|
|
10064
|
-
order: 4
|
|
10065
|
-
}),
|
|
10066
10755
|
enforceCredits: makeBooleanSetting({
|
|
10067
10756
|
key: "enforceCredits",
|
|
10068
10757
|
userReadable: true,
|
|
10069
10758
|
name: "Enforce Credits",
|
|
10070
10759
|
defaultValue: process.env.B4M_SELF_HOST === "true" ? false : true,
|
|
10071
10760
|
description: "Whether to enforce credits for users",
|
|
10072
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
10073
10761
|
category: "Users"
|
|
10074
10762
|
}),
|
|
10075
10763
|
billOperationalUsage: makeBooleanSetting({
|
|
@@ -10081,12 +10769,12 @@ const settingsMap = {
|
|
|
10081
10769
|
category: "Users"
|
|
10082
10770
|
}),
|
|
10083
10771
|
enableTeamPlan: makeBooleanSetting({
|
|
10772
|
+
acceptNumeric: true,
|
|
10084
10773
|
key: "enableTeamPlan",
|
|
10085
10774
|
userReadable: true,
|
|
10086
10775
|
name: "Enable Team Plan",
|
|
10087
10776
|
defaultValue: false,
|
|
10088
10777
|
description: "Whether to enable team plans",
|
|
10089
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
10090
10778
|
category: "Users"
|
|
10091
10779
|
}),
|
|
10092
10780
|
allowOpenRegistration: makeBooleanSetting({
|
|
@@ -10094,7 +10782,6 @@ const settingsMap = {
|
|
|
10094
10782
|
name: "Allow Open Registration",
|
|
10095
10783
|
defaultValue: false,
|
|
10096
10784
|
description: "Master switch for self-serve signup. When OFF (default), a valid invite code is required to register. When ON, users may register without an invite code; the Default Free Credits grant is then applied after they verify their email (anti-spam — see Default Free Credits). Safe to enable: the pre-request credit reservation caps every free user at the credits they are granted.",
|
|
10097
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
10098
10785
|
category: "Users"
|
|
10099
10786
|
}),
|
|
10100
10787
|
blockDisposableEmails: makeBooleanSetting({
|
|
@@ -10111,7 +10798,6 @@ const settingsMap = {
|
|
|
10111
10798
|
name: "Default Free Credits",
|
|
10112
10799
|
defaultValue: 0,
|
|
10113
10800
|
description: "Base credits granted after email verification to a user who registers WITHOUT an invite code, including eligible partner signups when Allow Open Registration is OFF. Partner-rule credits are added on top of this amount. An unverified account receives no credits. A free user cannot spend beyond their total granted balance.",
|
|
10114
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
10115
10801
|
category: "Users"
|
|
10116
10802
|
}),
|
|
10117
10803
|
teamPlanMinSeats: makeNumberSetting({
|
|
@@ -10123,7 +10809,6 @@ const settingsMap = {
|
|
|
10123
10809
|
min: 1,
|
|
10124
10810
|
max: TEAM_PLAN_SEATS_HARD_LIMIT,
|
|
10125
10811
|
description: "Fewest seats a paid team subscription can be bought with. Enforced at checkout, on seat changes from Stripe and on admin conversion to paid. Admin grants may still go down to 1. If set above the maximum seats, the maximum wins.",
|
|
10126
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
10127
10812
|
category: "Users"
|
|
10128
10813
|
}),
|
|
10129
10814
|
teamPlanMaxSeats: makeNumberSetting({
|
|
@@ -10135,7 +10820,6 @@ const settingsMap = {
|
|
|
10135
10820
|
min: 1,
|
|
10136
10821
|
max: TEAM_PLAN_SEATS_HARD_LIMIT,
|
|
10137
10822
|
description: "Most seats any team can hold (owner + members + pending invites). Enforced at checkout, on every seat change, on admin grants and on the partner-signup auto-raise. Lowering it below a team that is already larger does not remove anyone; that team can only be set down to this cap.",
|
|
10138
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
10139
10823
|
category: "Users"
|
|
10140
10824
|
}),
|
|
10141
10825
|
teamPlanCreditsPerSeat: makeNumberSetting({
|
|
@@ -10146,7 +10830,6 @@ const settingsMap = {
|
|
|
10146
10830
|
min: 0,
|
|
10147
10831
|
max: 1e8,
|
|
10148
10832
|
description: "Credits added to a team pool per paid seat each billing cycle (and per seat-month on admin team grants). Applies to invoices issued after the change; credits already granted are not adjusted.",
|
|
10149
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
10150
10833
|
category: "Users",
|
|
10151
10834
|
userReadable: true
|
|
10152
10835
|
}),
|
|
@@ -10159,7 +10842,6 @@ const settingsMap = {
|
|
|
10159
10842
|
min: 0,
|
|
10160
10843
|
max: 1e8,
|
|
10161
10844
|
description: "Below this many credits a user sees the low-credit warning state. Set to 0 to show warnings only once credits run out.",
|
|
10162
|
-
group: API_SERVICE_GROUPS.CREDITS.id,
|
|
10163
10845
|
category: "Users"
|
|
10164
10846
|
}),
|
|
10165
10847
|
syntheticUserEmailDomains: makeStringSetting({
|
|
@@ -10238,6 +10920,16 @@ const settingsMap = {
|
|
|
10238
10920
|
group: API_SERVICE_GROUPS.USER_MANAGEMENT.id,
|
|
10239
10921
|
order: 3
|
|
10240
10922
|
}),
|
|
10923
|
+
showDesktopAppPromo: makeBooleanSetting({
|
|
10924
|
+
key: "showDesktopAppPromo",
|
|
10925
|
+
name: "Promote the Desktop App",
|
|
10926
|
+
defaultValue: true,
|
|
10927
|
+
description: "Show signed-in users the \"Try the desktop app\" button and the profile-menu link to the desktop download page. Turn off for deployments that do not want to point users at the published desktop builds.",
|
|
10928
|
+
category: "Branding",
|
|
10929
|
+
group: API_SERVICE_GROUPS.BRANDING.id,
|
|
10930
|
+
order: 9,
|
|
10931
|
+
userReadable: true
|
|
10932
|
+
}),
|
|
10241
10933
|
SystemFiles: makeStringSetting({
|
|
10242
10934
|
key: "SystemFiles",
|
|
10243
10935
|
name: "System Prompt Files",
|
|
@@ -10330,6 +11022,35 @@ const settingsMap = {
|
|
|
10330
11022
|
order: 4,
|
|
10331
11023
|
isSensitive: true
|
|
10332
11024
|
}),
|
|
11025
|
+
EnableStudioCreateV2: makeBooleanSetting({
|
|
11026
|
+
key: "EnableStudioCreateV2",
|
|
11027
|
+
name: "Enable Studio Create v2",
|
|
11028
|
+
defaultValue: false,
|
|
11029
|
+
description: "Admin-only preview of the restructured Studio Create area. Non-admins never see it, whatever this is set to.",
|
|
11030
|
+
category: "Experimental",
|
|
11031
|
+
group: API_SERVICE_GROUPS.EXPERIMENTAL.id,
|
|
11032
|
+
order: 300
|
|
11033
|
+
}),
|
|
11034
|
+
EnableStudioImage: makeBooleanSetting({
|
|
11035
|
+
key: "EnableStudioImage",
|
|
11036
|
+
name: "Enable Image in Studio",
|
|
11037
|
+
defaultValue: false,
|
|
11038
|
+
description: "Admin-only preview of the Image tab in Studio. Non-admins never see it, whatever this is set to.",
|
|
11039
|
+
category: "Experimental",
|
|
11040
|
+
group: API_SERVICE_GROUPS.EXPERIMENTAL.id,
|
|
11041
|
+
order: 301,
|
|
11042
|
+
dependsOn: "EnableStudioCreateV2"
|
|
11043
|
+
}),
|
|
11044
|
+
EnableStudioProductions: makeBooleanSetting({
|
|
11045
|
+
key: "EnableStudioProductions",
|
|
11046
|
+
name: "Enable Studio Productions",
|
|
11047
|
+
defaultValue: false,
|
|
11048
|
+
description: "Admin-only preview of Studio Productions (assembling many assets into one piece). Non-admins never see it, whatever this is set to.",
|
|
11049
|
+
category: "Experimental",
|
|
11050
|
+
group: API_SERVICE_GROUPS.EXPERIMENTAL.id,
|
|
11051
|
+
order: 302,
|
|
11052
|
+
dependsOn: "EnableStudioCreateV2"
|
|
11053
|
+
}),
|
|
10333
11054
|
EnablePotionQuest: makeBooleanSetting({
|
|
10334
11055
|
key: "EnablePotionQuest",
|
|
10335
11056
|
name: "Enable PotionQuest Tools",
|
|
@@ -11998,6 +12719,41 @@ const musicRequestSchema = z.object({
|
|
|
11998
12719
|
format: z.string().optional(),
|
|
11999
12720
|
...generatedAudioRequestFields
|
|
12000
12721
|
});
|
|
12722
|
+
const turnRetryShape = {
|
|
12723
|
+
reason: z$1.enum(TURN_RETRY_REASONS),
|
|
12724
|
+
status: z$1.number().optional(),
|
|
12725
|
+
retryAfterMs: z$1.number().optional(),
|
|
12726
|
+
requestId: z$1.string().optional(),
|
|
12727
|
+
delayMs: z$1.number(),
|
|
12728
|
+
model: z$1.string()
|
|
12729
|
+
};
|
|
12730
|
+
const turnTimingShape = {
|
|
12731
|
+
queueMs: z$1.number(),
|
|
12732
|
+
contextBuildMs: z$1.number().optional(),
|
|
12733
|
+
semaphoreWaitMs: z$1.number(),
|
|
12734
|
+
totalMs: z$1.number().optional(),
|
|
12735
|
+
fallbackHops: z$1.number()
|
|
12736
|
+
};
|
|
12737
|
+
/** Wire shape of ITurnTiming for the live chat frame; hydrates `at` into a Date server-side. */
|
|
12738
|
+
const TurnTimingSchema = z$1.object({
|
|
12739
|
+
...turnTimingShape,
|
|
12740
|
+
retries: z$1.array(z$1.object({
|
|
12741
|
+
...turnRetryShape,
|
|
12742
|
+
at: z$1.coerce.date()
|
|
12743
|
+
}))
|
|
12744
|
+
});
|
|
12745
|
+
/**
|
|
12746
|
+
* The same record for the public quest poll. `at` is an ISO string on the wire (a Date only
|
|
12747
|
+
* before JSON serialization). Not z.coerce.date() here: like the other public response schemas
|
|
12748
|
+
* (schemas/chat.ts, schemas/session.ts), it would document the field as nullable in OpenAPI.
|
|
12749
|
+
*/
|
|
12750
|
+
const TurnTimingPollSchema = z$1.object({
|
|
12751
|
+
...turnTimingShape,
|
|
12752
|
+
retries: z$1.array(z$1.object({
|
|
12753
|
+
...turnRetryShape,
|
|
12754
|
+
at: z$1.union([z$1.string().datetime(), z$1.date()])
|
|
12755
|
+
}))
|
|
12756
|
+
});
|
|
12001
12757
|
/**
|
|
12002
12758
|
* Canonical agent execution status tuple. Shared between the database model
|
|
12003
12759
|
* (`AgentExecutionModel`), the client store (`useAgentExecutionStore`), and
|
|
@@ -12182,7 +12938,7 @@ const CliCompletionRequestAction = z$1.object({
|
|
|
12182
12938
|
]),
|
|
12183
12939
|
content: z$1.union([z$1.string(), z$1.array(z$1.unknown())]),
|
|
12184
12940
|
cache: z$1.boolean().optional()
|
|
12185
|
-
})),
|
|
12941
|
+
})).min(1),
|
|
12186
12942
|
options: z$1.object({
|
|
12187
12943
|
temperature: z$1.number().optional(),
|
|
12188
12944
|
maxTokens: z$1.number().optional(),
|
|
@@ -12517,6 +13273,7 @@ const StreamedChatCompletionAction = z$1.object({
|
|
|
12517
13273
|
endTime: z$1.number().optional()
|
|
12518
13274
|
}).optional(),
|
|
12519
13275
|
fallbackInfo: FallbackInfoSchema.nullish(),
|
|
13276
|
+
turnTiming: TurnTimingSchema.optional(),
|
|
12520
13277
|
pendingAction: z$1.object({
|
|
12521
13278
|
tool: z$1.string(),
|
|
12522
13279
|
params: z$1.record(z$1.string(), z$1.unknown()),
|
|
@@ -13476,6 +14233,16 @@ const PermissionRequestAction = z$1.object({
|
|
|
13476
14233
|
*/
|
|
13477
14234
|
toolCallId: z$1.string().optional()
|
|
13478
14235
|
});
|
|
14236
|
+
const ConfidenceGateAction = z$1.object({
|
|
14237
|
+
action: z$1.literal("confidence_gate"),
|
|
14238
|
+
executionId: z$1.string(),
|
|
14239
|
+
/** 0-indexed wire convention, matching `permission_request` and `IterationStream`. */
|
|
14240
|
+
iteration: z$1.number(),
|
|
14241
|
+
/** 0..1, the agent's reported confidence for the paused iteration. */
|
|
14242
|
+
confidence: z$1.number(),
|
|
14243
|
+
/** Pre-formatted server copy, e.g. "2 iterations in a row below the 60% confidence threshold (latest 42%)". */
|
|
14244
|
+
reason: z$1.string()
|
|
14245
|
+
});
|
|
13479
14246
|
const ChildExecutionSnapshotSchema = z$1.lazy(() => z$1.object({
|
|
13480
14247
|
executionId: z$1.string(),
|
|
13481
14248
|
agentName: z$1.string(),
|
|
@@ -13490,6 +14257,7 @@ const ChildExecutionSnapshotSchema = z$1.lazy(() => z$1.object({
|
|
|
13490
14257
|
}));
|
|
13491
14258
|
const ReconnectResultAction = z$1.object({
|
|
13492
14259
|
action: z$1.literal("reconnect_result"),
|
|
14260
|
+
requestId: z$1.string().optional(),
|
|
13493
14261
|
found: z$1.boolean(),
|
|
13494
14262
|
executionId: z$1.string().optional(),
|
|
13495
14263
|
sessionId: z$1.string().optional(),
|
|
@@ -13500,6 +14268,13 @@ const ReconnectResultAction = z$1.object({
|
|
|
13500
14268
|
requestedAt: z$1.union([z$1.string(), z$1.date()]),
|
|
13501
14269
|
toolCallId: z$1.string().optional()
|
|
13502
14270
|
}).optional(),
|
|
14271
|
+
pendingGate: z$1.object({
|
|
14272
|
+
/** 0-indexed wire convention, matching `ConfidenceGateAction` and `IterationStream`. */
|
|
14273
|
+
iteration: z$1.number(),
|
|
14274
|
+
confidence: z$1.number(),
|
|
14275
|
+
reason: z$1.string(),
|
|
14276
|
+
requestedAt: z$1.union([z$1.string(), z$1.date()])
|
|
14277
|
+
}).optional(),
|
|
13503
14278
|
totalCreditsUsed: z$1.number().optional(),
|
|
13504
14279
|
iterationCount: z$1.number().optional(),
|
|
13505
14280
|
steps: z$1.array(AgentStepSchema).optional(),
|
|
@@ -13591,6 +14366,7 @@ z$1.discriminatedUnion("action", [
|
|
|
13591
14366
|
SubagentFailedAction,
|
|
13592
14367
|
SubagentProgressAction,
|
|
13593
14368
|
PermissionRequestAction,
|
|
14369
|
+
ConfidenceGateAction,
|
|
13594
14370
|
ReconnectResultAction
|
|
13595
14371
|
]);
|
|
13596
14372
|
const FLEET_USAGE_MAX_ROWS = 1e4;
|
|
@@ -13708,11 +14484,7 @@ const AgentExecutionStartRequestSchema = z$1.object({
|
|
|
13708
14484
|
* is what reproduces the product UI's Agent Mode toggle.
|
|
13709
14485
|
*/
|
|
13710
14486
|
agent_id: z$1.string().optional(),
|
|
13711
|
-
|
|
13712
|
-
* Bill this run to an organization's credit pool. The caller must belong to it; a
|
|
13713
|
-
* non-member gets 404. Omit to bill the caller personally.
|
|
13714
|
-
*/
|
|
13715
|
-
organization_id: z$1.string().optional(),
|
|
14487
|
+
organization_id: z$1.string().optional().describe("The organization whose credit pool pays for this run. You must belong to it; a non-member gets 404. Omit it to bill your personal credits. An organization-billed API key always bills its own organization: omit this or set it to the key's; any other value is a 403 (`errorCode: billing_organization_mismatch`)."),
|
|
13716
14488
|
/**
|
|
13717
14489
|
* Tool-id allowlist for the run. Omit to use the resolved profile's own list.
|
|
13718
14490
|
*
|
|
@@ -13839,7 +14611,8 @@ const ToolExecutionRequestSchema = z$1.object({
|
|
|
13839
14611
|
toolName: z$1.enum([
|
|
13840
14612
|
"weather_info",
|
|
13841
14613
|
"web_search",
|
|
13842
|
-
"web_fetch"
|
|
14614
|
+
"web_fetch",
|
|
14615
|
+
"decide"
|
|
13843
14616
|
]),
|
|
13844
14617
|
input: z$1.record(z$1.string(), z$1.unknown())
|
|
13845
14618
|
});
|
|
@@ -14376,7 +15149,9 @@ z.object({
|
|
|
14376
15149
|
/** Set to true if the file should be publicly accessible */
|
|
14377
15150
|
public: z.boolean().optional(),
|
|
14378
15151
|
/** The prefix to use for the file path */
|
|
14379
|
-
prefix: z.string().optional()
|
|
15152
|
+
prefix: z.string().optional(),
|
|
15153
|
+
/** Admin What's New media: the server stores it under its modal prefix and admits mp4 */
|
|
15154
|
+
purpose: z.literal("modal-media").optional()
|
|
14380
15155
|
});
|
|
14381
15156
|
/**
|
|
14382
15157
|
* Constants for BFL safety tolerance settings.
|
|
@@ -14978,6 +15753,7 @@ const QuestPollResponseSchema = ChatQuestPollResultSchema.extend({
|
|
|
14978
15753
|
promptMeta: z$1.record(z$1.string(), z$1.unknown()).optional(),
|
|
14979
15754
|
attachmentNotices: z$1.array(z$1.string()).optional(),
|
|
14980
15755
|
attachmentDelivery: z$1.record(z$1.string(), z$1.unknown()).optional(),
|
|
15756
|
+
turnTiming: TurnTimingPollSchema.optional(),
|
|
14981
15757
|
executionTracking: z$1.unknown().optional()
|
|
14982
15758
|
});
|
|
14983
15759
|
/**
|
|
@@ -15208,6 +15984,7 @@ z$2.object(passthroughShape({
|
|
|
15208
15984
|
pendingAction: true,
|
|
15209
15985
|
attachmentNotices: true,
|
|
15210
15986
|
attachmentDelivery: true,
|
|
15987
|
+
turnTiming: true,
|
|
15211
15988
|
navigationIntents: true,
|
|
15212
15989
|
suggestedChoices: true,
|
|
15213
15990
|
attachmentList: true,
|
|
@@ -15255,6 +16032,123 @@ z$2.object({
|
|
|
15255
16032
|
envVariables: envVariableResponseSchema,
|
|
15256
16033
|
metadata: metadataResponseSchema.nullish()
|
|
15257
16034
|
});
|
|
16035
|
+
const SAML_CONFIG_RESPONSE_FIELDS = {
|
|
16036
|
+
entryPoint: true,
|
|
16037
|
+
issuer: true,
|
|
16038
|
+
cert: true,
|
|
16039
|
+
callbackUrl: true,
|
|
16040
|
+
identifierFormat: true,
|
|
16041
|
+
acceptedClockSkewMs: true,
|
|
16042
|
+
attributeConsumingServiceIndex: true,
|
|
16043
|
+
disableRequestedAuthnContext: true,
|
|
16044
|
+
attributeMappings: true
|
|
16045
|
+
};
|
|
16046
|
+
const OKTA_CONFIG_RESPONSE_FIELDS = {
|
|
16047
|
+
audience: true,
|
|
16048
|
+
clientId: true,
|
|
16049
|
+
authServerId: true,
|
|
16050
|
+
useOrgAuthServer: true
|
|
16051
|
+
};
|
|
16052
|
+
/** An identity provider as the admin routes return it: configuration only, no credential values. */
|
|
16053
|
+
const identityProviderResponseSchema = z$2.object({
|
|
16054
|
+
...passthroughShape({
|
|
16055
|
+
id: true,
|
|
16056
|
+
name: true,
|
|
16057
|
+
emailDomain: true,
|
|
16058
|
+
type: true,
|
|
16059
|
+
isActive: true,
|
|
16060
|
+
samlConfig: true,
|
|
16061
|
+
oktaConfig: true,
|
|
16062
|
+
createdAt: true,
|
|
16063
|
+
updatedAt: true,
|
|
16064
|
+
createdBy: true
|
|
16065
|
+
}),
|
|
16066
|
+
samlConfig: z$2.object(passthroughShape(SAML_CONFIG_RESPONSE_FIELDS)).nullish(),
|
|
16067
|
+
oktaConfig: z$2.object(passthroughShape(OKTA_CONFIG_RESPONSE_FIELDS)).nullish()
|
|
16068
|
+
});
|
|
16069
|
+
/**
|
|
16070
|
+
* Which credentials an identity provider has stored: flags, never values. The single source for
|
|
16071
|
+
* the repository that computes them and the admin UI that reads them.
|
|
16072
|
+
*/
|
|
16073
|
+
const identityProviderSecretPresenceSchema = z$2.object({
|
|
16074
|
+
decryptionPvk: z$2.boolean(),
|
|
16075
|
+
privateCert: z$2.boolean(),
|
|
16076
|
+
clientSecret: z$2.boolean()
|
|
16077
|
+
});
|
|
16078
|
+
/** The admin list row: the provider plus which credentials are stored. */
|
|
16079
|
+
const identityProviderListItemResponseSchema = identityProviderResponseSchema.extend({ hasSecrets: identityProviderSecretPresenceSchema });
|
|
16080
|
+
z$2.array(identityProviderListItemResponseSchema);
|
|
16081
|
+
/** An API key as the admin routes return it: everything but the secret material. */
|
|
16082
|
+
const userApiKeyResponseSchema = z$2.object(passthroughShape({
|
|
16083
|
+
id: true,
|
|
16084
|
+
userId: true,
|
|
16085
|
+
name: true,
|
|
16086
|
+
keyPrefix: true,
|
|
16087
|
+
scopes: true,
|
|
16088
|
+
status: true,
|
|
16089
|
+
expiresAt: true,
|
|
16090
|
+
lastUsedAt: true,
|
|
16091
|
+
revokedAt: true,
|
|
16092
|
+
revokedBy: true,
|
|
16093
|
+
revokedReason: true,
|
|
16094
|
+
callbackSigningSecretCreatedAt: true,
|
|
16095
|
+
rateLimit: true,
|
|
16096
|
+
usage: true,
|
|
16097
|
+
metadata: true,
|
|
16098
|
+
productId: true,
|
|
16099
|
+
productName: true,
|
|
16100
|
+
billingOwnerType: true,
|
|
16101
|
+
organizationId: true,
|
|
16102
|
+
agentId: true,
|
|
16103
|
+
allowedOrigins: true,
|
|
16104
|
+
identifiedClientIds: true,
|
|
16105
|
+
preauthorizedLakeIds: true,
|
|
16106
|
+
branding: true,
|
|
16107
|
+
spendCap: true,
|
|
16108
|
+
ownerHasWhitelabel: true,
|
|
16109
|
+
createdAt: true,
|
|
16110
|
+
updatedAt: true
|
|
16111
|
+
}));
|
|
16112
|
+
/**
|
|
16113
|
+
* A key's live minute/day rate-limit counters. The single source for the server's
|
|
16114
|
+
* `RateLimitUsage` and the admin client's response type, so a new field cannot be stripped here
|
|
16115
|
+
* while the producer and the UI both expect it.
|
|
16116
|
+
*/
|
|
16117
|
+
const apiKeyRateLimitUsageSchema = z$2.object({
|
|
16118
|
+
minute: z$2.number(),
|
|
16119
|
+
day: z$2.number(),
|
|
16120
|
+
/** Epoch seconds when the current minute window ends; undefined when no window is open (count 0). */
|
|
16121
|
+
minuteResetAt: z$2.number().optional(),
|
|
16122
|
+
/** Epoch seconds when the current day window ends; undefined when no window is open (count 0). */
|
|
16123
|
+
dayResetAt: z$2.number().optional()
|
|
16124
|
+
});
|
|
16125
|
+
z$2.object({
|
|
16126
|
+
apiKeys: z$2.array(userApiKeyResponseSchema),
|
|
16127
|
+
liveUsage: z$2.record(z$2.string(), apiKeyRateLimitUsageSchema)
|
|
16128
|
+
});
|
|
16129
|
+
const emailVerificationUserResponseSchema = z$2.object(passthroughShape({
|
|
16130
|
+
_id: true,
|
|
16131
|
+
username: true,
|
|
16132
|
+
email: true,
|
|
16133
|
+
name: true,
|
|
16134
|
+
emailVerified: true,
|
|
16135
|
+
emailVerifiedAt: true,
|
|
16136
|
+
emailVerificationSentAt: true,
|
|
16137
|
+
emailVerificationExpires: true,
|
|
16138
|
+
pendingEmail: true,
|
|
16139
|
+
pendingEmailSentAt: true,
|
|
16140
|
+
pendingEmailExpires: true,
|
|
16141
|
+
createdAt: true
|
|
16142
|
+
}));
|
|
16143
|
+
z$2.object({
|
|
16144
|
+
users: z$2.array(emailVerificationUserResponseSchema),
|
|
16145
|
+
pagination: z$2.object({
|
|
16146
|
+
page: z$2.number(),
|
|
16147
|
+
limit: z$2.number(),
|
|
16148
|
+
totalPages: z$2.number(),
|
|
16149
|
+
totalCount: z$2.number()
|
|
16150
|
+
})
|
|
16151
|
+
});
|
|
15258
16152
|
const questMasterPlanResponseSchema = z$2.object(passthroughShape({
|
|
15259
16153
|
id: true,
|
|
15260
16154
|
createdAt: true,
|
|
@@ -15281,6 +16175,86 @@ z$2.object({
|
|
|
15281
16175
|
success: z$2.literal(true),
|
|
15282
16176
|
plan: questMasterPlanResponseSchema
|
|
15283
16177
|
}).extend({ metrics: passthroughField });
|
|
16178
|
+
/** A lake document as returned by the SPA data-lake routes (editor document or reader projection). */
|
|
16179
|
+
const dataLakeResponseSchema = z$2.object(passthroughShape({
|
|
16180
|
+
id: true,
|
|
16181
|
+
createdAt: true,
|
|
16182
|
+
updatedAt: true,
|
|
16183
|
+
name: true,
|
|
16184
|
+
slug: true,
|
|
16185
|
+
description: true,
|
|
16186
|
+
systemPrompt: true,
|
|
16187
|
+
injectPromptForReaders: true,
|
|
16188
|
+
preferredSystemPromptId: true,
|
|
16189
|
+
groundingMode: true,
|
|
16190
|
+
requiredPassageTokenTarget: true,
|
|
16191
|
+
inconsistencyReport: true,
|
|
16192
|
+
inconsistencyComputedAt: true,
|
|
16193
|
+
lastInconsistencyScanAt: true,
|
|
16194
|
+
fileTagPrefix: true,
|
|
16195
|
+
datalakeTag: true,
|
|
16196
|
+
requiredUserTag: true,
|
|
16197
|
+
requiredEntitlement: true,
|
|
16198
|
+
createdByUserId: true,
|
|
16199
|
+
lastUpdatedByUserId: true,
|
|
16200
|
+
organizationId: true,
|
|
16201
|
+
isPublic: true,
|
|
16202
|
+
auditQueryTextEnabled: true,
|
|
16203
|
+
status: true,
|
|
16204
|
+
fileCount: true,
|
|
16205
|
+
totalSizeBytes: true,
|
|
16206
|
+
totalChunkedChars: true,
|
|
16207
|
+
embeddingSpendMicroUsd: true,
|
|
16208
|
+
lastSyncAt: true,
|
|
16209
|
+
lastHealthCheckedAt: true,
|
|
16210
|
+
filesDeletedAt: true,
|
|
16211
|
+
filesArchivedAt: true,
|
|
16212
|
+
purgeClaimId: true,
|
|
16213
|
+
purgeStartedAt: true,
|
|
16214
|
+
lakeMemoryEnabled: true,
|
|
16215
|
+
lakeMemoryExtractionAt: true,
|
|
16216
|
+
lakeMemoryCursor: true,
|
|
16217
|
+
lakeMemoryPurgedAt: true,
|
|
16218
|
+
origin: true,
|
|
16219
|
+
pendingConnector: true,
|
|
16220
|
+
modelInconsistencyRunAt: true
|
|
16221
|
+
}));
|
|
16222
|
+
z$2.object({ data: z$2.array(dataLakeResponseSchema) });
|
|
16223
|
+
z$2.object({ data: z$2.array(z$2.object(passthroughShape({
|
|
16224
|
+
id: true,
|
|
16225
|
+
slug: true,
|
|
16226
|
+
name: true,
|
|
16227
|
+
requiredUserTag: true,
|
|
16228
|
+
requiredEntitlement: true,
|
|
16229
|
+
fileTagPrefix: true,
|
|
16230
|
+
datalakeTag: true,
|
|
16231
|
+
organizationId: true,
|
|
16232
|
+
description: true,
|
|
16233
|
+
isPublic: true,
|
|
16234
|
+
lakeMemoryEnabled: true,
|
|
16235
|
+
injectPromptForReaders: true,
|
|
16236
|
+
canManage: true,
|
|
16237
|
+
status: true,
|
|
16238
|
+
origin: true,
|
|
16239
|
+
systemPrompt: true,
|
|
16240
|
+
requiredPassageTokenTarget: true,
|
|
16241
|
+
isOwn: true,
|
|
16242
|
+
isCreator: true,
|
|
16243
|
+
canPreauthorize: true,
|
|
16244
|
+
ownerDisplayName: true,
|
|
16245
|
+
ownerUserId: true,
|
|
16246
|
+
ownerUsername: true,
|
|
16247
|
+
preferredSystemPromptId: true,
|
|
16248
|
+
pendingProposalCount: true,
|
|
16249
|
+
groundingMode: true,
|
|
16250
|
+
pendingConnector: true,
|
|
16251
|
+
hasGitHubConnection: true,
|
|
16252
|
+
embeddingSpendMicroUsd: true,
|
|
16253
|
+
canRebuild: true,
|
|
16254
|
+
canManageSettings: true,
|
|
16255
|
+
canManageMemory: true,
|
|
16256
|
+
retrievable: true
|
|
16257
|
+
}))) });
|
|
15284
16258
|
z$1.preprocess((val) => {
|
|
15285
16259
|
if (typeof val === "string") {
|
|
15286
16260
|
if (val.toLowerCase() === "true") return true;
|
|
@@ -15625,6 +16599,14 @@ const EmbeddingsErrorSchema = ApiErrorSchema.extend({ errorCode: z$1.enum([
|
|
|
15625
16599
|
"provider_not_configured",
|
|
15626
16600
|
"provider_rejected"
|
|
15627
16601
|
]).optional() });
|
|
16602
|
+
const MAX_REFINE_TEXT_CHARS = 1e4;
|
|
16603
|
+
const MAX_REFINE_CONTEXT_CHARS = 1e4;
|
|
16604
|
+
const TextRefinementRequestSchema = z$1.object({
|
|
16605
|
+
text: z$1.string().min(1).max(MAX_REFINE_TEXT_CHARS),
|
|
16606
|
+
context: z$1.string().max(MAX_REFINE_CONTEXT_CHARS).optional()
|
|
16607
|
+
});
|
|
16608
|
+
const TextRefinementResponseSchema = z$1.object({ text: z$1.string() });
|
|
16609
|
+
const TextRefinementErrorSchema = ApiErrorSchema.extend({ errorCode: z$1.enum(["provider_not_configured", "provider_rejected"]).optional() });
|
|
15628
16610
|
/**
|
|
15629
16611
|
* Every tool name in `b4mLLMTools`. Exhaustive by annotation - do not widen the type.
|
|
15630
16612
|
*/
|
|
@@ -15652,6 +16634,7 @@ const CORE_TOOL_SIDE_EFFECTS = {
|
|
|
15652
16634
|
fmp_financial_data: "none",
|
|
15653
16635
|
bob_panel_read: "none",
|
|
15654
16636
|
skill: "none",
|
|
16637
|
+
decide: "none",
|
|
15655
16638
|
recharts: "local",
|
|
15656
16639
|
mermaid_chart: "local",
|
|
15657
16640
|
navigate_view: "local",
|
|
@@ -15725,6 +16708,19 @@ const InternalTeamMemberSchema = z$1.object({
|
|
|
15725
16708
|
isActive: z$1.boolean().optional()
|
|
15726
16709
|
});
|
|
15727
16710
|
z$1.array(InternalTeamMemberSchema);
|
|
16711
|
+
/** An internal team member as the admin routes return it. */
|
|
16712
|
+
const internalTeamMemberResponseSchema = z$1.object(passthroughShape({
|
|
16713
|
+
id: true,
|
|
16714
|
+
name: true,
|
|
16715
|
+
phone: true,
|
|
16716
|
+
email: true,
|
|
16717
|
+
role: true,
|
|
16718
|
+
department: true,
|
|
16719
|
+
isActive: true,
|
|
16720
|
+
createdAt: true,
|
|
16721
|
+
updatedAt: true
|
|
16722
|
+
}));
|
|
16723
|
+
z$1.array(internalTeamMemberResponseSchema);
|
|
15728
16724
|
/**
|
|
15729
16725
|
* Lattice Zod Schemas
|
|
15730
16726
|
*
|
|
@@ -16511,6 +17507,32 @@ const UpdateProjectRequestSchema = z$1.object({
|
|
|
16511
17507
|
description: z$1.string().min(1).optional()
|
|
16512
17508
|
}).strict();
|
|
16513
17509
|
/**
|
|
17510
|
+
* Wire schemas for the Skill Market's Claude Code plugin feed
|
|
17511
|
+
* (api-contract/contracts/skillMarket.contract.ts). The 200 body is a Claude Code
|
|
17512
|
+
* `marketplace.json`, so its field names follow Claude Code, not this API's snake_case.
|
|
17513
|
+
*/
|
|
17514
|
+
const ClaudeMarketplaceQuerySchema = z$1.object({ orgId: z$1.string().min(1) });
|
|
17515
|
+
const ClaudePluginZipParamSchema = z$1.object({ id: z$1.string().min(1) });
|
|
17516
|
+
const ClaudePluginZipQuerySchema = z$1.object({ version: z$1.coerce.number().int().positive().optional() });
|
|
17517
|
+
const ClaudeMarketplacePluginSchema = z$1.object({
|
|
17518
|
+
name: z$1.string(),
|
|
17519
|
+
description: z$1.string(),
|
|
17520
|
+
/** The listing's approved version number; Claude Code offers an update when it changes. */
|
|
17521
|
+
version: z$1.string(),
|
|
17522
|
+
source: z$1.object({
|
|
17523
|
+
source: z$1.literal("archive"),
|
|
17524
|
+
url: z$1.string(),
|
|
17525
|
+
sha256: z$1.string()
|
|
17526
|
+
})
|
|
17527
|
+
});
|
|
17528
|
+
const ClaudeMarketplaceSchema = z$1.object({
|
|
17529
|
+
name: z$1.string(),
|
|
17530
|
+
owner: z$1.object({ name: z$1.string() }),
|
|
17531
|
+
/** Claude Code uninstalls installed plugins this feed stops listing, at the next session start. */
|
|
17532
|
+
forceRemoveDeletedPlugins: z$1.boolean(),
|
|
17533
|
+
plugins: z$1.array(ClaudeMarketplacePluginSchema)
|
|
17534
|
+
});
|
|
17535
|
+
/**
|
|
16514
17536
|
* The public projection of `ModelInfo` served by `GET /api/v1/models`.
|
|
16515
17537
|
*
|
|
16516
17538
|
* Deliberately narrower than `ModelInfo`: every field here is one an integrator can pin, so
|
|
@@ -16590,8 +17612,8 @@ const ListModelsResponseSchema = paginatedResponseSchema(z$1.object({
|
|
|
16590
17612
|
reasons_within_output_budget: z$1.boolean().describe("Whether reasoning tokens are spent inside `max_output_tokens` on every turn. When true, a small `max_tokens` can be used up by reasoning alone and return an empty reply, so leave room above the answer you expect."),
|
|
16591
17613
|
reasoning_efforts: z$1.array(CompletionReasoningEffortSchema).describe("The `reasoningEffort` levels this model acts on, lowest first; empty when it ignores the option. `none` is listed only where it turns reasoning off. Each level is mapped to the nearest one the provider offers. A listed level can still be dropped on one request: some OpenAI models drop it on tool turns, and Claude models with a fixed thinking budget drop it when `max_tokens` leaves no room for the budget plus the answer."),
|
|
16592
17614
|
supports_tools: z$1.boolean(),
|
|
16593
|
-
supports_tool_search: z$1.boolean().describe("Whether the model accepts the tool search server tool and `defer_loading: true` on tool definitions, so a large tool catalog is searched on demand instead of loaded into context up front. Describes the model: `/api/ai/v1/completions` honours it
|
|
16594
|
-
supports_tool_changes: z$1.boolean().describe("Whether a system-role message can carry `tool_addition` and `tool_removal` blocks, which add or remove a declared tool mid-conversation. Describes the model
|
|
17615
|
+
supports_tool_search: z$1.boolean().describe("Whether the model accepts the tool search server tool and `defer_loading: true` on tool definitions, so a large tool catalog is searched on demand instead of loaded into context up front. Describes the model: `/api/ai/v1/completions` honours it for every model with this flag set, whether its `backend` is `anthropic` or `bedrock`."),
|
|
17616
|
+
supports_tool_changes: z$1.boolean().describe("Whether a system-role message can carry `tool_addition` and `tool_removal` blocks, which add or remove a declared tool mid-conversation. Describes the model: `/api/ai/v1/completions` honours it only for models whose `backend` is `anthropic`; a `bedrock` model with this flag set is refused there with `errorCode: \"tool_changes_unsupported\"`."),
|
|
16595
17617
|
supports_vision: z$1.boolean(),
|
|
16596
17618
|
deprecation_date: z$1.string().nullable().describe("`YYYY-MM-DD`; null when no retirement is scheduled."),
|
|
16597
17619
|
replaced_by: z$1.string().nullable().describe("The id of the recommended successor, when there is one."),
|
|
@@ -16717,7 +17739,7 @@ const GenerateImageIvokeParamsSchema = OpenAIImageGenerationInput.extend({
|
|
|
16717
17739
|
referenceImageFabFileIds: z$1.array(z$1.string()).max(15).optional(),
|
|
16718
17740
|
tools: z$1.array(z$1.union([b4mLLMTools, z$1.string()])).optional(),
|
|
16719
17741
|
safety_tolerance: BFLSafetyToleranceSchema,
|
|
16720
|
-
prompt_upsampling: z$1.boolean().
|
|
17742
|
+
prompt_upsampling: z$1.boolean().prefault(false).describe("Let the provider rewrite and expand the prompt before rendering. Applies to Black Forest Labs (FLUX) models only; other models ignore it. Defaults to false."),
|
|
16721
17743
|
seed: z$1.number().nullable().optional(),
|
|
16722
17744
|
output_format: ImageOutputFormatSchema.nullable().optional(),
|
|
16723
17745
|
/** Resolved by the API route's prompt resolver. Defaults to 'fresh' for first-turn or sessions with no prior image. */
|
|
@@ -16847,7 +17869,13 @@ z$1.object({
|
|
|
16847
17869
|
"tool"
|
|
16848
17870
|
]),
|
|
16849
17871
|
content: z$1.union([z$1.string(), z$1.array(z$1.any())]),
|
|
16850
|
-
fabFileIds: z$1.array(z$1.string()).optional()
|
|
17872
|
+
fabFileIds: z$1.array(z$1.string()).optional(),
|
|
17873
|
+
/**
|
|
17874
|
+
* Send this message in the current user turn instead of the system prompt, keeping the
|
|
17875
|
+
* system prefix byte-stable for prompt caching. Only for content that changes every turn
|
|
17876
|
+
* (a view description, a per-send brief); a caller's actual system prompt must not set it.
|
|
17877
|
+
*/
|
|
17878
|
+
perTurn: z$1.boolean().optional()
|
|
16851
17879
|
})).optional(),
|
|
16852
17880
|
/** Dashboard related params */
|
|
16853
17881
|
dashboardParams: DashboardParamsSchema.optional(),
|
|
@@ -17036,11 +18064,15 @@ const VideoGenerationErrorResponseSchema = ApiErrorSchema.extend({ errorCode: z$
|
|
|
17036
18064
|
const CreateVideoGenerationBodySchema = z$1.strictObject({
|
|
17037
18065
|
model: z$1.string().min(1).describe("A model id from GET /api/v1/video-models."),
|
|
17038
18066
|
prompt: z$1.string().min(1).max(4e3),
|
|
17039
|
-
mode: z$1.enum(VIDEO_MODES).optional().describe("Defaults to image_to_video when input_image_file_id is set, else text_to_video."),
|
|
18067
|
+
mode: z$1.enum(VIDEO_MODES).optional().describe("Defaults to image_to_video when a first_frame input (or input_image_file_id) is set, else text_to_video."),
|
|
17040
18068
|
duration_seconds: z$1.number().positive().optional().describe("Defaults to the model's default duration."),
|
|
17041
18069
|
aspect_ratio: z$1.enum(ASPECT_RATIOS).optional(),
|
|
17042
18070
|
resolution: z$1.enum(RESOLUTION_TIERS).optional(),
|
|
17043
|
-
|
|
18071
|
+
inputs: z$1.array(z$1.strictObject({
|
|
18072
|
+
file_id: z$1.string().min(1),
|
|
18073
|
+
role: z$1.enum(VIDEO_INPUT_ROLES)
|
|
18074
|
+
})).max(8).optional().describe("Image files you own, each tagged with what it is for. image_to_video needs a first_frame. The roles a model accepts, and how many of each, are its input_roles in GET /api/v1/video-models."),
|
|
18075
|
+
input_image_file_id: z$1.string().min(1).optional().describe("Deprecated: send inputs with role first_frame instead. Cannot be combined with inputs."),
|
|
17044
18076
|
audio: z$1.boolean().optional(),
|
|
17045
18077
|
organization_id: BillingOrganizationIdSchema
|
|
17046
18078
|
});
|
|
@@ -17082,6 +18114,10 @@ const VideoModelSchema = z$1.object({
|
|
|
17082
18114
|
display_name: z$1.string(),
|
|
17083
18115
|
provider: z$1.string(),
|
|
17084
18116
|
modes: z$1.array(z$1.enum(VIDEO_MODES)),
|
|
18117
|
+
input_roles: z$1.array(z$1.object({
|
|
18118
|
+
role: z$1.string(),
|
|
18119
|
+
max: z$1.number().int().positive()
|
|
18120
|
+
})).optional().describe(`The inputs[] roles this model accepts and the most of each one request may carry. Roles today: ${VIDEO_INPUT_ROLES.join(", ")}; ignore any you do not know.`),
|
|
17085
18121
|
duration: z$1.union([z$1.object({
|
|
17086
18122
|
kind: z$1.literal("range"),
|
|
17087
18123
|
min: z$1.number(),
|
|
@@ -17388,9 +18424,13 @@ defineEndpoint({
|
|
|
17388
18424
|
schema: AgentExecutionAckSchema
|
|
17389
18425
|
},
|
|
17390
18426
|
400: {
|
|
17391
|
-
description:
|
|
18427
|
+
description: `No usable default chat model is configured and none was supplied. ${BILLING_ORGANIZATION_STALE_KEY_DESCRIPTION}`,
|
|
17392
18428
|
schema: ApiErrorSchema
|
|
17393
18429
|
},
|
|
18430
|
+
403: {
|
|
18431
|
+
description: `The API key holds neither the \`ai:chat\` nor the \`ai:generate\` scope, or an organization-billed API key names any organization but its own (\`errorCode: ${BILLING_ORGANIZATION_MISMATCH_ERROR_CODE}\`).`,
|
|
18432
|
+
schema: BillingOrganizationForbiddenErrorSchema
|
|
18433
|
+
},
|
|
17394
18434
|
404: {
|
|
17395
18435
|
description: "No session with the given `session_id` is owned by the caller, or `organization_id` names an organization the caller does not belong to. \"Exists but is not yours\" is reported as 404 too, so neither session ids nor org membership can be probed through this endpoint.",
|
|
17396
18436
|
schema: ApiErrorSchema
|
|
@@ -17600,7 +18640,7 @@ defineEndpoint({
|
|
|
17600
18640
|
path: "/api/ai/v1/tools",
|
|
17601
18641
|
operationId: "executeTool",
|
|
17602
18642
|
summary: "Execute a server-side tool",
|
|
17603
|
-
description: "Runs one of the built-in server-side tools (`weather_info`, `web_search`, `web_fetch`) and returns its result as JSON. Authenticate with a JWT access token only - API keys are NOT accepted on this endpoint. Rate-limited to 100 requests/hour per user, counted separately from other endpoints. `request_id` echoes the X-Request-ID response header.",
|
|
18643
|
+
description: "Runs one of the built-in server-side tools (`weather_info`, `web_search`, `web_fetch`, `decide`) and returns its result as JSON. Authenticate with a JWT access token only - API keys are NOT accepted on this endpoint. Rate-limited to 100 requests/hour per user, counted separately from other endpoints. `request_id` echoes the X-Request-ID response header.",
|
|
17604
18644
|
tags: ["AI"],
|
|
17605
18645
|
auth: "jwtOnly",
|
|
17606
18646
|
request: ToolExecutionRequestSchema,
|
|
@@ -17655,7 +18695,7 @@ defineEndpoint({
|
|
|
17655
18695
|
path: "/api/ai/v1/completions",
|
|
17656
18696
|
operationId: "createCompletion",
|
|
17657
18697
|
summary: "Create a chat completion",
|
|
17658
|
-
description: "OpenAI-compatible completion. A successful request is ALWAYS answered with an SSE stream (`text/event-stream`), regardless of the `stream` flag: a `meta` event, then `content`/`tool_use` events carrying `usage`/`credits`, terminated by `data: [DONE]`. The terminal event carries `stopReason`; treat `max_tokens` as a TRUNCATED reply rather than a complete one, and note that omitting `max_tokens` on the request lets the server size the output ceiling for the model (recommended for reasoning models, which spend thinking tokens inside that ceiling). A message `content` may be a string or an array of parts; image parts are accepted in OpenAI Chat (`image_url`), OpenAI Responses (`input_image`) or Anthropic (`image` with a `source`) form and are translated to whatever the target model speaks. Authenticate with an API key (`b4m_live_`) or a JWT.\n\nTOOL SEARCH. On a model whose `GET /api/v1/models` row has `supports_tool_search: true`
|
|
18698
|
+
description: "OpenAI-compatible completion. A successful request is ALWAYS answered with an SSE stream (`text/event-stream`), regardless of the `stream` flag: a `meta` event, then `content`/`tool_use` events carrying `usage`/`credits`, terminated by `data: [DONE]`. The terminal event carries `stopReason`; treat `max_tokens` as a TRUNCATED reply rather than a complete one, and note that omitting `max_tokens` on the request lets the server size the output ceiling for the model (recommended for reasoning models, which spend thinking tokens inside that ceiling). A message `content` may be a string or an array of parts; image parts are accepted in OpenAI Chat (`image_url`), OpenAI Responses (`input_image`) or Anthropic (`image` with a `source`) form and are translated to whatever the target model speaks. Authenticate with an API key (`b4m_live_`) or a JWT.\n\nTOOL SEARCH. On a model whose `GET /api/v1/models` row has `supports_tool_search: true` (`backend` `\"anthropic\"` or `\"bedrock\"`), a `tools` entry may set `toolSchema.defer_loading: true`, and a `{ \"serverTool\": { \"type\": \"tool_search_tool_regex_20251119\", \"name\": \"tool_search_tool_regex\" } }` (or the `bm25` pair) entry adds Anthropic's tool search, so deferred definitions load only when the model searches for them. The stream then carries `provider_block` events (`{ type, provider: \"anthropic\", block }`) for the server-run search; echo each block back verbatim, in order, in the assistant `messages` content of the next request, and never answer one with a `tool_result`. When the server-run search loop hits its iteration limit the stream ends with `stopReason: \"pause_turn\"`; continue by re-sending the conversation with that assistant turn's provider blocks echoed. A client-side search may return `{ \"type\": \"tool_reference\", \"tool_name\": \"...\" }` blocks inside a `tool_result`'s content. On every other model `defer_loading` is ignored (every tool is sent as usual) and a server tool, a `tool_reference` or an echoed tool search block is refused with a `400` rather than run without it.\n\nERRORS. Everything checked before the model provider is called fails with a JSON error body and a real HTTP status, before any stream opens: an empty `messages` array, a conversation with no non-empty user or assistant message (system-only, or only blank content), a malformed request, or an unknown `model` `400` (`errorCode: \"unknown_model\"` for an unknown model), a bad credential `401`, a key without a required scope `403` (with `required_scopes`), a body over 25 MB `413`, any other body that fails schema validation `422`, insufficient credits `422` with `errorCode: \"insufficient_credits\"` (personal or org balance, or an org per-member credit cap), a rate limit `429` with `Retry-After`, and a catalogued model whose provider is not configured on this deployment, or a model that could only come from a self-hosted model server (Ollama, local image) that is currently unreachable, `503` with `errorCode: \"provider_not_configured\"` (retryable). A provider rejection of caller input that happens before the stream opens is also a JSON `400`, with `errorCode: \"invalid_request\"` (do not retry it unchanged). Once the stream has opened the status stays `200` and a failure arrives as one terminal in-band `error` event. Branch on that event's `code`, never on `message`, which is prose and may change: `insufficient_credits` (buy credits) when credits run out mid-generation, `invalid_request` when the provider rejects caller input (do not retry it unchanged), `provider_rejected` when the model provider refused our credentials, `content_blocked` when the model declined the request (do not retry it unchanged), and `provider_error` for any other provider failure. Treat `code` as optional.",
|
|
17659
18699
|
tags: ["AI"],
|
|
17660
18700
|
auth: "apiKeyOrJwt",
|
|
17661
18701
|
scopes: ["ai:chat", "ai:generate"],
|
|
@@ -17689,7 +18729,7 @@ defineEndpoint({
|
|
|
17689
18729
|
}
|
|
17690
18730
|
},
|
|
17691
18731
|
400: {
|
|
17692
|
-
description: "Malformed or otherwise invalid request (no `errorCode`), or a `model` the caller cannot use (`errorCode: \"unknown_model\"`): not in the catalog or not available to the caller. List valid ids with `GET /api/v1/models`. Tool search requests are refused with: `tool_search_unsupported` (a server tool, `tool_reference` or echoed tool search block on a model that cannot serve tool search here), `all_tools_deferred` (every tool deferred and no server tool), `deferred_tool_cache_control` (`cache_control` on a deferred tool), `unknown_tool_reference` (a `tool_reference` naming a tool not in `tools`, or carrying no string `tool_name`). Mid-conversation tool changes are refused with: `tool_changes_unsupported` (a `tool_addition` / `tool_removal` system message on a model that cannot serve it here), `invalid_tool_change` (a malformed block, or one placed where the provider does not accept it), and `unknown_tool_reference` (a changed tool not in `tools`).",
|
|
18732
|
+
description: "Malformed or otherwise invalid request (no `errorCode`), provider-rejected caller input (`errorCode: \"invalid_request\"`), or a `model` the caller cannot use (`errorCode: \"unknown_model\"`): not in the catalog or not available to the caller. List valid ids with `GET /api/v1/models`. Tool search requests are refused with: `tool_search_unsupported` (a server tool, `tool_reference` or echoed tool search block on a model that cannot serve tool search here), `all_tools_deferred` (every tool deferred and no server tool), `deferred_tool_cache_control` (`cache_control` on a deferred tool), `unknown_tool_reference` (a `tool_reference` naming a tool not in `tools`, or carrying no string `tool_name`). Mid-conversation tool changes are refused with: `tool_changes_unsupported` (a `tool_addition` / `tool_removal` system message on a model that cannot serve it here), `invalid_tool_change` (a malformed block, or one placed where the provider does not accept it), and `unknown_tool_reference` (a changed tool not in `tools`).",
|
|
17693
18733
|
schema: CompletionsBadRequestErrorSchema
|
|
17694
18734
|
},
|
|
17695
18735
|
413: {
|
|
@@ -17710,7 +18750,7 @@ defineEndpoint({
|
|
|
17710
18750
|
schema: ApiErrorSchema
|
|
17711
18751
|
},
|
|
17712
18752
|
503: {
|
|
17713
|
-
description: "Temporarily unavailable: the model's provider is not configured on this deployment (`errorCode: \"provider_not_configured\"`), or the database is unreachable (no `errorCode`). Retry later.",
|
|
18753
|
+
description: "Temporarily unavailable: the model's provider is not configured on this deployment, or the self-hosted model server that lists it (Ollama, local image) is unreachable (`errorCode: \"provider_not_configured\"`), or the database is unreachable (no `errorCode`). Retry later.",
|
|
17714
18754
|
schema: ProviderNotConfiguredErrorSchema
|
|
17715
18755
|
}
|
|
17716
18756
|
},
|
|
@@ -18513,7 +19553,7 @@ defineEndpoint({
|
|
|
18513
19553
|
streaming: false
|
|
18514
19554
|
}
|
|
18515
19555
|
});
|
|
18516
|
-
const EXAMPLE_REQUEST$
|
|
19556
|
+
const EXAMPLE_REQUEST$2 = {
|
|
18517
19557
|
model: "text-embedding-3-small",
|
|
18518
19558
|
input: ["The quick brown fox", "jumps over the lazy dog"],
|
|
18519
19559
|
dimensions: 1024
|
|
@@ -18528,7 +19568,7 @@ defineEndpoint({
|
|
|
18528
19568
|
auth: "apiKeyOrJwt",
|
|
18529
19569
|
scopes: ["ai:generate"],
|
|
18530
19570
|
request: EmbeddingsRequestSchema,
|
|
18531
|
-
requestExample: EXAMPLE_REQUEST$
|
|
19571
|
+
requestExample: EXAMPLE_REQUEST$2,
|
|
18532
19572
|
responses: {
|
|
18533
19573
|
200: {
|
|
18534
19574
|
description: "One embedding per input, in input order.",
|
|
@@ -18585,6 +19625,55 @@ defineEndpoint({
|
|
|
18585
19625
|
}
|
|
18586
19626
|
},
|
|
18587
19627
|
emitsRateLimitHeaders: true,
|
|
19628
|
+
codeSample: {
|
|
19629
|
+
authToken: "b4m_live_<key>",
|
|
19630
|
+
streaming: false,
|
|
19631
|
+
body: EXAMPLE_REQUEST$2
|
|
19632
|
+
}
|
|
19633
|
+
});
|
|
19634
|
+
const EXAMPLE_REQUEST$1 = {
|
|
19635
|
+
text: "a dog on a beach",
|
|
19636
|
+
context: "prompt for an image generator"
|
|
19637
|
+
};
|
|
19638
|
+
defineEndpoint({
|
|
19639
|
+
method: "post",
|
|
19640
|
+
path: "/api/v1/text-refinements",
|
|
19641
|
+
operationId: "createTextRefinement",
|
|
19642
|
+
summary: "Refine text",
|
|
19643
|
+
description: `Rewrites \`text\` to be more concise, clear and detailed while keeping its intent. \`context\` is optional background that steers the rewrite. \`text\` is at most ${MAX_REFINE_TEXT_CHARS} characters and \`context\` at most ${MAX_REFINE_CONTEXT_CHARS}. Output is capped at about 800 tokens, and identical requests are served from a cache for about five minutes. Not billed in credits. Authenticate with an API key (\`b4m_live_\`) carrying \`ai:generate\`, or a JWT.`,
|
|
19644
|
+
tags: ["AI"],
|
|
19645
|
+
auth: "apiKeyOrJwt",
|
|
19646
|
+
scopes: ["ai:generate"],
|
|
19647
|
+
request: TextRefinementRequestSchema,
|
|
19648
|
+
requestExample: EXAMPLE_REQUEST$1,
|
|
19649
|
+
responses: {
|
|
19650
|
+
200: {
|
|
19651
|
+
description: "The refined text.",
|
|
19652
|
+
schema: TextRefinementResponseSchema,
|
|
19653
|
+
example: { text: "A golden retriever running along a sunlit beach at sunset, waves breaking behind it." }
|
|
19654
|
+
},
|
|
19655
|
+
401: {
|
|
19656
|
+
description: "Missing/invalid credentials, or the text-refinement provider refused the configured key (`errorCode: \"provider_rejected\"`).",
|
|
19657
|
+
schema: TextRefinementErrorSchema
|
|
19658
|
+
},
|
|
19659
|
+
429: {
|
|
19660
|
+
description: "Per-key rate limit exceeded.",
|
|
19661
|
+
schema: ApiErrorSchema
|
|
19662
|
+
},
|
|
19663
|
+
500: {
|
|
19664
|
+
description: "Unexpected server error (for example the refinement cache is unavailable).",
|
|
19665
|
+
schema: ApiErrorSchema
|
|
19666
|
+
},
|
|
19667
|
+
502: {
|
|
19668
|
+
description: "The model call failed for a reason other than a rejected credential, or returned no refined text.",
|
|
19669
|
+
schema: ApiErrorSchema
|
|
19670
|
+
},
|
|
19671
|
+
503: {
|
|
19672
|
+
description: "This deployment has no operations model configured (`errorCode: \"provider_not_configured\"`).",
|
|
19673
|
+
schema: TextRefinementErrorSchema
|
|
19674
|
+
}
|
|
19675
|
+
},
|
|
19676
|
+
emitsRateLimitHeaders: true,
|
|
18588
19677
|
codeSample: {
|
|
18589
19678
|
authToken: "b4m_live_<key>",
|
|
18590
19679
|
streaming: false,
|
|
@@ -19238,7 +20327,7 @@ defineEndpoint({
|
|
|
19238
20327
|
path: "/api/v1/transcriptions",
|
|
19239
20328
|
operationId: "createTranscription",
|
|
19240
20329
|
summary: "Transcribe audio",
|
|
19241
|
-
description: "Transcribes an upload minted by `POST /api/v1/transcriptions/uploads` and returns the text. Call it within 5 minutes of minting the upload. Credits are charged by file size. The uploaded audio is deleted when the call returns, whether it succeeds or fails, so each upload can be transcribed once.\n\n**Limit:** this call is synchronous.
|
|
20330
|
+
description: "Transcribes an upload minted by `POST /api/v1/transcriptions/uploads` and returns the text. Call it within 5 minutes of minting the upload. Credits are charged by file size. The uploaded audio is deleted when the call returns, whether it succeeds or fails, so each upload can be transcribed once.\n\n**Limit:** this call is synchronous. Provider work stops being awaited after 45 seconds from request arrival, leaving time to return reserved credits and delete the upload before the hosted server stops at 60 seconds. A slow recording returns a gateway timeout (`504`) instead of text. AWS batch jobs cannot be cancelled remotely and may finish later; their output expires automatically. Do not retry with the same `file_key`: mint a new upload and send shorter audio. If cleanup fails, the upload may not be deleted right away (it expires on its own).",
|
|
19242
20331
|
tags: ["Transcriptions"],
|
|
19243
20332
|
auth: "apiKeyOrJwt",
|
|
19244
20333
|
scopes: ["ai:generate"],
|
|
@@ -19268,6 +20357,10 @@ defineEndpoint({
|
|
|
19268
20357
|
503: {
|
|
19269
20358
|
description: "This deployment has no speech model, or no credential for its provider, configured (`errorCode: \"provider_not_configured\"`).",
|
|
19270
20359
|
schema: ProviderNotConfiguredErrorSchema
|
|
20360
|
+
},
|
|
20361
|
+
504: {
|
|
20362
|
+
description: "The transcription exceeded the request deadline; reserved credits are returned.",
|
|
20363
|
+
schema: ApiErrorSchema
|
|
19271
20364
|
}
|
|
19272
20365
|
},
|
|
19273
20366
|
codeSample: {
|
|
@@ -19374,6 +20467,35 @@ defineEndpoint({
|
|
|
19374
20467
|
}
|
|
19375
20468
|
}
|
|
19376
20469
|
});
|
|
20470
|
+
defineEndpoint({
|
|
20471
|
+
method: "get",
|
|
20472
|
+
path: "/api/v1/whats-new/media/{id}/{asset}",
|
|
20473
|
+
operationId: "getWhatsNewMedia",
|
|
20474
|
+
summary: "Get release note media",
|
|
20475
|
+
description: "Redirects to one file of a published release note video: `landscape` and `portrait` are the 16:9 and 9:16 MP4s, the `-poster` assets their still images. The `video` URLs that listWhatsNew returns for uploaded files point here, so a browser can use them as `src` and `poster` as they are. Public: no credentials are needed, and the note must be one listWhatsNew would show. The redirect is cacheable for up to 10 minutes and its target is signed for 1 hour, longer than that, so follow it rather than storing the target. Rate limited per client IP.",
|
|
20476
|
+
tags: ["Release notes"],
|
|
20477
|
+
auth: "public",
|
|
20478
|
+
pathParams: ReleaseNoteMediaParamsSchema,
|
|
20479
|
+
responses: {
|
|
20480
|
+
303: {
|
|
20481
|
+
description: "`Location` is a time-limited signed GET for the file.",
|
|
20482
|
+
noBody: true,
|
|
20483
|
+
headers: { Location: "Signed URL of the file." }
|
|
20484
|
+
},
|
|
20485
|
+
404: {
|
|
20486
|
+
description: "No published note has this id, or the note has no such file, or the file is not an upload this deployment serves (a linked URL is listed as is, not through this route).",
|
|
20487
|
+
schema: ApiErrorSchema
|
|
20488
|
+
},
|
|
20489
|
+
429: {
|
|
20490
|
+
description: "Per-IP rate limit exceeded.",
|
|
20491
|
+
schema: ApiErrorSchema
|
|
20492
|
+
},
|
|
20493
|
+
500: {
|
|
20494
|
+
description: "Unexpected server error.",
|
|
20495
|
+
schema: ApiErrorSchema
|
|
20496
|
+
}
|
|
20497
|
+
}
|
|
20498
|
+
});
|
|
19377
20499
|
/**
|
|
19378
20500
|
* The read/write/query API-key scope sets the data-lake doors accept (OR semantics), shared by the
|
|
19379
20501
|
* SPA routes (`apps/client/server/dataLakes/dataLakeScopes.ts` re-exports these) and the public
|
|
@@ -19726,11 +20848,11 @@ defineEndpoint({
|
|
|
19726
20848
|
schema: ApiErrorSchema
|
|
19727
20849
|
},
|
|
19728
20850
|
404: {
|
|
19729
|
-
description: "`input_image_file_id` does not name an image you own (`errorCode: input_image_not_found`). A nonexistent `organization_id` is `404` only for an admin caller; for anyone else it is `403`.",
|
|
20851
|
+
description: "An `inputs` file (or `input_image_file_id`) does not name an image you own (`errorCode: input_image_not_found`). A nonexistent `organization_id` is `404` only for an admin caller; for anyone else it is `403`.",
|
|
19730
20852
|
schema: VideoGenerationErrorResponseSchema
|
|
19731
20853
|
},
|
|
19732
20854
|
422: {
|
|
19733
|
-
description: "The request cannot run: a body or capability violation (`errorCode` names it, e.g. `unsupported_duration`), an unknown or unavailable model (`model_unavailable`), a model your administrator disabled (`model_disabled`), too few credits (`insufficient_credits`), or an Idempotency-Key problem (`invalid_idempotency_key`, `idempotency_key_reused`).",
|
|
20855
|
+
description: "The request cannot run: a body or capability violation (`errorCode` names it, e.g. `unsupported_duration`, or `unsupported_input_role` for an input role the model does not take), an unknown or unavailable model (`model_unavailable`), a model your administrator disabled (`model_disabled`), too few credits (`insufficient_credits`), or an Idempotency-Key problem (`invalid_idempotency_key`, `idempotency_key_reused`).",
|
|
19734
20856
|
schema: VideoGenerationErrorResponseSchema
|
|
19735
20857
|
},
|
|
19736
20858
|
429: rateLimited$1
|
|
@@ -20573,6 +21695,94 @@ defineEndpoint({
|
|
|
20573
21695
|
streaming: false
|
|
20574
21696
|
}
|
|
20575
21697
|
});
|
|
21698
|
+
const AUTH_NOTE = "Authenticate with an API key (`b4m_live_`) carrying `skills:read`, sent as `Authorization: Bearer`. Claude Code sends that header when it is set as the marketplace source's `headers` in its settings, and forwards it to the same-origin plugin archives.";
|
|
21699
|
+
defineEndpoint({
|
|
21700
|
+
method: "get",
|
|
21701
|
+
path: "/api/v1/skills/market/claude-marketplace.json",
|
|
21702
|
+
operationId: "getClaudeMarketplace",
|
|
21703
|
+
summary: "Get an organization's Claude Code plugin marketplace",
|
|
21704
|
+
description: `Returns a Claude Code \`marketplace.json\` listing the organization's approved Organization-visibility Skill Market listings, one \`archive\` plugin each, pinned by \`sha256\`. Public and unlisted listings are not included. Responses are never cacheable. ${AUTH_NOTE}`,
|
|
21705
|
+
tags: ["Skills"],
|
|
21706
|
+
auth: "apiKeyOrJwt",
|
|
21707
|
+
scopes: ["skills:read"],
|
|
21708
|
+
queryParams: ClaudeMarketplaceQuerySchema,
|
|
21709
|
+
emitsRateLimitHeaders: true,
|
|
21710
|
+
responses: {
|
|
21711
|
+
200: {
|
|
21712
|
+
description: "The marketplace.",
|
|
21713
|
+
schema: ClaudeMarketplaceSchema,
|
|
21714
|
+
example: {
|
|
21715
|
+
name: `b4m-org-${EXAMPLE_RESOURCE_ID}`,
|
|
21716
|
+
owner: { name: "Acme" },
|
|
21717
|
+
forceRemoveDeletedPlugins: true,
|
|
21718
|
+
plugins: [{
|
|
21719
|
+
name: "review-pr",
|
|
21720
|
+
description: "Review a pull request against the team checklist.",
|
|
21721
|
+
version: "3",
|
|
21722
|
+
source: {
|
|
21723
|
+
source: "archive",
|
|
21724
|
+
url: `https://app.bike4mind.com/api/v1/skills/market/${EXAMPLE_RESOURCE_ID}/claude-plugin.zip?version=3`,
|
|
21725
|
+
sha256: "a3f1c0de9b8e7d6c5b4a39281706f5e4d3c2b1a09f8e7d6c5b4a392817060f5e"
|
|
21726
|
+
}
|
|
21727
|
+
}]
|
|
21728
|
+
}
|
|
21729
|
+
},
|
|
21730
|
+
403: {
|
|
21731
|
+
description: "The API key lacks `skills:read`, or the caller is not a member of the organization.",
|
|
21732
|
+
schema: ScopeForbiddenErrorSchema
|
|
21733
|
+
},
|
|
21734
|
+
429: {
|
|
21735
|
+
description: "Per-user rate limit exceeded.",
|
|
21736
|
+
schema: ApiErrorSchema
|
|
21737
|
+
}
|
|
21738
|
+
},
|
|
21739
|
+
codeSample: {
|
|
21740
|
+
authToken: "b4m_live_<key>",
|
|
21741
|
+
streaming: false,
|
|
21742
|
+
body: {}
|
|
21743
|
+
}
|
|
21744
|
+
});
|
|
21745
|
+
defineEndpoint({
|
|
21746
|
+
method: "get",
|
|
21747
|
+
path: "/api/v1/skills/market/{id}/claude-plugin.zip",
|
|
21748
|
+
operationId: "getClaudePluginZip",
|
|
21749
|
+
summary: "Download a Skill Market listing as a Claude Code plugin",
|
|
21750
|
+
description: `A zip holding an approved version as \`skills/<name>/SKILL.md\`. The optional \`version\` query pins the listing version advertised by the feed, so later approvals do not change its bytes or \`sha256\`. Without it, returns the current approved version. ${AUTH_NOTE}`,
|
|
21751
|
+
tags: ["Skills"],
|
|
21752
|
+
auth: "apiKeyOrJwt",
|
|
21753
|
+
scopes: ["skills:read"],
|
|
21754
|
+
pathParams: ClaudePluginZipParamSchema,
|
|
21755
|
+
queryParams: ClaudePluginZipQuerySchema,
|
|
21756
|
+
validationErrorStatus: 400,
|
|
21757
|
+
emitsRateLimitHeaders: true,
|
|
21758
|
+
responses: {
|
|
21759
|
+
200: {
|
|
21760
|
+
description: "The plugin archive.",
|
|
21761
|
+
contentType: "application/zip"
|
|
21762
|
+
},
|
|
21763
|
+
400: {
|
|
21764
|
+
description: "Invalid version query.",
|
|
21765
|
+
schema: ApiErrorSchema
|
|
21766
|
+
},
|
|
21767
|
+
403: {
|
|
21768
|
+
description: "The API key lacks `skills:read`.",
|
|
21769
|
+
schema: ScopeForbiddenErrorSchema
|
|
21770
|
+
},
|
|
21771
|
+
404: {
|
|
21772
|
+
description: "No Organization listing with that id is visible to the caller. A listing in an org you are not in, a public or unlisted listing, and a malformed id are all reported as 404.",
|
|
21773
|
+
schema: ApiErrorSchema
|
|
21774
|
+
},
|
|
21775
|
+
429: {
|
|
21776
|
+
description: "Per-user rate limit exceeded.",
|
|
21777
|
+
schema: ApiErrorSchema
|
|
21778
|
+
}
|
|
21779
|
+
},
|
|
21780
|
+
codeSample: {
|
|
21781
|
+
authToken: "b4m_live_<key>",
|
|
21782
|
+
streaming: false,
|
|
21783
|
+
body: {}
|
|
21784
|
+
}
|
|
21785
|
+
});
|
|
20576
21786
|
/**
|
|
20577
21787
|
* The fence language the model writes to place an inline map of search-result places in a reply.
|
|
20578
21788
|
*
|
|
@@ -23301,7 +24511,7 @@ async function sleep(ms, abortSignal) {
|
|
|
23301
24511
|
* Respects Retry-After headers when present (e.g., for 429 rate limiting).
|
|
23302
24512
|
*/
|
|
23303
24513
|
async function withRetry(fn, options = {}) {
|
|
23304
|
-
const { maxRetries = 3, initialDelayMs = 100, maxDelayMs = 5e3, jitterFactor = .1, isRetryable = isRetryableError, logger, abortSignal } = options;
|
|
24514
|
+
const { maxRetries = 3, initialDelayMs = 100, maxDelayMs = 5e3, jitterFactor = .1, isRetryable = isRetryableError, logger, abortSignal, onRetry } = options;
|
|
23305
24515
|
let attempts = 0;
|
|
23306
24516
|
let totalDelayMs = 0;
|
|
23307
24517
|
while (true) try {
|
|
@@ -23332,6 +24542,15 @@ async function withRetry(fn, options = {}) {
|
|
|
23332
24542
|
attempt: attempts,
|
|
23333
24543
|
delayMs
|
|
23334
24544
|
});
|
|
24545
|
+
try {
|
|
24546
|
+
onRetry?.({
|
|
24547
|
+
attempt: attempts,
|
|
24548
|
+
delayMs,
|
|
24549
|
+
error: err
|
|
24550
|
+
});
|
|
24551
|
+
} catch (callbackError) {
|
|
24552
|
+
logger?.warn("onRetry callback threw; continuing the retry", { error: String(callbackError) });
|
|
24553
|
+
}
|
|
23335
24554
|
try {
|
|
23336
24555
|
await sleep(delayMs, abortSignal);
|
|
23337
24556
|
} catch {
|
|
@@ -24298,6 +25517,7 @@ const CORE_TOOL_DESCRIPTORS = new Map(Object.entries({
|
|
|
24298
25517
|
weather_info: reader(CORE, { openWorld: true }),
|
|
24299
25518
|
web_search: reader(CORE, { openWorld: true }),
|
|
24300
25519
|
web_fetch: reader(CORE, { openWorld: true }),
|
|
25520
|
+
decide: reader(CORE, { openWorld: true }),
|
|
24301
25521
|
deep_research: reader(CORE, { openWorld: true }),
|
|
24302
25522
|
check_shell_output: reader(),
|
|
24303
25523
|
list_background_shells: reader(),
|
|
@@ -25867,4 +27087,4 @@ var ConfigStore = class {
|
|
|
25867
27087
|
}
|
|
25868
27088
|
};
|
|
25869
27089
|
//#endregion
|
|
25870
|
-
export {
|
|
27090
|
+
export { ModelBackend as $, selfClaimedActorKindSchema as $t, ARTIFACT_REMOVED_PLACEHOLDER as A, isUserInitiatedAbort as At, ChatModels as B, supportedVoiceGenerationVendor as Bt, htmlErrorTitle as C, getMcpProviderMetadata as Ct, AGENT_QUEST_MANIFEST as D, isEarlyStop as Dt, AGENT_QUEST_ID as E, hasDeliverablePinnedArtifact as Et, BRIEFCASE_CATALOG_QUERIES as F, secureParameters as Ft, DecisionTextPartSchema as G, visibleReplyText as Gt, CreateArtifactRequestSchema as H, ttsBase64ResponseSchema as Ht, BedrockEmbeddingModel as I, signImageUrl as It, ImageModels as J, DELEGATION_PAYLOAD_SCHEMA_NAME as Jt, DecisionsRequestSchema as K, withRetry as Kt, BriefcasePromptIdSchema as L, splitEquals as Lt, ApiKeyType as M, obfuscateApiKey as Mt, ArtifactTypeSchema as N, questReplyText as Nt, AGENT_QUEST_MCP_URI as O, isPlaceholderImageSigningSecret as Ot, AudioMimeType as P, replacePromptVariables as Pt, McpServerName as Q, delegationPayloadSchema as Qt, CONTEXT_WINDOW_SAFETY_BUFFER_TOKENS as R, stripDeliveredArtifactBlocks as Rt, isValidSessionId as S, generatedAudioResponseSchema as St, escapeArtifactBodyJson as T, googleMapsSearchUrl as Tt, DEFAULT_TTS_PROVIDER as U, ttsRequestSchema as Ut, CompletionReasoningEffortSchema as V, tokenEstimateMultiplier as Vt, DEGENERATE_FINISH_REASON as W, ttsResponseTooLargeSchema as Wt, LOCATION_MAP_LANGUAGE as X, actorKindMarker as Xt, ImagePromptResolutionSchema as Y, actorColorIndex as Yt, MODEL_INFO_FIELD_GROUP_OF as Z, actorKindSchema as Zt, LOCAL_DEV_URL as _, buildPromptContext as _t, commandTextOf as a, REVIEW_GATE_STATUS_VALUES as at, logger as b, escapeThinkMarkers as bt, toolCategory as c, SUBQUEST_STATUS_VALUES as ct, getCreditsUrl as d, TTS_MAX_INPUT_CHARS as dt, frontmatterHasSourceStamp as en, NotFoundError as et, getEnvironmentName as f, UnprocessableEntityError as ft, DeviceFlowClient as g, assertAuthOriginMatchesApiKey as gt, AuthenticatedApiClient as h, WORK_ITEM_STATUSES as ht, ToolCatalog as i, WEBSITE_URL as in, PermissionDeniedError as it, ApiKeyScope as j, joinReplySlots as jt, ARTIFACT_DELIVERED_PLACEHOLDER as k, isRetryableError as kt, writePathOf as l, SupportedFabFileMimeTypes as lt, resolveApiEndpoint as m, VoyageAIEmbeddingModel as mt, extractCompactInstructions as n, splitSkillMdFrontmatter as nn, OpenAIEmbeddingModel as nt, isReadOnlyTool as o, SEARCH_RESULT_CARDS_LANGUAGE as ot, requireApiUrl as p, VisibilitySchema as pt, GENERATED_IMAGE_EXTENSION_RE as q, ACTOR_COLOR_SLOTS as qt, loadContextFiles as r, APP_NAME as rn, PROMPT_TEXT_MAX as rt, sandboxedCommandArg as s, SLUG_OWNED_BY_OTHER as st, ConfigStore as t, readSkillMdSourceUrl as tn, OllamaEmbeddingModel as tt, ApiEndpointUnconfiguredError as u, TTS_DEFAULT_MODEL as ut, NotAuthenticatedError as v, completionsSupportsToolSearch as vt, htmlFirstH1 as w, getQuestErrorCode as wt, SESSION_ID_PATTERN as x, filterToolArtifactMarkup as xt, parseApiUrl as y, createThinkMarkerEscaper as yt, CREDIT_DEDUCT_TRANSACTION_TYPES as z, stripToolArtifactMarkup as zt };
|