@overaihq/cli 0.15.1 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1482 -142
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1591,7 +1591,7 @@ var require_xpath = __commonJS({
|
|
|
1591
1591
|
function toString2(x) {
|
|
1592
1592
|
return x.toString();
|
|
1593
1593
|
}
|
|
1594
|
-
var
|
|
1594
|
+
var join9 = function(s, xs) {
|
|
1595
1595
|
return xs.join(s);
|
|
1596
1596
|
};
|
|
1597
1597
|
var wrap = function(pref, suf, str) {
|
|
@@ -3337,7 +3337,7 @@ var require_xpath = __commonJS({
|
|
|
3337
3337
|
return wrap("[", "]", predicate.toString());
|
|
3338
3338
|
};
|
|
3339
3339
|
PathExpr.predicatesString = function(predicates) {
|
|
3340
|
-
return
|
|
3340
|
+
return join9(
|
|
3341
3341
|
"",
|
|
3342
3342
|
map3(PathExpr.predicateString, predicates)
|
|
3343
3343
|
);
|
|
@@ -4692,7 +4692,7 @@ var require_xpath = __commonJS({
|
|
|
4692
4692
|
}
|
|
4693
4693
|
return acc;
|
|
4694
4694
|
}, {}, from);
|
|
4695
|
-
var t =
|
|
4695
|
+
var t = join9(
|
|
4696
4696
|
"",
|
|
4697
4697
|
map3(function(ch) {
|
|
4698
4698
|
return ch in cMap ? cMap[ch] : ch;
|
|
@@ -13529,7 +13529,7 @@ var require_jsonata = __commonJS({
|
|
|
13529
13529
|
}
|
|
13530
13530
|
return result;
|
|
13531
13531
|
}
|
|
13532
|
-
function
|
|
13532
|
+
function join9(strs, separator) {
|
|
13533
13533
|
if (typeof strs === "undefined") {
|
|
13534
13534
|
return void 0;
|
|
13535
13535
|
}
|
|
@@ -14460,7 +14460,7 @@ var require_jsonata = __commonJS({
|
|
|
14460
14460
|
contains: contains2,
|
|
14461
14461
|
replace: replace2,
|
|
14462
14462
|
split: split2,
|
|
14463
|
-
join:
|
|
14463
|
+
join: join9,
|
|
14464
14464
|
formatNumber,
|
|
14465
14465
|
formatBase,
|
|
14466
14466
|
number: number4,
|
|
@@ -38122,6 +38122,1082 @@ var automationRunState = async (client, runId) => {
|
|
|
38122
38122
|
if (data.automationRun == null) throw new Error(`Run ${runId} not found.`);
|
|
38123
38123
|
return data.automationRun.state ?? {};
|
|
38124
38124
|
};
|
|
38125
|
+
var automationRun = async (client, runId, options) => {
|
|
38126
|
+
const data = await client.graphql(
|
|
38127
|
+
`query SdkAutomationRun($id: String!) {
|
|
38128
|
+
automationRun(id: $id) {
|
|
38129
|
+
id startedAt endedAt errored isCancelled manuallyTriggered version { num }
|
|
38130
|
+
}
|
|
38131
|
+
}`,
|
|
38132
|
+
{ id: runId },
|
|
38133
|
+
options
|
|
38134
|
+
);
|
|
38135
|
+
const run2 = data.automationRun;
|
|
38136
|
+
if (run2 == null)
|
|
38137
|
+
throw new Error(
|
|
38138
|
+
`Run ${runId} not found or not accessible in this organization.`
|
|
38139
|
+
);
|
|
38140
|
+
return {
|
|
38141
|
+
id: run2.id,
|
|
38142
|
+
version: run2.version?.num,
|
|
38143
|
+
startedAt: run2.startedAt,
|
|
38144
|
+
endedAt: run2.endedAt,
|
|
38145
|
+
status: run2.errored ? "errored" : run2.isCancelled ? "cancelled" : run2.endedAt == null ? "running" : "ok",
|
|
38146
|
+
manual: run2.manuallyTriggered
|
|
38147
|
+
};
|
|
38148
|
+
};
|
|
38149
|
+
|
|
38150
|
+
// ../common/src/llm/models.ts
|
|
38151
|
+
var DEFAULT_MODEL = "claude-sonnet-5-5";
|
|
38152
|
+
var DEFAULT_OPENAI_MODEL = "gpt-6.1-sol";
|
|
38153
|
+
var LARGE_SCHEMA_MODELS = [
|
|
38154
|
+
DEFAULT_OPENAI_MODEL,
|
|
38155
|
+
"gemini-4-argon"
|
|
38156
|
+
];
|
|
38157
|
+
var stripAnthropicThinking = (opts) => {
|
|
38158
|
+
const anthropicOpts = opts?.anthropic;
|
|
38159
|
+
if (!opts || !anthropicOpts || !("thinking" in anthropicOpts)) return opts;
|
|
38160
|
+
const { thinking: _omit, ...rest } = anthropicOpts;
|
|
38161
|
+
return { ...opts, anthropic: rest };
|
|
38162
|
+
};
|
|
38163
|
+
var bothVertexRegions = (route) => [
|
|
38164
|
+
{ ...route, subprocessor: "vertex-global" },
|
|
38165
|
+
{ ...route, subprocessor: "vertex-us" }
|
|
38166
|
+
];
|
|
38167
|
+
var HAIKU_5_5_PRICING = {
|
|
38168
|
+
input: 0.1,
|
|
38169
|
+
output: 0.5,
|
|
38170
|
+
cacheRead: 0.01,
|
|
38171
|
+
cacheWrite: 0.125,
|
|
38172
|
+
longContext: {
|
|
38173
|
+
inputTokenThreshold: 1e5,
|
|
38174
|
+
input: 0.5,
|
|
38175
|
+
output: 2.5,
|
|
38176
|
+
cacheRead: 0.05,
|
|
38177
|
+
cacheWrite: 0.625
|
|
38178
|
+
}
|
|
38179
|
+
};
|
|
38180
|
+
var GEMINI_FLASH_PROMO_PRICING = {
|
|
38181
|
+
input: 0.75,
|
|
38182
|
+
output: 3.75,
|
|
38183
|
+
cacheRead: 0.075,
|
|
38184
|
+
cacheWrite: 0.75
|
|
38185
|
+
};
|
|
38186
|
+
var SONNET_5_5_PRICING_PERIODS = [
|
|
38187
|
+
{
|
|
38188
|
+
from: "2026-09-28",
|
|
38189
|
+
through: "2026-10-06",
|
|
38190
|
+
pricing: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }
|
|
38191
|
+
}
|
|
38192
|
+
];
|
|
38193
|
+
var MODEL_ROUTES = [
|
|
38194
|
+
// Anthropic. Pricing cacheWrite = 1.25x input — the 5-minute-TTL write rate,
|
|
38195
|
+
// which is what applyAnthropicCacheBreakpoints buys (1h TTL would bill 2x).
|
|
38196
|
+
// The 5.5 generation: 1M context, 128K output, vision and tool use.
|
|
38197
|
+
// Current architect default (see DEFAULT_MODEL).
|
|
38198
|
+
{
|
|
38199
|
+
model: "claude-sonnet-5-5",
|
|
38200
|
+
id: "claude-sonnet-5-5",
|
|
38201
|
+
name: "Claude Sonnet 5.5",
|
|
38202
|
+
subprocessor: "anthropic",
|
|
38203
|
+
provider: "anthropic",
|
|
38204
|
+
active: true,
|
|
38205
|
+
pricing: { input: 2, output: 10, cacheRead: 0.1, cacheWrite: 2.5 },
|
|
38206
|
+
pricingPeriods: SONNET_5_5_PRICING_PERIODS
|
|
38207
|
+
},
|
|
38208
|
+
{
|
|
38209
|
+
model: "claude-opus-5-5",
|
|
38210
|
+
id: "claude-opus-5-5",
|
|
38211
|
+
name: "Claude Opus 5.5",
|
|
38212
|
+
subprocessor: "anthropic",
|
|
38213
|
+
provider: "anthropic",
|
|
38214
|
+
active: true,
|
|
38215
|
+
pricing: { input: 4, output: 20, cacheRead: 0.2, cacheWrite: 5 }
|
|
38216
|
+
},
|
|
38217
|
+
{
|
|
38218
|
+
model: "claude-fable-5-1",
|
|
38219
|
+
id: "claude-fable-5-1",
|
|
38220
|
+
name: "Claude Fable 5.1",
|
|
38221
|
+
subprocessor: "anthropic",
|
|
38222
|
+
provider: "anthropic",
|
|
38223
|
+
active: true,
|
|
38224
|
+
pricing: { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 },
|
|
38225
|
+
providerOptionsTransform: stripAnthropicThinking
|
|
38226
|
+
},
|
|
38227
|
+
{
|
|
38228
|
+
model: "claude-haiku-5-5",
|
|
38229
|
+
id: "claude-haiku-5-5",
|
|
38230
|
+
name: "Claude Haiku 5.5",
|
|
38231
|
+
subprocessor: "anthropic",
|
|
38232
|
+
provider: "anthropic",
|
|
38233
|
+
active: true,
|
|
38234
|
+
pricing: HAIKU_5_5_PRICING
|
|
38235
|
+
},
|
|
38236
|
+
{
|
|
38237
|
+
model: "claude-sonnet-4-6",
|
|
38238
|
+
id: "claude-sonnet-4-6",
|
|
38239
|
+
name: "Claude Sonnet 4.6",
|
|
38240
|
+
subprocessor: "anthropic",
|
|
38241
|
+
provider: "anthropic",
|
|
38242
|
+
active: true,
|
|
38243
|
+
pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }
|
|
38244
|
+
},
|
|
38245
|
+
// Superseded by Sonnet 5.5: same input and output price, half the cache-read
|
|
38246
|
+
// rate. Launched 2026-06-30 at a $2/$10 launch rate that Anthropic made
|
|
38247
|
+
// permanent on 2026-08-10, so the announced $3/$15 was never billed and the
|
|
38248
|
+
// row needs no pricing window.
|
|
38249
|
+
{
|
|
38250
|
+
model: "claude-sonnet-5",
|
|
38251
|
+
id: "claude-sonnet-5",
|
|
38252
|
+
name: "Claude Sonnet 5",
|
|
38253
|
+
subprocessor: "anthropic",
|
|
38254
|
+
provider: "anthropic",
|
|
38255
|
+
active: false,
|
|
38256
|
+
pricing: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }
|
|
38257
|
+
},
|
|
38258
|
+
// Superseded by Opus 5.5 (cheaper, newer).
|
|
38259
|
+
{
|
|
38260
|
+
model: "claude-opus-5",
|
|
38261
|
+
id: "claude-opus-5",
|
|
38262
|
+
name: "Claude Opus 5",
|
|
38263
|
+
subprocessor: "anthropic",
|
|
38264
|
+
provider: "anthropic",
|
|
38265
|
+
active: false,
|
|
38266
|
+
pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
|
|
38267
|
+
},
|
|
38268
|
+
// Superseded by Fable 5.1 (same price).
|
|
38269
|
+
{
|
|
38270
|
+
model: "claude-fable-5",
|
|
38271
|
+
id: "claude-fable-5",
|
|
38272
|
+
name: "Claude Fable 5",
|
|
38273
|
+
subprocessor: "anthropic",
|
|
38274
|
+
provider: "anthropic",
|
|
38275
|
+
active: false,
|
|
38276
|
+
pricing: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 },
|
|
38277
|
+
providerOptionsTransform: stripAnthropicThinking
|
|
38278
|
+
},
|
|
38279
|
+
// Superseded by Haiku 5.5 at a tenth of the price. Its "not sooner than
|
|
38280
|
+
// 2026-10-15" retirement date has passed with no deprecation notice yet.
|
|
38281
|
+
{
|
|
38282
|
+
model: "claude-haiku-4-5",
|
|
38283
|
+
id: "claude-haiku-4-5",
|
|
38284
|
+
name: "Claude Haiku 4.5",
|
|
38285
|
+
subprocessor: "anthropic",
|
|
38286
|
+
provider: "anthropic",
|
|
38287
|
+
active: false,
|
|
38288
|
+
pricing: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }
|
|
38289
|
+
},
|
|
38290
|
+
// Superseded by Opus 5 (same price, newer); kept addressable for persisted
|
|
38291
|
+
// automations/agents but dropped from the dropdown.
|
|
38292
|
+
{
|
|
38293
|
+
model: "claude-opus-4-8",
|
|
38294
|
+
id: "claude-opus-4-8",
|
|
38295
|
+
name: "Claude Opus 4.8",
|
|
38296
|
+
subprocessor: "anthropic",
|
|
38297
|
+
provider: "anthropic",
|
|
38298
|
+
active: false,
|
|
38299
|
+
pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
|
|
38300
|
+
},
|
|
38301
|
+
// Opus 4.7 sat between 4.6 and 4.8; kept addressable for any persisted
|
|
38302
|
+
// automations but not surfaced in the dropdown now that 4.8 is out.
|
|
38303
|
+
{
|
|
38304
|
+
model: "claude-opus-4-7",
|
|
38305
|
+
id: "claude-opus-4-7",
|
|
38306
|
+
name: "Claude Opus 4.7",
|
|
38307
|
+
subprocessor: "anthropic",
|
|
38308
|
+
provider: "anthropic",
|
|
38309
|
+
active: false,
|
|
38310
|
+
pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
|
|
38311
|
+
},
|
|
38312
|
+
// $5/$25 since its 2026-02-05 launch (the $15/$75 to $5/$25 cut came with
|
|
38313
|
+
// Opus 4.5); keep in sync with platform.claude.com/docs/.../pricing.
|
|
38314
|
+
{
|
|
38315
|
+
model: "claude-opus-4-6",
|
|
38316
|
+
id: "claude-opus-4-6",
|
|
38317
|
+
name: "Claude Opus 4.6",
|
|
38318
|
+
subprocessor: "anthropic",
|
|
38319
|
+
provider: "anthropic",
|
|
38320
|
+
active: false,
|
|
38321
|
+
pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
|
|
38322
|
+
},
|
|
38323
|
+
// Deprecated 2026-09-30; retires on the direct API 2026-11-30, when
|
|
38324
|
+
// SUNSET_MODEL_REPLACEMENTS moves persisted names to Sonnet 5.5.
|
|
38325
|
+
{
|
|
38326
|
+
model: "claude-sonnet-4-5",
|
|
38327
|
+
id: "claude-sonnet-4-5",
|
|
38328
|
+
name: "Claude Sonnet 4.5",
|
|
38329
|
+
subprocessor: "anthropic",
|
|
38330
|
+
provider: "anthropic",
|
|
38331
|
+
active: false,
|
|
38332
|
+
pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }
|
|
38333
|
+
},
|
|
38334
|
+
// OpenAI (docs at developers.openai.com). The 6 line (Astra frontier / Sol
|
|
38335
|
+
// balanced / Luna efficient) supersedes 5.6; 5.6 and older stay addressable
|
|
38336
|
+
// for persisted configs but drop from the dropdown. From 5.6 on, cacheRead =
|
|
38337
|
+
// 10% of input (6.1 Sol: 5%) and cacheWrite = 1.25x input for the default
|
|
38338
|
+
// 30-minute cache; older models bill no cache write, so their cacheWrite
|
|
38339
|
+
// equals input. Above 272K input tokens OpenAI bills the full request at 2x
|
|
38340
|
+
// input and cache rates and 1.5x output.
|
|
38341
|
+
{
|
|
38342
|
+
model: "gpt-6.1-sol",
|
|
38343
|
+
id: "gpt-6.1-sol",
|
|
38344
|
+
name: "GPT 6.1 Sol",
|
|
38345
|
+
subprocessor: "openai",
|
|
38346
|
+
provider: "openai",
|
|
38347
|
+
active: true,
|
|
38348
|
+
pricing: {
|
|
38349
|
+
input: 2,
|
|
38350
|
+
output: 10,
|
|
38351
|
+
cacheRead: 0.1,
|
|
38352
|
+
cacheWrite: 2.5,
|
|
38353
|
+
longContext: {
|
|
38354
|
+
inputTokenThreshold: 272e3,
|
|
38355
|
+
input: 4,
|
|
38356
|
+
output: 15,
|
|
38357
|
+
cacheRead: 0.2,
|
|
38358
|
+
cacheWrite: 5
|
|
38359
|
+
}
|
|
38360
|
+
}
|
|
38361
|
+
},
|
|
38362
|
+
{
|
|
38363
|
+
model: "gpt-6-luna",
|
|
38364
|
+
id: "gpt-6-luna",
|
|
38365
|
+
name: "GPT 6 Luna",
|
|
38366
|
+
subprocessor: "openai",
|
|
38367
|
+
provider: "openai",
|
|
38368
|
+
active: true,
|
|
38369
|
+
pricing: {
|
|
38370
|
+
input: 0.1,
|
|
38371
|
+
output: 0.5,
|
|
38372
|
+
cacheRead: 0.01,
|
|
38373
|
+
cacheWrite: 0.125,
|
|
38374
|
+
longContext: {
|
|
38375
|
+
inputTokenThreshold: 272e3,
|
|
38376
|
+
input: 0.2,
|
|
38377
|
+
output: 0.75,
|
|
38378
|
+
cacheRead: 0.02,
|
|
38379
|
+
cacheWrite: 0.25
|
|
38380
|
+
}
|
|
38381
|
+
}
|
|
38382
|
+
},
|
|
38383
|
+
{
|
|
38384
|
+
model: "gpt-6-astra",
|
|
38385
|
+
id: "gpt-6-astra",
|
|
38386
|
+
name: "GPT 6 Astra",
|
|
38387
|
+
subprocessor: "openai",
|
|
38388
|
+
provider: "openai",
|
|
38389
|
+
active: true,
|
|
38390
|
+
pricing: {
|
|
38391
|
+
input: 10,
|
|
38392
|
+
output: 50,
|
|
38393
|
+
cacheRead: 1,
|
|
38394
|
+
cacheWrite: 12.5,
|
|
38395
|
+
longContext: {
|
|
38396
|
+
inputTokenThreshold: 272e3,
|
|
38397
|
+
input: 20,
|
|
38398
|
+
output: 75,
|
|
38399
|
+
cacheRead: 2,
|
|
38400
|
+
cacheWrite: 25
|
|
38401
|
+
}
|
|
38402
|
+
}
|
|
38403
|
+
},
|
|
38404
|
+
// Superseded a week later by 6.1 Sol at the same price with half the
|
|
38405
|
+
// cache-read rate. Chat Completions serves it only with
|
|
38406
|
+
// `reasoning_effort: none`.
|
|
38407
|
+
{
|
|
38408
|
+
model: "gpt-6-sol",
|
|
38409
|
+
id: "gpt-6-sol",
|
|
38410
|
+
name: "GPT 6 Sol",
|
|
38411
|
+
subprocessor: "openai",
|
|
38412
|
+
provider: "openai",
|
|
38413
|
+
active: false,
|
|
38414
|
+
pricing: {
|
|
38415
|
+
input: 2,
|
|
38416
|
+
output: 10,
|
|
38417
|
+
cacheRead: 0.2,
|
|
38418
|
+
cacheWrite: 2.5,
|
|
38419
|
+
longContext: {
|
|
38420
|
+
inputTokenThreshold: 272e3,
|
|
38421
|
+
input: 4,
|
|
38422
|
+
output: 15,
|
|
38423
|
+
cacheRead: 0.4,
|
|
38424
|
+
cacheWrite: 5
|
|
38425
|
+
}
|
|
38426
|
+
}
|
|
38427
|
+
},
|
|
38428
|
+
// The 5.6 line launched 2026-07-09. OpenAI cut Terra 20% and Luna 80% on
|
|
38429
|
+
// 2026-07-30; each row's window holds the launch rate for usage before the cut.
|
|
38430
|
+
{
|
|
38431
|
+
model: "gpt-5.6-terra",
|
|
38432
|
+
id: "gpt-5.6-terra",
|
|
38433
|
+
name: "GPT 5.6 Terra",
|
|
38434
|
+
subprocessor: "openai",
|
|
38435
|
+
provider: "openai",
|
|
38436
|
+
active: false,
|
|
38437
|
+
pricing: {
|
|
38438
|
+
input: 2,
|
|
38439
|
+
output: 12,
|
|
38440
|
+
cacheRead: 0.2,
|
|
38441
|
+
cacheWrite: 2.5,
|
|
38442
|
+
longContext: {
|
|
38443
|
+
inputTokenThreshold: 272e3,
|
|
38444
|
+
input: 4,
|
|
38445
|
+
output: 18,
|
|
38446
|
+
cacheRead: 0.4,
|
|
38447
|
+
cacheWrite: 5
|
|
38448
|
+
}
|
|
38449
|
+
},
|
|
38450
|
+
pricingPeriods: [
|
|
38451
|
+
{
|
|
38452
|
+
from: "2026-07-09",
|
|
38453
|
+
through: "2026-07-29",
|
|
38454
|
+
pricing: {
|
|
38455
|
+
input: 2.5,
|
|
38456
|
+
output: 15,
|
|
38457
|
+
cacheRead: 0.25,
|
|
38458
|
+
cacheWrite: 3.125,
|
|
38459
|
+
longContext: {
|
|
38460
|
+
inputTokenThreshold: 272e3,
|
|
38461
|
+
input: 5,
|
|
38462
|
+
output: 22.5,
|
|
38463
|
+
cacheRead: 0.5,
|
|
38464
|
+
cacheWrite: 6.25
|
|
38465
|
+
}
|
|
38466
|
+
}
|
|
38467
|
+
}
|
|
38468
|
+
]
|
|
38469
|
+
},
|
|
38470
|
+
// Sol's $4/$20 promo runs through 2026-11-29; standard rates resume November 30.
|
|
38471
|
+
{
|
|
38472
|
+
model: "gpt-5.6-sol",
|
|
38473
|
+
id: "gpt-5.6-sol",
|
|
38474
|
+
name: "GPT 5.6 Sol",
|
|
38475
|
+
subprocessor: "openai",
|
|
38476
|
+
provider: "openai",
|
|
38477
|
+
active: false,
|
|
38478
|
+
pricing: {
|
|
38479
|
+
input: 5,
|
|
38480
|
+
output: 30,
|
|
38481
|
+
cacheRead: 0.5,
|
|
38482
|
+
cacheWrite: 6.25,
|
|
38483
|
+
longContext: {
|
|
38484
|
+
inputTokenThreshold: 272e3,
|
|
38485
|
+
input: 10,
|
|
38486
|
+
output: 45,
|
|
38487
|
+
cacheRead: 1,
|
|
38488
|
+
cacheWrite: 12.5
|
|
38489
|
+
}
|
|
38490
|
+
},
|
|
38491
|
+
pricingPeriods: [
|
|
38492
|
+
{
|
|
38493
|
+
from: "2026-08-21",
|
|
38494
|
+
through: "2026-11-29",
|
|
38495
|
+
pricing: {
|
|
38496
|
+
input: 4,
|
|
38497
|
+
output: 20,
|
|
38498
|
+
cacheRead: 0.4,
|
|
38499
|
+
cacheWrite: 5,
|
|
38500
|
+
longContext: {
|
|
38501
|
+
inputTokenThreshold: 272e3,
|
|
38502
|
+
input: 8,
|
|
38503
|
+
output: 30,
|
|
38504
|
+
cacheRead: 0.8,
|
|
38505
|
+
cacheWrite: 10
|
|
38506
|
+
}
|
|
38507
|
+
}
|
|
38508
|
+
}
|
|
38509
|
+
]
|
|
38510
|
+
},
|
|
38511
|
+
{
|
|
38512
|
+
model: "gpt-5.6-luna",
|
|
38513
|
+
id: "gpt-5.6-luna",
|
|
38514
|
+
name: "GPT 5.6 Luna",
|
|
38515
|
+
subprocessor: "openai",
|
|
38516
|
+
provider: "openai",
|
|
38517
|
+
active: false,
|
|
38518
|
+
pricing: {
|
|
38519
|
+
input: 0.2,
|
|
38520
|
+
output: 1.2,
|
|
38521
|
+
cacheRead: 0.02,
|
|
38522
|
+
cacheWrite: 0.25,
|
|
38523
|
+
longContext: {
|
|
38524
|
+
inputTokenThreshold: 272e3,
|
|
38525
|
+
input: 0.4,
|
|
38526
|
+
output: 1.8,
|
|
38527
|
+
cacheRead: 0.04,
|
|
38528
|
+
cacheWrite: 0.5
|
|
38529
|
+
}
|
|
38530
|
+
},
|
|
38531
|
+
pricingPeriods: [
|
|
38532
|
+
{
|
|
38533
|
+
from: "2026-07-09",
|
|
38534
|
+
through: "2026-07-29",
|
|
38535
|
+
pricing: {
|
|
38536
|
+
input: 1,
|
|
38537
|
+
output: 6,
|
|
38538
|
+
cacheRead: 0.1,
|
|
38539
|
+
cacheWrite: 1.25,
|
|
38540
|
+
longContext: {
|
|
38541
|
+
inputTokenThreshold: 272e3,
|
|
38542
|
+
input: 2,
|
|
38543
|
+
output: 9,
|
|
38544
|
+
cacheRead: 0.2,
|
|
38545
|
+
cacheWrite: 2.5
|
|
38546
|
+
}
|
|
38547
|
+
}
|
|
38548
|
+
}
|
|
38549
|
+
]
|
|
38550
|
+
},
|
|
38551
|
+
{
|
|
38552
|
+
model: "gpt-5.4",
|
|
38553
|
+
id: "gpt-5.4",
|
|
38554
|
+
name: "GPT 5.4",
|
|
38555
|
+
subprocessor: "openai",
|
|
38556
|
+
provider: "openai",
|
|
38557
|
+
active: false,
|
|
38558
|
+
pricing: {
|
|
38559
|
+
input: 2.5,
|
|
38560
|
+
output: 15,
|
|
38561
|
+
cacheRead: 0.25,
|
|
38562
|
+
cacheWrite: 2.5,
|
|
38563
|
+
longContext: {
|
|
38564
|
+
inputTokenThreshold: 272e3,
|
|
38565
|
+
input: 5,
|
|
38566
|
+
output: 22.5,
|
|
38567
|
+
cacheRead: 0.5,
|
|
38568
|
+
cacheWrite: 5
|
|
38569
|
+
}
|
|
38570
|
+
}
|
|
38571
|
+
},
|
|
38572
|
+
// Shuts down 2027-04-01. OpenAI names gpt-6-sol as the replacement; the
|
|
38573
|
+
// sunset entry should point at gpt-6.1-sol.
|
|
38574
|
+
{
|
|
38575
|
+
model: "gpt-5.3-codex",
|
|
38576
|
+
id: "gpt-5.3-codex",
|
|
38577
|
+
name: "GPT 5.3 Codex",
|
|
38578
|
+
subprocessor: "openai",
|
|
38579
|
+
provider: "openai",
|
|
38580
|
+
active: false,
|
|
38581
|
+
pricing: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 1.75 }
|
|
38582
|
+
},
|
|
38583
|
+
{
|
|
38584
|
+
model: "gpt-5.4-mini",
|
|
38585
|
+
id: "gpt-5.4-mini",
|
|
38586
|
+
name: "GPT 5.4 Mini",
|
|
38587
|
+
subprocessor: "openai",
|
|
38588
|
+
provider: "openai",
|
|
38589
|
+
active: false,
|
|
38590
|
+
pricing: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0.75 }
|
|
38591
|
+
},
|
|
38592
|
+
{
|
|
38593
|
+
model: "gpt-5.2",
|
|
38594
|
+
id: "gpt-5.2",
|
|
38595
|
+
name: "GPT 5.2",
|
|
38596
|
+
subprocessor: "openai",
|
|
38597
|
+
provider: "openai",
|
|
38598
|
+
active: false,
|
|
38599
|
+
pricing: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 1.75 }
|
|
38600
|
+
},
|
|
38601
|
+
{
|
|
38602
|
+
model: "gpt-5-mini",
|
|
38603
|
+
id: "gpt-5-mini",
|
|
38604
|
+
name: "GPT 5 Mini",
|
|
38605
|
+
subprocessor: "openai",
|
|
38606
|
+
provider: "openai",
|
|
38607
|
+
active: false,
|
|
38608
|
+
pricing: { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0.25 }
|
|
38609
|
+
},
|
|
38610
|
+
{
|
|
38611
|
+
model: "gpt-5",
|
|
38612
|
+
id: "gpt-5",
|
|
38613
|
+
name: "GPT 5",
|
|
38614
|
+
subprocessor: "openai",
|
|
38615
|
+
provider: "openai",
|
|
38616
|
+
active: false,
|
|
38617
|
+
pricing: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 1.25 }
|
|
38618
|
+
},
|
|
38619
|
+
// Shuts down 2027-01-14; OpenAI's replacement is gpt-6-luna.
|
|
38620
|
+
{
|
|
38621
|
+
model: "gpt-4.1",
|
|
38622
|
+
id: "gpt-4.1",
|
|
38623
|
+
name: "GPT 4.1",
|
|
38624
|
+
subprocessor: "openai",
|
|
38625
|
+
provider: "openai",
|
|
38626
|
+
active: false,
|
|
38627
|
+
pricing: { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 2 }
|
|
38628
|
+
},
|
|
38629
|
+
// Google, native Gemini. Vertex retired the 2.5 generation on 2026-10-20;
|
|
38630
|
+
// those rows stay to price historical usage, and SUNSET_MODEL_REPLACEMENTS
|
|
38631
|
+
// rewrites persisted names onto 3.8 Flash. Pricing cacheWrite mirrors input —
|
|
38632
|
+
// Vertex has no separate cache-write rate. 3.8/3.7/3.6 Flash bill a half-price
|
|
38633
|
+
// promo through 2026-12-31 (see GEMINI_FLASH_PROMO_PRICING).
|
|
38634
|
+
// Current Google default (see DEFAULT_GOOGLE_MODEL); kept in the dropdown so
|
|
38635
|
+
// the default is a first-class selectable option, not a hidden ID.
|
|
38636
|
+
...bothVertexRegions({
|
|
38637
|
+
model: "gemini-3.8-flash",
|
|
38638
|
+
id: "gemini-3.8-flash",
|
|
38639
|
+
name: "Gemini 3.8 Flash",
|
|
38640
|
+
provider: "google",
|
|
38641
|
+
active: true,
|
|
38642
|
+
pricing: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.5 },
|
|
38643
|
+
pricingPeriods: [
|
|
38644
|
+
{
|
|
38645
|
+
from: "2026-09-02",
|
|
38646
|
+
through: "2026-12-31",
|
|
38647
|
+
pricing: GEMINI_FLASH_PROMO_PRICING
|
|
38648
|
+
}
|
|
38649
|
+
]
|
|
38650
|
+
}),
|
|
38651
|
+
// Google's Gemini 4 line, GA 2026-10-13 on Vertex from both `global` and the
|
|
38652
|
+
// `us` multi-region per Google's model page (not probed by direct call here).
|
|
38653
|
+
// The top Google model, Pro-priced, with no long-context tier. 1M context
|
|
38654
|
+
// shared between input and output, 64K output per request. Rejects
|
|
38655
|
+
// `thinking_budget` (we send none); implicit context caching only, no
|
|
38656
|
+
// explicit caches.
|
|
38657
|
+
...bothVertexRegions({
|
|
38658
|
+
model: "gemini-4-argon",
|
|
38659
|
+
id: "gemini-4-argon",
|
|
38660
|
+
name: "Gemini 4 Argon",
|
|
38661
|
+
provider: "google",
|
|
38662
|
+
active: true,
|
|
38663
|
+
pricing: { input: 4, output: 20, cacheRead: 0.2, cacheWrite: 4 },
|
|
38664
|
+
pricingPeriods: [
|
|
38665
|
+
{
|
|
38666
|
+
from: "2026-10-13",
|
|
38667
|
+
through: "2026-11-30",
|
|
38668
|
+
pricing: { input: 2, output: 10, cacheRead: 0.1, cacheWrite: 2 }
|
|
38669
|
+
}
|
|
38670
|
+
]
|
|
38671
|
+
}),
|
|
38672
|
+
// Superseded by 3.8 Flash (identical pricing, newer); kept addressable for
|
|
38673
|
+
// persisted automations but dropped from the dropdown. Vertex retires it
|
|
38674
|
+
// 2027-01-28.
|
|
38675
|
+
...bothVertexRegions({
|
|
38676
|
+
model: "gemini-3.7-flash",
|
|
38677
|
+
id: "gemini-3.7-flash",
|
|
38678
|
+
name: "Gemini 3.7 Flash",
|
|
38679
|
+
provider: "google",
|
|
38680
|
+
active: false,
|
|
38681
|
+
pricing: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.5 },
|
|
38682
|
+
pricingPeriods: [
|
|
38683
|
+
{
|
|
38684
|
+
from: "2026-08-13",
|
|
38685
|
+
through: "2026-12-31",
|
|
38686
|
+
pricing: GEMINI_FLASH_PROMO_PRICING
|
|
38687
|
+
}
|
|
38688
|
+
]
|
|
38689
|
+
}),
|
|
38690
|
+
// Still the only Pro-branded id, and still preview: Vertex publishes it under
|
|
38691
|
+
// the `-preview` suffix and serves it from the global endpoint only (preview
|
|
38692
|
+
// models are global-only, hence the single route). Switch to a GA ID without
|
|
38693
|
+
// the suffix if Google promotes it. Gemini 4 Argon is the top Google model.
|
|
38694
|
+
{
|
|
38695
|
+
model: "gemini-3.1-pro-preview",
|
|
38696
|
+
id: "gemini-3.1-pro-preview",
|
|
38697
|
+
name: "Gemini 3.1 Pro (Preview)",
|
|
38698
|
+
subprocessor: "vertex-global",
|
|
38699
|
+
provider: "google",
|
|
38700
|
+
active: true,
|
|
38701
|
+
pricing: {
|
|
38702
|
+
input: 2,
|
|
38703
|
+
output: 12,
|
|
38704
|
+
cacheRead: 0.2,
|
|
38705
|
+
cacheWrite: 2,
|
|
38706
|
+
longContext: {
|
|
38707
|
+
inputTokenThreshold: 2e5,
|
|
38708
|
+
input: 4,
|
|
38709
|
+
output: 18,
|
|
38710
|
+
cacheRead: 0.4,
|
|
38711
|
+
cacheWrite: 4
|
|
38712
|
+
}
|
|
38713
|
+
}
|
|
38714
|
+
},
|
|
38715
|
+
// Superseded by 3.7 Flash (identical pricing, newer); kept addressable for
|
|
38716
|
+
// persisted automations but dropped from the dropdown. Vertex retires it
|
|
38717
|
+
// 2026-11-19 (see SUNSET_MODEL_REPLACEMENTS). Google's `us` multi-region allowlist on 3.6 was lifted
|
|
38718
|
+
// 2026-08-18 (Gemini Enterprise release notes), and the `us` endpoint serves
|
|
38719
|
+
// it — verified by direct call.
|
|
38720
|
+
...bothVertexRegions({
|
|
38721
|
+
model: "gemini-3.6-flash",
|
|
38722
|
+
id: "gemini-3.6-flash",
|
|
38723
|
+
name: "Gemini 3.6 Flash",
|
|
38724
|
+
provider: "google",
|
|
38725
|
+
active: false,
|
|
38726
|
+
pricing: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 1.5 },
|
|
38727
|
+
pricingPeriods: [
|
|
38728
|
+
{
|
|
38729
|
+
from: "2026-08-13",
|
|
38730
|
+
through: "2026-12-31",
|
|
38731
|
+
pricing: GEMINI_FLASH_PROMO_PRICING
|
|
38732
|
+
}
|
|
38733
|
+
]
|
|
38734
|
+
}),
|
|
38735
|
+
...bothVertexRegions({
|
|
38736
|
+
model: "gemini-3.5-flash-lite",
|
|
38737
|
+
id: "gemini-3.5-flash-lite",
|
|
38738
|
+
name: "Gemini 3.5 Flash-Lite",
|
|
38739
|
+
provider: "google",
|
|
38740
|
+
active: true,
|
|
38741
|
+
pricing: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.3 }
|
|
38742
|
+
}),
|
|
38743
|
+
// Superseded by 3.6 Flash (same input rate, cheaper output, ~17% fewer
|
|
38744
|
+
// output tokens); kept addressable for persisted automations but dropped
|
|
38745
|
+
// from the dropdown.
|
|
38746
|
+
...bothVertexRegions({
|
|
38747
|
+
model: "gemini-3.5-flash",
|
|
38748
|
+
id: "gemini-3.5-flash",
|
|
38749
|
+
name: "Gemini 3.5 Flash",
|
|
38750
|
+
provider: "google",
|
|
38751
|
+
active: false,
|
|
38752
|
+
pricing: { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 1.5 }
|
|
38753
|
+
}),
|
|
38754
|
+
// Retired by Vertex 2026-10-20 (see SUNSET_MODEL_REPLACEMENTS); kept to price
|
|
38755
|
+
// historical usage. Never served by the `us` multi-region endpoint, hence the
|
|
38756
|
+
// single global route.
|
|
38757
|
+
{
|
|
38758
|
+
model: "gemini-2.5-pro",
|
|
38759
|
+
id: "gemini-2.5-pro",
|
|
38760
|
+
name: "Gemini 2.5 Pro",
|
|
38761
|
+
subprocessor: "vertex-global",
|
|
38762
|
+
provider: "google",
|
|
38763
|
+
active: false,
|
|
38764
|
+
pricing: {
|
|
38765
|
+
input: 1.25,
|
|
38766
|
+
output: 10,
|
|
38767
|
+
cacheRead: 0.125,
|
|
38768
|
+
cacheWrite: 1.25,
|
|
38769
|
+
longContext: {
|
|
38770
|
+
inputTokenThreshold: 2e5,
|
|
38771
|
+
input: 2.5,
|
|
38772
|
+
output: 15,
|
|
38773
|
+
cacheRead: 0.25,
|
|
38774
|
+
cacheWrite: 2.5
|
|
38775
|
+
}
|
|
38776
|
+
}
|
|
38777
|
+
},
|
|
38778
|
+
{
|
|
38779
|
+
model: "gemini-2.5-flash",
|
|
38780
|
+
id: "gemini-2.5-flash",
|
|
38781
|
+
name: "Gemini 2.5 Flash",
|
|
38782
|
+
subprocessor: "vertex-global",
|
|
38783
|
+
provider: "google",
|
|
38784
|
+
active: false,
|
|
38785
|
+
pricing: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0.3 }
|
|
38786
|
+
},
|
|
38787
|
+
/*
|
|
38788
|
+
* Vertex MaaS (Model-as-a-Service). Open/partner models — GLM (ZAI) —
|
|
38789
|
+
* served over Vertex's OpenAI-compatible Chat Completions endpoint, a
|
|
38790
|
+
* different transport from the native Gemini models above (see
|
|
38791
|
+
* `vertexMaasModel` in common-server/src/llm.ts). IDs are the
|
|
38792
|
+
* `<publisher>/<model>-maas` strings Vertex Model Garden lists. Reuse the
|
|
38793
|
+
* same GOOGLE_VERTEX_* service-account creds — no per-model secret — and are
|
|
38794
|
+
* billed as Vertex usage. These models are region-gated: only `global`
|
|
38795
|
+
* serves them — the `us` multi-region endpoint 404s both, verified by
|
|
38796
|
+
* direct call.
|
|
38797
|
+
*
|
|
38798
|
+
* Pricing: these open models expose no prompt-cache discount on Vertex (nor
|
|
38799
|
+
* on Bedrock — only Anthropic and Nova cache there), so cacheRead and
|
|
38800
|
+
* cacheWrite both mirror input: a cache hit costs the same as fresh input.
|
|
38801
|
+
* Rates are each model's standard published rate.
|
|
38802
|
+
*/
|
|
38803
|
+
{
|
|
38804
|
+
model: "glm-5",
|
|
38805
|
+
id: "zai-org/glm-5-maas",
|
|
38806
|
+
name: "GLM 5 (Vertex)",
|
|
38807
|
+
subprocessor: "vertex-global",
|
|
38808
|
+
provider: "vertex-maas",
|
|
38809
|
+
active: true,
|
|
38810
|
+
pricing: { input: 1, output: 3.2, cacheRead: 1, cacheWrite: 1 }
|
|
38811
|
+
},
|
|
38812
|
+
{
|
|
38813
|
+
model: "glm-4.7",
|
|
38814
|
+
id: "zai-org/glm-4.7-maas",
|
|
38815
|
+
name: "GLM 4.7 (Vertex)",
|
|
38816
|
+
subprocessor: "vertex-global",
|
|
38817
|
+
provider: "vertex-maas",
|
|
38818
|
+
active: true,
|
|
38819
|
+
pricing: { input: 0.6, output: 2.2, cacheRead: 0.6, cacheWrite: 0.6 }
|
|
38820
|
+
},
|
|
38821
|
+
/*
|
|
38822
|
+
* Amazon Bedrock. IDs are raw Bedrock model strings: `global.*` prefixes are
|
|
38823
|
+
* global cross-region inference profiles (AWS may process in any commercial
|
|
38824
|
+
* region, at the direct-API price), `us.*` are US-only profiles (+10%, kept
|
|
38825
|
+
* for the ids the enclave clusters persisted), and bare `<publisher>.*` IDs
|
|
38826
|
+
* are single-region foundation models. Auth uses the default AWS credential
|
|
38827
|
+
* chain — ECS task role in deploys, AWS_ACCESS_KEY_ID + AWS_REGION env vars
|
|
38828
|
+
* locally.
|
|
38829
|
+
*
|
|
38830
|
+
* Claude first. These rows share `model` with the Anthropic rows so a
|
|
38831
|
+
* cluster can serve every persisted Claude name from Amazon instead:
|
|
38832
|
+
* `claude-sonnet-4-6` resolves to the Bedrock row wherever
|
|
38833
|
+
* LLM_SUBPROCESSOR_PREFERENCE puts `bedrock` first (see
|
|
38834
|
+
* common-server/src/aiSubprocessors.ts). They are `active: false` because
|
|
38835
|
+
* the dropdown already offers each model once, under its Anthropic-named
|
|
38836
|
+
* row, and the router picks the host. Claude on Bedrock dispatches through
|
|
38837
|
+
* the SDK's native Messages API entry point (common-server/src/llm.ts), so
|
|
38838
|
+
* the same `anthropic.cacheControl` breakpoints and provider options apply
|
|
38839
|
+
* as on the direct route, and pricing — base and cache multipliers — matches
|
|
38840
|
+
* Anthropic's on `global.*` profiles.
|
|
38841
|
+
*/
|
|
38842
|
+
// The 5.5 generation, priced at the direct rates: Anthropic's Bedrock page
|
|
38843
|
+
// states `global.*` profiles carry no premium (AWS's per-token table renders
|
|
38844
|
+
// client-side and was not read). Unlike Haiku 4.5's, these ids carry no date
|
|
38845
|
+
// or `-v1:0` suffix.
|
|
38846
|
+
{
|
|
38847
|
+
model: "claude-sonnet-5-5",
|
|
38848
|
+
id: "global.anthropic.claude-sonnet-5-5",
|
|
38849
|
+
name: "Claude Sonnet 5.5 (Bedrock)",
|
|
38850
|
+
subprocessor: "bedrock",
|
|
38851
|
+
provider: "bedrock",
|
|
38852
|
+
active: false,
|
|
38853
|
+
pricing: { input: 2, output: 10, cacheRead: 0.1, cacheWrite: 2.5 },
|
|
38854
|
+
pricingPeriods: SONNET_5_5_PRICING_PERIODS
|
|
38855
|
+
},
|
|
38856
|
+
{
|
|
38857
|
+
model: "claude-opus-5-5",
|
|
38858
|
+
id: "global.anthropic.claude-opus-5-5",
|
|
38859
|
+
name: "Claude Opus 5.5 (Bedrock)",
|
|
38860
|
+
subprocessor: "bedrock",
|
|
38861
|
+
provider: "bedrock",
|
|
38862
|
+
active: false,
|
|
38863
|
+
pricing: { input: 4, output: 20, cacheRead: 0.2, cacheWrite: 5 }
|
|
38864
|
+
},
|
|
38865
|
+
{
|
|
38866
|
+
model: "claude-fable-5-1",
|
|
38867
|
+
id: "global.anthropic.claude-fable-5-1",
|
|
38868
|
+
name: "Claude Fable 5.1 (Bedrock)",
|
|
38869
|
+
subprocessor: "bedrock",
|
|
38870
|
+
provider: "bedrock",
|
|
38871
|
+
active: false,
|
|
38872
|
+
pricing: { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 },
|
|
38873
|
+
providerOptionsTransform: stripAnthropicThinking
|
|
38874
|
+
},
|
|
38875
|
+
// AWS lists the >100K tier as a separate "Long Context" line.
|
|
38876
|
+
{
|
|
38877
|
+
model: "claude-haiku-5-5",
|
|
38878
|
+
id: "global.anthropic.claude-haiku-5-5",
|
|
38879
|
+
name: "Claude Haiku 5.5 (Bedrock)",
|
|
38880
|
+
subprocessor: "bedrock",
|
|
38881
|
+
provider: "bedrock",
|
|
38882
|
+
active: false,
|
|
38883
|
+
pricing: HAIKU_5_5_PRICING
|
|
38884
|
+
},
|
|
38885
|
+
{
|
|
38886
|
+
model: "claude-sonnet-4-6",
|
|
38887
|
+
id: "global.anthropic.claude-sonnet-4-6",
|
|
38888
|
+
name: "Claude Sonnet 4.6 (Bedrock)",
|
|
38889
|
+
subprocessor: "bedrock",
|
|
38890
|
+
provider: "bedrock",
|
|
38891
|
+
active: false,
|
|
38892
|
+
pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }
|
|
38893
|
+
},
|
|
38894
|
+
{
|
|
38895
|
+
model: "claude-sonnet-5",
|
|
38896
|
+
id: "global.anthropic.claude-sonnet-5",
|
|
38897
|
+
name: "Claude Sonnet 5 (Bedrock)",
|
|
38898
|
+
subprocessor: "bedrock",
|
|
38899
|
+
provider: "bedrock",
|
|
38900
|
+
active: false,
|
|
38901
|
+
pricing: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }
|
|
38902
|
+
},
|
|
38903
|
+
{
|
|
38904
|
+
model: "claude-opus-5",
|
|
38905
|
+
id: "global.anthropic.claude-opus-5",
|
|
38906
|
+
name: "Claude Opus 5 (Bedrock)",
|
|
38907
|
+
subprocessor: "bedrock",
|
|
38908
|
+
provider: "bedrock",
|
|
38909
|
+
active: false,
|
|
38910
|
+
pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
|
|
38911
|
+
},
|
|
38912
|
+
{
|
|
38913
|
+
model: "claude-fable-5",
|
|
38914
|
+
id: "global.anthropic.claude-fable-5",
|
|
38915
|
+
name: "Claude Fable 5 (Bedrock)",
|
|
38916
|
+
subprocessor: "bedrock",
|
|
38917
|
+
provider: "bedrock",
|
|
38918
|
+
active: false,
|
|
38919
|
+
pricing: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 },
|
|
38920
|
+
providerOptionsTransform: stripAnthropicThinking
|
|
38921
|
+
},
|
|
38922
|
+
{
|
|
38923
|
+
model: "claude-haiku-4-5",
|
|
38924
|
+
id: "global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
38925
|
+
name: "Claude Haiku 4.5 (Bedrock)",
|
|
38926
|
+
subprocessor: "bedrock",
|
|
38927
|
+
provider: "bedrock",
|
|
38928
|
+
active: false,
|
|
38929
|
+
pricing: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }
|
|
38930
|
+
},
|
|
38931
|
+
// Prior-generation rows so a persisted name keeps resolving to the
|
|
38932
|
+
// preferred host rather than quietly staying on the direct route.
|
|
38933
|
+
{
|
|
38934
|
+
model: "claude-opus-4-8",
|
|
38935
|
+
id: "global.anthropic.claude-opus-4-8",
|
|
38936
|
+
name: "Claude Opus 4.8 (Bedrock)",
|
|
38937
|
+
subprocessor: "bedrock",
|
|
38938
|
+
provider: "bedrock",
|
|
38939
|
+
active: false,
|
|
38940
|
+
pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
|
|
38941
|
+
},
|
|
38942
|
+
{
|
|
38943
|
+
model: "claude-opus-4-7",
|
|
38944
|
+
id: "global.anthropic.claude-opus-4-7",
|
|
38945
|
+
name: "Claude Opus 4.7 (Bedrock)",
|
|
38946
|
+
subprocessor: "bedrock",
|
|
38947
|
+
provider: "bedrock",
|
|
38948
|
+
active: false,
|
|
38949
|
+
pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
|
|
38950
|
+
},
|
|
38951
|
+
{
|
|
38952
|
+
model: "claude-opus-4-6",
|
|
38953
|
+
id: "global.anthropic.claude-opus-4-6-v1",
|
|
38954
|
+
name: "Claude Opus 4.6 (Bedrock)",
|
|
38955
|
+
subprocessor: "bedrock",
|
|
38956
|
+
provider: "bedrock",
|
|
38957
|
+
active: false,
|
|
38958
|
+
pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
|
|
38959
|
+
},
|
|
38960
|
+
{
|
|
38961
|
+
model: "claude-sonnet-4-5",
|
|
38962
|
+
id: "global.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
|
38963
|
+
name: "Claude Sonnet 4.5 (Bedrock)",
|
|
38964
|
+
subprocessor: "bedrock",
|
|
38965
|
+
provider: "bedrock",
|
|
38966
|
+
active: false,
|
|
38967
|
+
pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }
|
|
38968
|
+
},
|
|
38969
|
+
// US-only profile, kept under its persisted id: the enclave clusters reach
|
|
38970
|
+
// only Bedrock and their saved resources name this string. Ranked behind the
|
|
38971
|
+
// global row so a model name lands there only where global is unreachable.
|
|
38972
|
+
// AWS bills US-pinned profiles 10% over the direct rate.
|
|
38973
|
+
{
|
|
38974
|
+
model: "claude-sonnet-4-5",
|
|
38975
|
+
id: "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
|
38976
|
+
name: "Claude Sonnet 4.5 (Bedrock \u2014 US)",
|
|
38977
|
+
subprocessor: "bedrock",
|
|
38978
|
+
provider: "bedrock",
|
|
38979
|
+
active: false,
|
|
38980
|
+
pricing: { input: 3.3, output: 16.5, cacheRead: 0.33, cacheWrite: 4.125 }
|
|
38981
|
+
},
|
|
38982
|
+
// Anthropic retired Opus 4.1 on the direct API 2026-08-05; Bedrock still
|
|
38983
|
+
// serves it, so the enclave's persisted id keeps resolving. Priced at the
|
|
38984
|
+
// legacy $15/$75 — the 4.6 reprice never propagated backwards — plus the
|
|
38985
|
+
// US-pinned 10%.
|
|
38986
|
+
{
|
|
38987
|
+
model: "claude-opus-4-1",
|
|
38988
|
+
id: "us.anthropic.claude-opus-4-1-20250805-v1:0",
|
|
38989
|
+
name: "Claude Opus 4.1 (Bedrock \u2014 US)",
|
|
38990
|
+
subprocessor: "bedrock",
|
|
38991
|
+
provider: "bedrock",
|
|
38992
|
+
active: false,
|
|
38993
|
+
pricing: { input: 16.5, output: 82.5, cacheRead: 1.65, cacheWrite: 20.625 }
|
|
38994
|
+
},
|
|
38995
|
+
// No canonical `-vN:M` suffix — that's how AWS lists Moonshot models. Kimi
|
|
38996
|
+
// on Bedrock gets no prompt-cache discount — Bedrock caching is
|
|
38997
|
+
// Anthropic/Nova only — so cacheRead mirrors input, not the input/10 the
|
|
38998
|
+
// Claude rows assume.
|
|
38999
|
+
{
|
|
39000
|
+
model: "kimi-k2.5",
|
|
39001
|
+
id: "moonshotai.kimi-k2.5",
|
|
39002
|
+
name: "Kimi K2.5 (Bedrock)",
|
|
39003
|
+
subprocessor: "bedrock",
|
|
39004
|
+
provider: "bedrock",
|
|
39005
|
+
active: true,
|
|
39006
|
+
pricing: { input: 0.6, output: 3, cacheRead: 0.6, cacheWrite: 0.6 }
|
|
39007
|
+
},
|
|
39008
|
+
{
|
|
39009
|
+
model: "llama4-maverick",
|
|
39010
|
+
id: "us.meta.llama4-maverick-17b-instruct-v1:0",
|
|
39011
|
+
name: "Llama 4 Maverick (Bedrock)",
|
|
39012
|
+
subprocessor: "bedrock",
|
|
39013
|
+
provider: "bedrock",
|
|
39014
|
+
active: true,
|
|
39015
|
+
pricing: { input: 0.24, output: 0.97, cacheRead: 0.024, cacheWrite: 0.24 }
|
|
39016
|
+
},
|
|
39017
|
+
{
|
|
39018
|
+
model: "llama4-scout",
|
|
39019
|
+
id: "us.meta.llama4-scout-17b-instruct-v1:0",
|
|
39020
|
+
name: "Llama 4 Scout (Bedrock)",
|
|
39021
|
+
subprocessor: "bedrock",
|
|
39022
|
+
provider: "bedrock",
|
|
39023
|
+
active: true,
|
|
39024
|
+
pricing: { input: 0.17, output: 0.66, cacheRead: 0.017, cacheWrite: 0.17 }
|
|
39025
|
+
},
|
|
39026
|
+
// Bedrock no longer recognizes this id (ValidationException on invoke); the
|
|
39027
|
+
// row stays to price historical usage and SUNSET_MODEL_REPLACEMENTS rewrites
|
|
39028
|
+
// persisted names onto Pixtral Large, Mistral's successor in the same family.
|
|
39029
|
+
{
|
|
39030
|
+
model: "mistral-large-2",
|
|
39031
|
+
id: "mistral.mistral-large-2407-v1:0",
|
|
39032
|
+
name: "Mistral Large 2 (Bedrock)",
|
|
39033
|
+
subprocessor: "bedrock",
|
|
39034
|
+
provider: "bedrock",
|
|
39035
|
+
active: false,
|
|
39036
|
+
pricing: { input: 3, output: 9, cacheRead: 0.3, cacheWrite: 3 }
|
|
39037
|
+
},
|
|
39038
|
+
{
|
|
39039
|
+
model: "pixtral-large",
|
|
39040
|
+
id: "mistral.pixtral-large-2502-v1:0",
|
|
39041
|
+
name: "Pixtral Large (Bedrock)",
|
|
39042
|
+
subprocessor: "bedrock",
|
|
39043
|
+
provider: "bedrock",
|
|
39044
|
+
active: true,
|
|
39045
|
+
pricing: { input: 2, output: 6, cacheRead: 0.2, cacheWrite: 2 }
|
|
39046
|
+
},
|
|
39047
|
+
/*
|
|
39048
|
+
* Third-party open-weight hosts — Fireworks, Sail (sailresearch.com), and GMI
|
|
39049
|
+
* Cloud (gmicloud.ai) — serving the GLM 5.3 line. One `model` identity, one route
|
|
39050
|
+
* per host: the hosts genuinely price the same weights differently (Sail's Flash
|
|
39051
|
+
* is 30% under the other two), so the route the org enables decides the bill. All
|
|
39052
|
+
* ship OPT-IN (see OPT_IN_SUBPROCESSORS in policy.ts): every organization starts
|
|
39053
|
+
* with them refused and an admin turns one on from the settings page.
|
|
39054
|
+
*
|
|
39055
|
+
* Registered after Bedrock, at the bottom, on purpose: the default-model walk ranks
|
|
39056
|
+
* top down, and an org that manages to enable ONLY these should get them — putting
|
|
39057
|
+
* them ahead of the hosts most clusters default to would let a fail-open bug flip
|
|
39058
|
+
* everyone's architect onto one silently.
|
|
39059
|
+
*
|
|
39060
|
+
* `active: false` for rollout: hidden from pickers while the opt-in/enterprise wiring
|
|
39061
|
+
* settles, still addressable by the Architect staff override (inactive ids resolve
|
|
39062
|
+
* like any other). Freeing them is a one-line release.
|
|
39063
|
+
*
|
|
39064
|
+
* Pricing per each host's published rates. All bill no separate cache-write premium
|
|
39065
|
+
* (cache fill happens in normal input processing), so cacheWrite is 0 rather than
|
|
39066
|
+
* the mirror-input convention the MaaS/Bedrock rows use (that mirrors "no caching
|
|
39067
|
+
* at all"; these hosts have caching, just no write line item). GMI publishes its
|
|
39068
|
+
* rates inline in the /v1/models catalog (probed 2026-09-12) and applies a
|
|
39069
|
+
* discount_to_user on the account — its rates here are the list rows.
|
|
39070
|
+
*
|
|
39071
|
+
* Fireworks is two routes the way Vertex is: `fireworks` global, and the US-only
|
|
39072
|
+
* endpoint (us.api.fireworks.ai) pinned to `fireworks-us` at the documented +50%
|
|
39073
|
+
* premium. Unlike the dual-region Vertex rows these are DIFFERENT ids — the US
|
|
39074
|
+
* endpoint serves `routers/*-us` names — so an org that refuses global fireworks
|
|
39075
|
+
* must name the US id explicitly; there is no same-id region fallback to land in.
|
|
39076
|
+
*
|
|
39077
|
+
* Sail prices the SAME id by completion window (`metadata.completion_window`:
|
|
39078
|
+
* asap/balanced/flex, flex half of asap) — that is a REQUEST parameter, not a host,
|
|
39079
|
+
* so it can't be a route under this registry (pricing keys off id; one id one price,
|
|
39080
|
+
* enforced by the policy spec). Registered at the asap row's rates; wiring windows
|
|
39081
|
+
* for a lazy lane later means per-request billing, not new routes. Sail is
|
|
39082
|
+
* zero-data-retention by default, SOC 2 / HIPAA, and case-sensitive on model ids —
|
|
39083
|
+
* routes register the lowercase form (what modelFromName dispatches) and the sail
|
|
39084
|
+
* transport restores the canonical wire case (see SAIL_WIRE_IDS in llm.ts).
|
|
39085
|
+
*
|
|
39086
|
+
* Sail is ALSO two routes the way Fireworks is: `sail` global, and `sail-us`, which
|
|
39087
|
+
* pins US residency with a per-request `routing.allowed_countries: ["US"]` flag at
|
|
39088
|
+
* the documented +20% premium. One gateway serves both, so the US rows take
|
|
39089
|
+
* sail-us- prefixed ids (same one-id-one-price constraint as the completion windows)
|
|
39090
|
+
* and the transport strips the prefix and injects the flag.
|
|
39091
|
+
*
|
|
39092
|
+
* GMI is case-sensitive the same way (a lowercase id 400s "No matching target
|
|
39093
|
+
* server found"), and its native ids collide with Sail's (`zai-org/GLM-5.3-Flash`
|
|
39094
|
+
* serves on BOTH hosts) — so gmi routes take gmi- prefixed ids and the transport
|
|
39095
|
+
* restores the wire case (GMI_WIRE_IDS in llm.ts). It also silently TRUNCATES an
|
|
39096
|
+
* over-context prompt by default; the transport overrides that to error. GMI has
|
|
39097
|
+
* no US-only endpoint, so no residency row; and it publishes no zero-retention /
|
|
39098
|
+
* no-training commitment for the shared serverless product — production clusters
|
|
39099
|
+
* don't declare it (LLM_SUBPROCESSORS) until that ships in a DPA.
|
|
39100
|
+
*
|
|
39101
|
+
* GLM-5.3 is NOT on Vertex MaaS (probed 2026-09-12: both `zai-org/glm-5.3-maas`
|
|
39102
|
+
* and a flash variant 404 while `zai-org/glm-5-maas` still serves), and MaaS/Bedrock
|
|
39103
|
+
* expose no prompt-cache discount for open weights anyway — the reason these hosts
|
|
39104
|
+
* exist as a fourth home for the weights.
|
|
39105
|
+
*/
|
|
39106
|
+
{
|
|
39107
|
+
model: "glm-5.3-flash",
|
|
39108
|
+
id: "accounts/fireworks/models/glm-5p3-flash",
|
|
39109
|
+
name: "GLM 5.3 Flash (Fireworks)",
|
|
39110
|
+
subprocessor: "fireworks",
|
|
39111
|
+
provider: "fireworks",
|
|
39112
|
+
active: false,
|
|
39113
|
+
pricing: { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }
|
|
39114
|
+
},
|
|
39115
|
+
{
|
|
39116
|
+
model: "glm-5.3-flash",
|
|
39117
|
+
id: "accounts/fireworks/routers/glm-5p3-flash-us",
|
|
39118
|
+
name: "GLM 5.3 Flash (Fireworks US)",
|
|
39119
|
+
subprocessor: "fireworks-us",
|
|
39120
|
+
provider: "fireworks",
|
|
39121
|
+
active: false,
|
|
39122
|
+
pricing: { input: 0.225, output: 0.75, cacheRead: 0.045, cacheWrite: 0 }
|
|
39123
|
+
},
|
|
39124
|
+
{
|
|
39125
|
+
model: "glm-5.3-flash",
|
|
39126
|
+
id: "zai-org/glm-5.3-flash",
|
|
39127
|
+
name: "GLM 5.3 Flash (Sail)",
|
|
39128
|
+
subprocessor: "sail",
|
|
39129
|
+
provider: "sail",
|
|
39130
|
+
active: false,
|
|
39131
|
+
pricing: { input: 0.105, output: 0.35, cacheRead: 0.021, cacheWrite: 0 }
|
|
39132
|
+
},
|
|
39133
|
+
{
|
|
39134
|
+
model: "glm-5.3-flash",
|
|
39135
|
+
id: "sail-us-zai-org/glm-5.3-flash",
|
|
39136
|
+
name: "GLM 5.3 Flash (Sail \u2014 US)",
|
|
39137
|
+
subprocessor: "sail-us",
|
|
39138
|
+
provider: "sail",
|
|
39139
|
+
active: false,
|
|
39140
|
+
pricing: { input: 0.126, output: 0.42, cacheRead: 0.0252, cacheWrite: 0 }
|
|
39141
|
+
},
|
|
39142
|
+
{
|
|
39143
|
+
model: "glm-5.3-flash",
|
|
39144
|
+
id: "gmi-glm53flash",
|
|
39145
|
+
name: "GLM 5.3 Flash (GMI Cloud)",
|
|
39146
|
+
subprocessor: "gmi",
|
|
39147
|
+
provider: "gmi",
|
|
39148
|
+
active: false,
|
|
39149
|
+
pricing: { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }
|
|
39150
|
+
},
|
|
39151
|
+
{
|
|
39152
|
+
model: "glm-5.3",
|
|
39153
|
+
id: "accounts/fireworks/models/glm-5p3",
|
|
39154
|
+
name: "GLM 5.3 (Fireworks)",
|
|
39155
|
+
subprocessor: "fireworks",
|
|
39156
|
+
provider: "fireworks",
|
|
39157
|
+
active: false,
|
|
39158
|
+
pricing: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }
|
|
39159
|
+
},
|
|
39160
|
+
{
|
|
39161
|
+
model: "glm-5.3",
|
|
39162
|
+
id: "accounts/fireworks/routers/glm-5p3-us",
|
|
39163
|
+
name: "GLM 5.3 (Fireworks US)",
|
|
39164
|
+
subprocessor: "fireworks-us",
|
|
39165
|
+
provider: "fireworks",
|
|
39166
|
+
active: false,
|
|
39167
|
+
pricing: { input: 2.1, output: 6.6, cacheRead: 0.39, cacheWrite: 0 }
|
|
39168
|
+
},
|
|
39169
|
+
{
|
|
39170
|
+
model: "glm-5.3",
|
|
39171
|
+
id: "zai-org/glm-5.3",
|
|
39172
|
+
name: "GLM 5.3 (Sail)",
|
|
39173
|
+
subprocessor: "sail",
|
|
39174
|
+
provider: "sail",
|
|
39175
|
+
active: false,
|
|
39176
|
+
pricing: { input: 0.98, output: 3.08, cacheRead: 0.182, cacheWrite: 0 }
|
|
39177
|
+
},
|
|
39178
|
+
{
|
|
39179
|
+
model: "glm-5.3",
|
|
39180
|
+
id: "sail-us-zai-org/glm-5.3",
|
|
39181
|
+
name: "GLM 5.3 (Sail \u2014 US)",
|
|
39182
|
+
subprocessor: "sail-us",
|
|
39183
|
+
provider: "sail",
|
|
39184
|
+
active: false,
|
|
39185
|
+
pricing: { input: 1.176, output: 3.696, cacheRead: 0.2184, cacheWrite: 0 }
|
|
39186
|
+
},
|
|
39187
|
+
{
|
|
39188
|
+
model: "glm-5.3",
|
|
39189
|
+
id: "gmi-glm53-744b",
|
|
39190
|
+
name: "GLM 5.3 (GMI Cloud)",
|
|
39191
|
+
subprocessor: "gmi",
|
|
39192
|
+
provider: "gmi",
|
|
39193
|
+
active: false,
|
|
39194
|
+
pricing: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }
|
|
39195
|
+
}
|
|
39196
|
+
];
|
|
39197
|
+
var LLM_MODELS = MODEL_ROUTES.filter(
|
|
39198
|
+
(route, index) => MODEL_ROUTES.findIndex((r) => r.id === route.id) === index
|
|
39199
|
+
).map(({ id, name: name2, provider, active }) => ({ id, name: name2, provider, active }));
|
|
39200
|
+
var ACTIVE_MODEL_IDS = LLM_MODELS.filter((m) => m.active).map((m) => m.id).join(", ");
|
|
38125
39201
|
|
|
38126
39202
|
// ../common/src/agent.ts
|
|
38127
39203
|
var agentVersionConfigSchema = external_exports.object({
|
|
@@ -38141,7 +39217,7 @@ var agentVersionConfigSchema = external_exports.object({
|
|
|
38141
39217
|
});
|
|
38142
39218
|
var defaultAgentVersionConfig = {
|
|
38143
39219
|
systemPrompt: "You are a helpful assistant.",
|
|
38144
|
-
model:
|
|
39220
|
+
model: DEFAULT_MODEL,
|
|
38145
39221
|
temperature: 0.7,
|
|
38146
39222
|
maxTokens: 4096,
|
|
38147
39223
|
maxSteps: 20,
|
|
@@ -43938,11 +45014,6 @@ var reactDefaultTemplate = `function App() {
|
|
|
43938
45014
|
var setSearchParamPayloadSchema = external_exports.object({
|
|
43939
45015
|
params: external_exports.record(external_exports.string(), external_exports.string().nullable())
|
|
43940
45016
|
});
|
|
43941
|
-
var graphqlRequestPayloadSchema = external_exports.object({
|
|
43942
|
-
document: external_exports.string(),
|
|
43943
|
-
variables: external_exports.record(external_exports.string(), external_exports.unknown()).nullish(),
|
|
43944
|
-
requestId: external_exports.string()
|
|
43945
|
-
});
|
|
43946
45017
|
var llmCompletionPayloadSchema = external_exports.object({
|
|
43947
45018
|
message: external_exports.string(),
|
|
43948
45019
|
systemPrompt: external_exports.string().optional(),
|
|
@@ -44955,6 +46026,7 @@ var NodeEnum = /* @__PURE__ */ ((NodeEnum2) => {
|
|
|
44955
46026
|
NodeEnum2["apsApiRequest"] = "APS_API_REQUEST";
|
|
44956
46027
|
NodeEnum2["armisAction"] = "ARMIS_ACTION";
|
|
44957
46028
|
NodeEnum2["attributeChanged"] = "ATTRIBUTE_CHANGED";
|
|
46029
|
+
NodeEnum2["awsAthenaRunQuery"] = "AWS_ATHENA_RUN_QUERY";
|
|
44958
46030
|
NodeEnum2["awsS3GetObject"] = "AWS_S3_GET_OBJECT";
|
|
44959
46031
|
NodeEnum2["awsS3ListObjects"] = "AWS_S3_LIST_OBJECTS";
|
|
44960
46032
|
NodeEnum2["awsS3PutObject"] = "AWS_S3_PUT_OBJECT";
|
|
@@ -44997,6 +46069,8 @@ var NodeEnum = /* @__PURE__ */ ((NodeEnum2) => {
|
|
|
44997
46069
|
NodeEnum2["dropboxDownloadFile"] = "DROPBOX_DOWNLOAD_FILE";
|
|
44998
46070
|
NodeEnum2["dropboxListFolder"] = "DROPBOX_LIST_FOLDER";
|
|
44999
46071
|
NodeEnum2["dropboxUploadFile"] = "DROPBOX_UPLOAD_FILE";
|
|
46072
|
+
NodeEnum2["dynamics365Action"] = "DYNAMICS365_ACTION";
|
|
46073
|
+
NodeEnum2["dynamics365Query"] = "DYNAMICS365_QUERY";
|
|
45000
46074
|
NodeEnum2["emailReceived"] = "EMAIL_RECEIVED";
|
|
45001
46075
|
NodeEnum2["entraIdAction"] = "ENTRA_ID_ACTION";
|
|
45002
46076
|
NodeEnum2["error"] = "ERROR";
|
|
@@ -45288,7 +46362,7 @@ var jsonStringSchema = (fieldName) => external_exports.coerce.string().trim().de
|
|
|
45288
46362
|
{ message: `${fieldName} was not valid JSON` }
|
|
45289
46363
|
);
|
|
45290
46364
|
var jsonStringRecordSchema = (fieldName) => jsonStringSchema(fieldName).refine(
|
|
45291
|
-
(v) => external_exports.record(external_exports.string(), external_exports.string()).safeParse(JSON.parse(v)).success,
|
|
46365
|
+
(v) => external_exports.record(external_exports.string(), external_exports.string()).safeParse(resultOfSync(() => JSON.parse(v))[0]).success,
|
|
45292
46366
|
{ message: `${fieldName} should be a JSON object of string values` }
|
|
45293
46367
|
);
|
|
45294
46368
|
var integrationHttpActionRunnableSchema = external_exports.object({
|
|
@@ -60695,7 +61769,9 @@ var printablePageRender = (client, id) => ({
|
|
|
60695
61769
|
inputs: {
|
|
60696
61770
|
printablePageId: id,
|
|
60697
61771
|
searchParams: options?.searchParams ?? "{}",
|
|
60698
|
-
includeDiagnostics: true
|
|
61772
|
+
includeDiagnostics: true,
|
|
61773
|
+
...options?.format == null ? {} : { format: options.format },
|
|
61774
|
+
...options?.scale == null ? {} : { scale: options.scale }
|
|
60699
61775
|
}
|
|
60700
61776
|
}),
|
|
60701
61777
|
signal: AbortSignal.timeout(options?.timeoutMs ?? 6e4)
|
|
@@ -61265,6 +62341,24 @@ var genericResource = (client, id) => {
|
|
|
61265
62341
|
};
|
|
61266
62342
|
|
|
61267
62343
|
// ../sdk/src/runners.ts
|
|
62344
|
+
var runAction = async (client, input2) => {
|
|
62345
|
+
const organizationId = await client.organizationId();
|
|
62346
|
+
const res = await client.fetch(
|
|
62347
|
+
`/v2/actions/${organizationId}/${input2.workspaceId}/run`,
|
|
62348
|
+
{
|
|
62349
|
+
method: "POST",
|
|
62350
|
+
headers: { "Content-Type": "application/json" },
|
|
62351
|
+
body: JSON.stringify({
|
|
62352
|
+
actionId: input2.actionId,
|
|
62353
|
+
inputs: input2.inputs,
|
|
62354
|
+
...input2.actionRunnerId != null ? { actionRunnerId: input2.actionRunnerId } : {}
|
|
62355
|
+
})
|
|
62356
|
+
}
|
|
62357
|
+
);
|
|
62358
|
+
const raw2 = await res.text();
|
|
62359
|
+
if (!res.ok) throw apiError("action run", res, raw2, organizationId);
|
|
62360
|
+
return JSON.parse(raw2);
|
|
62361
|
+
};
|
|
61268
62362
|
var runnerCollection = (client) => ({
|
|
61269
62363
|
/*
|
|
61270
62364
|
* Two steps, same as the webapp: createMachineIdentity mints the identity
|
|
@@ -61323,7 +62417,6 @@ var runnerCollection = (client) => ({
|
|
|
61323
62417
|
});
|
|
61324
62418
|
var runnerResource = (client, id) => {
|
|
61325
62419
|
const enqueueAction = async (actionId, inputs) => {
|
|
61326
|
-
const organizationId = await client.organizationId();
|
|
61327
62420
|
const data = await client.graphql(
|
|
61328
62421
|
`query SdkResolveRunner($id: String!) {
|
|
61329
62422
|
actionRunners(condition: { id: $id }, first: 1) { nodes { workspaceId } }
|
|
@@ -61336,17 +62429,12 @@ var runnerResource = (client, id) => {
|
|
|
61336
62429
|
`Unknown runner ${id} (or it has no workspace). Try: overai runner list`
|
|
61337
62430
|
);
|
|
61338
62431
|
}
|
|
61339
|
-
|
|
61340
|
-
|
|
61341
|
-
|
|
61342
|
-
|
|
61343
|
-
|
|
61344
|
-
|
|
61345
|
-
}
|
|
61346
|
-
);
|
|
61347
|
-
const raw2 = await res.text();
|
|
61348
|
-
if (!res.ok) throw apiError("runner run", res, raw2, organizationId);
|
|
61349
|
-
return JSON.parse(raw2);
|
|
62432
|
+
return runAction(client, {
|
|
62433
|
+
workspaceId,
|
|
62434
|
+
actionId,
|
|
62435
|
+
inputs,
|
|
62436
|
+
actionRunnerId: id
|
|
62437
|
+
});
|
|
61350
62438
|
};
|
|
61351
62439
|
return {
|
|
61352
62440
|
token: async (options) => {
|
|
@@ -61905,11 +62993,12 @@ var OverAIClient = class {
|
|
|
61905
62993
|
* POST /v2/graphql. Throws with the server's error messages — callers (and
|
|
61906
62994
|
* agents driving them) need the actual reason, not a status code.
|
|
61907
62995
|
*/
|
|
61908
|
-
async graphql(query, variables) {
|
|
62996
|
+
async graphql(query, variables, options) {
|
|
61909
62997
|
const res = await this.fetch("/v2/graphql", {
|
|
61910
62998
|
method: "POST",
|
|
61911
62999
|
headers: { "Content-Type": "application/json" },
|
|
61912
|
-
body: JSON.stringify({ query, variables })
|
|
63000
|
+
body: JSON.stringify({ query, variables }),
|
|
63001
|
+
signal: options?.signal
|
|
61913
63002
|
});
|
|
61914
63003
|
const raw2 = await res.text();
|
|
61915
63004
|
const body = (() => {
|
|
@@ -62015,6 +63104,10 @@ var OverAIClient = class {
|
|
|
62015
63104
|
...agentRun(this, id)
|
|
62016
63105
|
};
|
|
62017
63106
|
}
|
|
63107
|
+
/** Completion metadata for one run, independent of its potentially offloaded node state. */
|
|
63108
|
+
automationRun(runId, options) {
|
|
63109
|
+
return automationRun(this, runId, options);
|
|
63110
|
+
}
|
|
62018
63111
|
/** A run addresses no automation, so its state is read by run id alone. */
|
|
62019
63112
|
automationRunState(runId) {
|
|
62020
63113
|
return automationRunState(this, runId);
|
|
@@ -62040,6 +63133,10 @@ var OverAIClient = class {
|
|
|
62040
63133
|
runner(id) {
|
|
62041
63134
|
return runnerResource(this, id);
|
|
62042
63135
|
}
|
|
63136
|
+
/** Runs one automation node's action on a runner, outside any automation. */
|
|
63137
|
+
runAction(input2) {
|
|
63138
|
+
return runAction(this, input2);
|
|
63139
|
+
}
|
|
62043
63140
|
clusterInfo() {
|
|
62044
63141
|
return clusterInfo(this);
|
|
62045
63142
|
}
|
|
@@ -62423,6 +63520,25 @@ var readStdin = async (claimant = "stdin") => {
|
|
|
62423
63520
|
}
|
|
62424
63521
|
return Buffer.concat(chunks).toString("utf8");
|
|
62425
63522
|
};
|
|
63523
|
+
var readInputs = async (args) => {
|
|
63524
|
+
const inputs = {};
|
|
63525
|
+
if (args.includes("-")) {
|
|
63526
|
+
const raw2 = (await readStdin()).trim();
|
|
63527
|
+
const [parsed] = resultOfSync(() => JSON.parse(raw2));
|
|
63528
|
+
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed))
|
|
63529
|
+
throw new Error(`stdin must be a JSON object. Got: ${raw2.slice(0, 120)}`);
|
|
63530
|
+
Object.assign(inputs, parsed);
|
|
63531
|
+
}
|
|
63532
|
+
for (let i = 0; i < args.length; i++) {
|
|
63533
|
+
if (args[i] === "--input") {
|
|
63534
|
+
const pair = args[i + 1] ?? "";
|
|
63535
|
+
const eq = pair.indexOf("=");
|
|
63536
|
+
if (eq <= 0) throw new Error(`--input expects k=v. Got: ${pair}`);
|
|
63537
|
+
inputs[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
63538
|
+
}
|
|
63539
|
+
}
|
|
63540
|
+
return inputs;
|
|
63541
|
+
};
|
|
62426
63542
|
var readValue = async (value, label) => {
|
|
62427
63543
|
if (value?.startsWith("@") !== true) return value;
|
|
62428
63544
|
if (value.startsWith("@@")) return value.slice(1);
|
|
@@ -62928,9 +64044,39 @@ var whoami = (args = []) => {
|
|
|
62928
64044
|
);
|
|
62929
64045
|
};
|
|
62930
64046
|
|
|
64047
|
+
// src/commands/action.ts
|
|
64048
|
+
var USAGE = "Usage: overai action run <workspaceId> <ACTION_ID> [--runner <runnerId>] [--input k=v ... | -]\n";
|
|
64049
|
+
var runAction2 = async (args) => {
|
|
64050
|
+
const [sub, workspaceId, actionId, ...rest] = args;
|
|
64051
|
+
if (sub !== "run" || workspaceId == null || workspaceId.startsWith("-") || actionId == null || actionId.startsWith("-")) {
|
|
64052
|
+
process.stderr.write(USAGE);
|
|
64053
|
+
process.exitCode = 1;
|
|
64054
|
+
return;
|
|
64055
|
+
}
|
|
64056
|
+
const unknown2 = unknownFlags(
|
|
64057
|
+
rest,
|
|
64058
|
+
["--runner", "--input", "-", "-o", "--output"],
|
|
64059
|
+
["--runner", "--input", "-o", "--output"]
|
|
64060
|
+
);
|
|
64061
|
+
if (unknown2.length > 0)
|
|
64062
|
+
throw new Error(
|
|
64063
|
+
`Unknown flag ${unknown2.join(", ")}. See: overai action --help`
|
|
64064
|
+
);
|
|
64065
|
+
const actionRunnerId = flagValue(rest, "--runner");
|
|
64066
|
+
printResult(
|
|
64067
|
+
await cliClient().runAction({
|
|
64068
|
+
workspaceId,
|
|
64069
|
+
actionId,
|
|
64070
|
+
inputs: await readInputs(rest),
|
|
64071
|
+
...actionRunnerId != null ? { actionRunnerId } : {}
|
|
64072
|
+
}),
|
|
64073
|
+
resolveFormat(flagValue(rest, "-o", "--output"))
|
|
64074
|
+
);
|
|
64075
|
+
};
|
|
64076
|
+
|
|
62931
64077
|
// src/commands/agent.ts
|
|
62932
64078
|
import { createInterface } from "readline";
|
|
62933
|
-
var
|
|
64079
|
+
var USAGE2 = [
|
|
62934
64080
|
"Usage:",
|
|
62935
64081
|
" overai agent generate <id> --message <text|@file|@->",
|
|
62936
64082
|
" overai agent tools <id> [--version <n>] [-o json|table|csv]",
|
|
@@ -63032,7 +64178,7 @@ Conversation: ${conversationId}
|
|
|
63032
64178
|
};
|
|
63033
64179
|
var runAgent = async (args) => {
|
|
63034
64180
|
const [operation, id] = args;
|
|
63035
|
-
if (id == null) throw new Error(
|
|
64181
|
+
if (id == null) throw new Error(USAGE2);
|
|
63036
64182
|
switch (operation) {
|
|
63037
64183
|
case "generate":
|
|
63038
64184
|
await generate(args, id);
|
|
@@ -63044,11 +64190,12 @@ var runAgent = async (args) => {
|
|
|
63044
64190
|
await chat(args, id);
|
|
63045
64191
|
return;
|
|
63046
64192
|
default:
|
|
63047
|
-
throw new Error(
|
|
64193
|
+
throw new Error(USAGE2);
|
|
63048
64194
|
}
|
|
63049
64195
|
};
|
|
63050
64196
|
|
|
63051
64197
|
// src/commands/automation.ts
|
|
64198
|
+
import { setTimeout as sleep } from "timers/promises";
|
|
63052
64199
|
var runRuns = async (automationId, args) => {
|
|
63053
64200
|
printResult(
|
|
63054
64201
|
await cliClient().automation(automationId).runs({
|
|
@@ -63067,37 +64214,104 @@ var runState = async (runId, args) => {
|
|
|
63067
64214
|
resolveFormat(flagValue(args, "-o", "--output"))
|
|
63068
64215
|
);
|
|
63069
64216
|
};
|
|
63070
|
-
var runTrigger = async (automationId, args) =>
|
|
63071
|
-
|
|
63072
|
-
|
|
63073
|
-
|
|
63074
|
-
|
|
63075
|
-
|
|
64217
|
+
var runTrigger = async (automationId, args) => cliClient().automation(automationId).run(await readInputs(args));
|
|
64218
|
+
var waitForRun = async (runId, timeoutSeconds, format2) => {
|
|
64219
|
+
process.stderr.write(`Automation run: ${runId}
|
|
64220
|
+
`);
|
|
64221
|
+
const controller = new AbortController();
|
|
64222
|
+
const interrupt = () => {
|
|
64223
|
+
controller.abort(
|
|
64224
|
+
new Error(
|
|
64225
|
+
`Stopped waiting for run ${runId}; the automation was not cancelled.`
|
|
64226
|
+
)
|
|
63076
64227
|
);
|
|
63077
|
-
}
|
|
63078
|
-
|
|
63079
|
-
|
|
63080
|
-
|
|
63081
|
-
|
|
63082
|
-
|
|
64228
|
+
};
|
|
64229
|
+
process.once("SIGINT", interrupt);
|
|
64230
|
+
const stopped = new Promise((_resolve, reject2) => {
|
|
64231
|
+
controller.signal.addEventListener(
|
|
64232
|
+
"abort",
|
|
64233
|
+
() => {
|
|
64234
|
+
reject2(controller.signal.reason);
|
|
64235
|
+
},
|
|
64236
|
+
{ once: true }
|
|
64237
|
+
);
|
|
64238
|
+
});
|
|
64239
|
+
const timeout = setTimeout(() => {
|
|
64240
|
+
controller.abort(
|
|
64241
|
+
new Error(
|
|
64242
|
+
`Timed out waiting for run ${runId} after ${String(timeoutSeconds)}s; the automation was not cancelled.`
|
|
64243
|
+
)
|
|
64244
|
+
);
|
|
64245
|
+
}, timeoutSeconds * 1e3);
|
|
64246
|
+
try {
|
|
64247
|
+
for (; ; ) {
|
|
64248
|
+
const run2 = await Promise.race([
|
|
64249
|
+
cliClient().automationRun(runId, { signal: controller.signal }),
|
|
64250
|
+
stopped
|
|
64251
|
+
]);
|
|
64252
|
+
controller.signal.throwIfAborted();
|
|
64253
|
+
if (run2.status === "cancelled" || run2.endedAt != null) {
|
|
64254
|
+
printResult(run2, format2);
|
|
64255
|
+
if (run2.status !== "ok") process.exitCode = 1;
|
|
64256
|
+
return;
|
|
64257
|
+
}
|
|
64258
|
+
await sleep(1e3, void 0, { signal: controller.signal });
|
|
63083
64259
|
}
|
|
64260
|
+
} catch (error62) {
|
|
64261
|
+
controller.signal.throwIfAborted();
|
|
64262
|
+
throw error62;
|
|
64263
|
+
} finally {
|
|
64264
|
+
clearTimeout(timeout);
|
|
64265
|
+
process.removeListener("SIGINT", interrupt);
|
|
63084
64266
|
}
|
|
63085
|
-
printResult(
|
|
63086
|
-
await cliClient().automation(automationId).run(body),
|
|
63087
|
-
resolveFormat(flagValue(args, "-o", "--output"))
|
|
63088
|
-
);
|
|
63089
64267
|
};
|
|
63090
64268
|
var runAutomation = async (args) => {
|
|
63091
64269
|
const [sub, id, ...rest] = args;
|
|
63092
64270
|
if (sub === "runs" && id != null) return runRuns(id, rest);
|
|
63093
64271
|
if (sub === "state" && id != null) return runState(id, rest);
|
|
63094
|
-
if (sub === "run" && id != null
|
|
64272
|
+
if ((sub === "run" || sub === "wait") && id != null && !id.startsWith("-")) {
|
|
64273
|
+
const unknown2 = unknownFlags(
|
|
64274
|
+
rest,
|
|
64275
|
+
sub === "run" ? ["--input", "-", "--wait", "--timeout", "-o", "--output"] : ["--timeout", "-o", "--output"],
|
|
64276
|
+
["--input", "--timeout", "-o", "--output"]
|
|
64277
|
+
);
|
|
64278
|
+
if (unknown2.length > 0)
|
|
64279
|
+
throw new Error(
|
|
64280
|
+
`Unknown flag ${unknown2.join(", ")}. See: overai automation --help`
|
|
64281
|
+
);
|
|
64282
|
+
const waiting = sub === "wait" || rest.includes("--wait");
|
|
64283
|
+
if (rest.includes("--timeout") && !waiting)
|
|
64284
|
+
throw new Error("--timeout requires --wait when starting a run.");
|
|
64285
|
+
const timeout = integerFlag(rest, "--timeout", 300);
|
|
64286
|
+
if (rest.includes("--timeout") && flagValue(rest, "--timeout") == null || timeout <= 0 || // Larger delays overflow Node's signed 32-bit millisecond timer and fire immediately.
|
|
64287
|
+
timeout > 2147483) {
|
|
64288
|
+
throw new Error(
|
|
64289
|
+
"--timeout must be a whole number of seconds between 1 and 2147483."
|
|
64290
|
+
);
|
|
64291
|
+
}
|
|
64292
|
+
const format2 = resolveFormat(flagValue(rest, "-o", "--output"));
|
|
64293
|
+
if (sub === "wait") return waitForRun(id, timeout, format2);
|
|
64294
|
+
const result = await runTrigger(id, rest);
|
|
64295
|
+
if (!waiting) {
|
|
64296
|
+
printResult(result, format2);
|
|
64297
|
+
return;
|
|
64298
|
+
}
|
|
64299
|
+
if (result.automationRunId == null)
|
|
64300
|
+
throw new Error(
|
|
64301
|
+
"The server returned no automationRunId; cannot wait. Check automation runs before retrying the trigger."
|
|
64302
|
+
);
|
|
64303
|
+
return waitForRun(result.automationRunId, timeout, format2);
|
|
64304
|
+
}
|
|
63095
64305
|
process.stderr.write(
|
|
63096
|
-
"Usage: overai automation runs <automationId> [--limit N] [--failed] [--running]\n overai automation state <runId> [--node <variableId>]\n overai automation run <automationId> [--input k=v ... | -]\n"
|
|
64306
|
+
"Usage: overai automation runs <automationId> [--limit N] [--failed] [--running]\n overai automation state <runId> [--node <variableId>]\n overai automation run <automationId> [--input k=v ... | -] [--wait] [--timeout seconds]\n overai automation wait <runId> [--timeout seconds]\nWait defaults to 300 seconds. Timeout or Ctrl-C stops waiting, not the automation.\n"
|
|
63097
64307
|
);
|
|
63098
64308
|
process.exitCode = 1;
|
|
63099
64309
|
};
|
|
63100
64310
|
|
|
64311
|
+
// src/commands/create.ts
|
|
64312
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
64313
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
64314
|
+
|
|
63101
64315
|
// src/workspace/adapters.ts
|
|
63102
64316
|
var CLONE_DIRS = {
|
|
63103
64317
|
function: "functions",
|
|
@@ -63240,7 +64454,7 @@ var runList = async (args) => {
|
|
|
63240
64454
|
});
|
|
63241
64455
|
printResult(runners, resolveFormat(flagValue(args, "-o", "--output")));
|
|
63242
64456
|
};
|
|
63243
|
-
var
|
|
64457
|
+
var USAGE3 = "Usage: overai runner create <workspaceId> [--name <name>]\n overai runner token <runnerId> [--note <note>]\n overai runner run <runnerId> [--interpreter shell|powershell] --code '<code>'\n overai runner upload <runnerId> --path '<path>'\n overai runner list [workspaceId] [--limit <n>]\n";
|
|
63244
64458
|
var runRunner = async (args) => {
|
|
63245
64459
|
const [sub, id, ...rest] = args;
|
|
63246
64460
|
if (sub === "create" && id != null) return runCreate(id, rest);
|
|
@@ -63248,7 +64462,7 @@ var runRunner = async (args) => {
|
|
|
63248
64462
|
if (sub === "run" && id != null) return runRun(id, rest);
|
|
63249
64463
|
if (sub === "upload" && id != null) return runUpload(id, rest);
|
|
63250
64464
|
if (sub === "list") return runList([id, ...rest].filter((a) => a != null));
|
|
63251
|
-
process.stderr.write(
|
|
64465
|
+
process.stderr.write(USAGE3);
|
|
63252
64466
|
process.exitCode = 1;
|
|
63253
64467
|
};
|
|
63254
64468
|
|
|
@@ -63286,27 +64500,6 @@ var adapterType = {
|
|
|
63286
64500
|
"printable-page": "printablePage",
|
|
63287
64501
|
agent: "agent"
|
|
63288
64502
|
};
|
|
63289
|
-
var addToClone = async (root, manifest, type, id) => {
|
|
63290
|
-
const remote = (await adapterFor(type).fetchAll(manifest.workspaceId)).find(
|
|
63291
|
-
(resource) => resource.id === id
|
|
63292
|
-
);
|
|
63293
|
-
if (remote == null) {
|
|
63294
|
-
throw new Error(
|
|
63295
|
-
`Created ${id}, but could not read it back into the clone.`
|
|
63296
|
-
);
|
|
63297
|
-
}
|
|
63298
|
-
Object.entries(remote.files).forEach(([path, content]) => {
|
|
63299
|
-
writeSynced(root, path, content);
|
|
63300
|
-
});
|
|
63301
|
-
manifest.resources[id] = {
|
|
63302
|
-
type,
|
|
63303
|
-
name: remote.name,
|
|
63304
|
-
files: Object.keys(remote.files),
|
|
63305
|
-
baseVersion: remote.latestVersion,
|
|
63306
|
-
deployedVersion: remote.deployedVersion
|
|
63307
|
-
};
|
|
63308
|
-
writeManifest(root, manifest);
|
|
63309
|
-
};
|
|
63310
64503
|
var runCreate2 = async (args) => {
|
|
63311
64504
|
const rawType = args[0];
|
|
63312
64505
|
if (!CREATE_TYPES.includes(rawType)) {
|
|
@@ -63315,19 +64508,26 @@ var runCreate2 = async (args) => {
|
|
|
63315
64508
|
);
|
|
63316
64509
|
}
|
|
63317
64510
|
const type = rawType;
|
|
64511
|
+
const format2 = resolveFormat(flagValue(args, "-o", "--output"));
|
|
63318
64512
|
const explicitWorkspaceId = flagValue(args, "--workspace");
|
|
63319
64513
|
const clone2 = (() => {
|
|
63320
|
-
if (explicitWorkspaceId != null) return null;
|
|
63321
64514
|
try {
|
|
64515
|
+
if (explicitWorkspaceId != null) {
|
|
64516
|
+
const root = findWorkspaceRoot();
|
|
64517
|
+
const manifest = readManifest(root);
|
|
64518
|
+
if (manifest.workspaceId.toLowerCase() !== explicitWorkspaceId.toLowerCase() || manifest.organizationId !== scopedOrgId() || manifest.apiBaseUrl != null && manifest.apiBaseUrl !== apiBaseUrl())
|
|
64519
|
+
return null;
|
|
64520
|
+
}
|
|
63322
64521
|
return openClone();
|
|
63323
64522
|
} catch (error62) {
|
|
64523
|
+
if (explicitWorkspaceId != null) return null;
|
|
63324
64524
|
if (error62 instanceof Error && error62.message.startsWith("Not inside a cloned workspace")) {
|
|
63325
64525
|
return null;
|
|
63326
64526
|
}
|
|
63327
64527
|
throw error62;
|
|
63328
64528
|
}
|
|
63329
64529
|
})();
|
|
63330
|
-
const workspaceId =
|
|
64530
|
+
const workspaceId = clone2?.manifest.workspaceId ?? explicitWorkspaceId;
|
|
63331
64531
|
if (type !== "workspace" && workspaceId == null) {
|
|
63332
64532
|
throw new Error(
|
|
63333
64533
|
"Pass --workspace <id>, or run the command inside a cloned workspace."
|
|
@@ -63372,18 +64572,64 @@ var runCreate2 = async (args) => {
|
|
|
63372
64572
|
}
|
|
63373
64573
|
return (await createActionRunner(workspaceId, name2)).actionRunnerId;
|
|
63374
64574
|
})();
|
|
64575
|
+
const localFiles = [];
|
|
64576
|
+
const result = {
|
|
64577
|
+
type,
|
|
64578
|
+
id,
|
|
64579
|
+
name: name2,
|
|
64580
|
+
workspaceId: type === "workspace" ? id : workspaceId
|
|
64581
|
+
};
|
|
63375
64582
|
const trackedType = adapterType[type];
|
|
63376
|
-
|
|
63377
|
-
|
|
64583
|
+
try {
|
|
64584
|
+
if (clone2 != null && trackedType != null) {
|
|
64585
|
+
const adapter = adapterFor(trackedType);
|
|
64586
|
+
const head = await adapter.head(id);
|
|
64587
|
+
const files = await adapter.fetchVersion(id, head.latestVersion, name2);
|
|
64588
|
+
Object.keys(files).forEach((path) => {
|
|
64589
|
+
if (existsSync3(join4(clone2.root, path)) || existsSync3(basePath(clone2.root, path))) {
|
|
64590
|
+
throw new Error(`Local file already exists: ${path}`);
|
|
64591
|
+
}
|
|
64592
|
+
});
|
|
64593
|
+
Object.entries(files).forEach(([path, content]) => {
|
|
64594
|
+
const workingPath = join4(clone2.root, path);
|
|
64595
|
+
mkdirSync3(dirname3(workingPath), { recursive: true });
|
|
64596
|
+
writeFileSync3(workingPath, content, { flag: "wx" });
|
|
64597
|
+
localFiles.push(workingPath);
|
|
64598
|
+
const pristinePath = basePath(clone2.root, path);
|
|
64599
|
+
mkdirSync3(dirname3(pristinePath), { recursive: true });
|
|
64600
|
+
writeFileSync3(pristinePath, content, { flag: "wx" });
|
|
64601
|
+
});
|
|
64602
|
+
const manifest = readManifest(clone2.root);
|
|
64603
|
+
manifest.resources[id] = {
|
|
64604
|
+
type: trackedType,
|
|
64605
|
+
name: name2,
|
|
64606
|
+
files: Object.keys(files),
|
|
64607
|
+
baseVersion: head.latestVersion,
|
|
64608
|
+
deployedVersion: head.deployedVersion
|
|
64609
|
+
};
|
|
64610
|
+
writeManifest(clone2.root, manifest);
|
|
64611
|
+
}
|
|
64612
|
+
} catch (error62) {
|
|
64613
|
+
const message = `Created ${id}, but local sync failed. Do not create it again. Preserve any existing local files, then run overai pull in the matching clone to recover (pull also syncs other resources). ${error62 instanceof Error ? error62.message : String(error62)}`;
|
|
64614
|
+
printResult(
|
|
64615
|
+
{
|
|
64616
|
+
...result,
|
|
64617
|
+
localFilesWritten: localFiles.length > 0,
|
|
64618
|
+
localFiles,
|
|
64619
|
+
localSyncError: message
|
|
64620
|
+
},
|
|
64621
|
+
format2
|
|
64622
|
+
);
|
|
64623
|
+
throw new Error(message, { cause: error62 });
|
|
63378
64624
|
}
|
|
63379
64625
|
printResult(
|
|
63380
|
-
{
|
|
63381
|
-
|
|
64626
|
+
{ ...result, localFilesWritten: localFiles.length > 0, localFiles },
|
|
64627
|
+
format2
|
|
63382
64628
|
);
|
|
63383
64629
|
};
|
|
63384
64630
|
|
|
63385
64631
|
// src/commands/dataFile.ts
|
|
63386
|
-
import { openAsBlob, writeFileSync as
|
|
64632
|
+
import { openAsBlob, writeFileSync as writeFileSync4 } from "fs";
|
|
63387
64633
|
var runDataFile = async (args) => {
|
|
63388
64634
|
const [operation, id, path] = args;
|
|
63389
64635
|
if (id == null || !["upload", "download", "head"].includes(operation ?? "")) {
|
|
@@ -63404,7 +64650,7 @@ var runDataFile = async (args) => {
|
|
|
63404
64650
|
}
|
|
63405
64651
|
const response = operation === "head" ? await dataFile.head({ lines: integerFlag(args, "--lines", 50) }) : await dataFile.read();
|
|
63406
64652
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
63407
|
-
if (path != null && path !== "-")
|
|
64653
|
+
if (path != null && path !== "-") writeFileSync4(path, bytes);
|
|
63408
64654
|
else process.stdout.write(bytes);
|
|
63409
64655
|
};
|
|
63410
64656
|
|
|
@@ -63452,18 +64698,18 @@ var runDataStream = async (args) => {
|
|
|
63452
64698
|
import { createHash as createHash3 } from "crypto";
|
|
63453
64699
|
import { watch } from "fs";
|
|
63454
64700
|
import { createServer as createServer2 } from "http";
|
|
63455
|
-
import { dirname as
|
|
64701
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
63456
64702
|
|
|
63457
64703
|
// src/commands/sync.ts
|
|
63458
64704
|
import {
|
|
63459
|
-
existsSync as
|
|
64705
|
+
existsSync as existsSync4,
|
|
63460
64706
|
lstatSync,
|
|
63461
|
-
mkdirSync as
|
|
64707
|
+
mkdirSync as mkdirSync4,
|
|
63462
64708
|
readFileSync as readFileSync5,
|
|
63463
64709
|
unlinkSync,
|
|
63464
|
-
writeFileSync as
|
|
64710
|
+
writeFileSync as writeFileSync5
|
|
63465
64711
|
} from "fs";
|
|
63466
|
-
import { join as
|
|
64712
|
+
import { join as join5, resolve as resolve3 } from "path";
|
|
63467
64713
|
|
|
63468
64714
|
// src/gql.ts
|
|
63469
64715
|
var gqlRequest = async (query, variables) => {
|
|
@@ -63532,39 +64778,39 @@ var runClone = async (args, isShallow = false) => {
|
|
|
63532
64778
|
await getAccessToken();
|
|
63533
64779
|
const workspace = await fetchWorkspace(workspaceId);
|
|
63534
64780
|
const root = resolve3(dirArg ?? slugify3(workspace.name));
|
|
63535
|
-
const cloneMarker =
|
|
63536
|
-
if (
|
|
64781
|
+
const cloneMarker = join5(root, ".overai", "clone-in-progress");
|
|
64782
|
+
if (existsSync4(join5(root, ".overai", "manifest.json"))) {
|
|
63537
64783
|
throw new Error(
|
|
63538
64784
|
`${root} is already a cloned workspace. Use \`overai pull\` to refresh.`
|
|
63539
64785
|
);
|
|
63540
64786
|
}
|
|
63541
|
-
const partialCloneWorkspaceId =
|
|
64787
|
+
const partialCloneWorkspaceId = existsSync4(cloneMarker) ? readFileSync5(cloneMarker, "utf8").trim() : null;
|
|
63542
64788
|
if (partialCloneWorkspaceId != null && partialCloneWorkspaceId !== workspaceId) {
|
|
63543
64789
|
throw new Error(
|
|
63544
64790
|
`${root} contains an incomplete clone of ${partialCloneWorkspaceId}. Retry that workspace or choose another directory.`
|
|
63545
64791
|
);
|
|
63546
64792
|
}
|
|
63547
|
-
if (
|
|
64793
|
+
if (existsSync4(join5(root, "WORKSPACE.md")) && partialCloneWorkspaceId == null) {
|
|
63548
64794
|
throw new Error(`${root} already contains WORKSPACE.md.`);
|
|
63549
64795
|
}
|
|
63550
64796
|
const pending = [{ workspace, root }];
|
|
63551
64797
|
const seen = /* @__PURE__ */ new Set([workspace.id]);
|
|
63552
64798
|
const plan = [];
|
|
63553
64799
|
for (const entry of pending) {
|
|
63554
|
-
const marker =
|
|
63555
|
-
const completed =
|
|
63556
|
-
if (entry.root !== root &&
|
|
64800
|
+
const marker = join5(entry.root, ".overai", "clone-in-progress");
|
|
64801
|
+
const completed = existsSync4(join5(entry.root, ".overai", "manifest.json"));
|
|
64802
|
+
if (entry.root !== root && existsSync4(entry.root)) {
|
|
63557
64803
|
if (lstatSync(entry.root).isSymbolicLink())
|
|
63558
64804
|
throw new Error(`Refusing to clone into symbolic link ${entry.root}.`);
|
|
63559
|
-
const savedId = completed ? readManifest(entry.root).workspaceId :
|
|
64805
|
+
const savedId = completed ? readManifest(entry.root).workspaceId : existsSync4(marker) ? readFileSync5(marker, "utf8").trim() : null;
|
|
63560
64806
|
if (partialCloneWorkspaceId !== workspaceId || savedId !== entry.workspace.id)
|
|
63561
64807
|
throw new Error(
|
|
63562
64808
|
`${entry.root} already exists. Choose another clone directory.`
|
|
63563
64809
|
);
|
|
63564
64810
|
}
|
|
63565
|
-
if (
|
|
64811
|
+
if (existsSync4(join5(entry.root, "workspaces")) && lstatSync(join5(entry.root, "workspaces")).isSymbolicLink())
|
|
63566
64812
|
throw new Error(
|
|
63567
|
-
`Refusing to clone through symbolic link ${
|
|
64813
|
+
`Refusing to clone through symbolic link ${join5(entry.root, "workspaces")}.`
|
|
63568
64814
|
);
|
|
63569
64815
|
if (!completed) {
|
|
63570
64816
|
const resourcesByAdapter = await Promise.all(
|
|
@@ -63593,7 +64839,7 @@ var runClone = async (args, isShallow = false) => {
|
|
|
63593
64839
|
seen.add(child.id);
|
|
63594
64840
|
pending.push({
|
|
63595
64841
|
workspace: child,
|
|
63596
|
-
root:
|
|
64842
|
+
root: join5(
|
|
63597
64843
|
entry.root,
|
|
63598
64844
|
"workspaces",
|
|
63599
64845
|
`${slugify3(child.name)}.${child.id}`
|
|
@@ -63602,14 +64848,14 @@ var runClone = async (args, isShallow = false) => {
|
|
|
63602
64848
|
}
|
|
63603
64849
|
}
|
|
63604
64850
|
for (const entry of plan) {
|
|
63605
|
-
|
|
63606
|
-
|
|
63607
|
-
|
|
64851
|
+
mkdirSync4(join5(entry.root, ".overai"), { recursive: true });
|
|
64852
|
+
writeFileSync5(
|
|
64853
|
+
join5(entry.root, ".overai", "clone-in-progress"),
|
|
63608
64854
|
`${entry.manifest.workspaceId}
|
|
63609
64855
|
`
|
|
63610
64856
|
);
|
|
63611
|
-
|
|
63612
|
-
|
|
64857
|
+
writeFileSync5(
|
|
64858
|
+
join5(entry.root, "WORKSPACE.md"),
|
|
63613
64859
|
entry.description.length === 0 ? "" : `${entry.description.trimEnd()}
|
|
63614
64860
|
`
|
|
63615
64861
|
);
|
|
@@ -63631,7 +64877,7 @@ var runClone = async (args, isShallow = false) => {
|
|
|
63631
64877
|
}
|
|
63632
64878
|
for (const entry of plan.toReversed()) {
|
|
63633
64879
|
writeManifest(entry.root, entry.manifest);
|
|
63634
|
-
unlinkSync(
|
|
64880
|
+
unlinkSync(join5(entry.root, ".overai", "clone-in-progress"));
|
|
63635
64881
|
}
|
|
63636
64882
|
process.stdout.write(
|
|
63637
64883
|
`
|
|
@@ -63752,7 +64998,7 @@ var runPull = async (clone2) => {
|
|
|
63752
64998
|
continue;
|
|
63753
64999
|
}
|
|
63754
65000
|
if (clone2 != null && Object.keys(remote.files).some(
|
|
63755
|
-
(path) => !resource.files.includes(path) &&
|
|
65001
|
+
(path) => !resource.files.includes(path) && existsSync4(join5(root, path))
|
|
63756
65002
|
)) {
|
|
63757
65003
|
incomplete = true;
|
|
63758
65004
|
process.stdout.write(
|
|
@@ -63773,7 +65019,7 @@ var runPull = async (clone2) => {
|
|
|
63773
65019
|
}
|
|
63774
65020
|
for (const remote of remotes) {
|
|
63775
65021
|
if (manifest.resources[remote.id] != null) continue;
|
|
63776
|
-
if (clone2 != null && Object.keys(remote.files).some((path) =>
|
|
65022
|
+
if (clone2 != null && Object.keys(remote.files).some((path) => existsSync4(join5(root, path)))) {
|
|
63777
65023
|
incomplete = true;
|
|
63778
65024
|
process.stdout.write(
|
|
63779
65025
|
`CONFLICT ${remote.name}: destination files already exist. Kept local.
|
|
@@ -64030,7 +65276,7 @@ var runDev = async (args) => {
|
|
|
64030
65276
|
}, 100);
|
|
64031
65277
|
};
|
|
64032
65278
|
const watchedDirs = [
|
|
64033
|
-
...new Set(resource.files.map((f) =>
|
|
65279
|
+
...new Set(resource.files.map((f) => join6(root, dirname4(f))))
|
|
64034
65280
|
];
|
|
64035
65281
|
watchedDirs.forEach((dir) => watch(dir, notifyChange));
|
|
64036
65282
|
const server = createServer2((req, res) => {
|
|
@@ -64228,13 +65474,13 @@ var runGraphql = async (args) => {
|
|
|
64228
65474
|
};
|
|
64229
65475
|
|
|
64230
65476
|
// src/commands/integration.ts
|
|
64231
|
-
var
|
|
65477
|
+
var USAGE4 = "Usage: overai integration configure <id> --config <json|@file|@-> | integration config <id> | integration secret set <id> <KEY> --value <@file|@-> | integration secret unset <id> <KEY>";
|
|
64232
65478
|
var runIntegration = async (args) => {
|
|
64233
65479
|
const [operation] = args;
|
|
64234
65480
|
if (operation === "secret") {
|
|
64235
65481
|
const [, action, id2, key] = args;
|
|
64236
65482
|
if (action !== "set" && action !== "unset" || id2 == null || key == null || key.startsWith("-")) {
|
|
64237
|
-
throw new Error(
|
|
65483
|
+
throw new Error(USAGE4);
|
|
64238
65484
|
}
|
|
64239
65485
|
const integration2 = cliClient().integration(id2);
|
|
64240
65486
|
if (action === "set") {
|
|
@@ -64263,7 +65509,7 @@ var runIntegration = async (args) => {
|
|
|
64263
65509
|
}
|
|
64264
65510
|
const [, id] = args;
|
|
64265
65511
|
if (id == null || operation !== "configure" && operation !== "config") {
|
|
64266
|
-
throw new Error(
|
|
65512
|
+
throw new Error(USAGE4);
|
|
64267
65513
|
}
|
|
64268
65514
|
const integration = cliClient().integration(id);
|
|
64269
65515
|
if (operation === "configure") {
|
|
@@ -64613,24 +65859,33 @@ var runPrintablePage = async (args) => {
|
|
|
64613
65859
|
const [operation, id] = args;
|
|
64614
65860
|
if (operation !== "render" || id == null)
|
|
64615
65861
|
throw new Error(
|
|
64616
|
-
"Usage: overai printable-page render <id> [--search-params <json|@file>] [--timeout <ms>]"
|
|
65862
|
+
"Usage: overai printable-page render <id> [--search-params <json|@file>] [--format pdf|png|jpeg] [--scale <1-4>] [--timeout <ms>]"
|
|
64617
65863
|
);
|
|
65864
|
+
const rawFormat = flagValue(args, "--format");
|
|
65865
|
+
const format2 = ["pdf", "png", "jpeg"].find((f) => f === rawFormat);
|
|
65866
|
+
if (rawFormat != null && format2 == null)
|
|
65867
|
+
throw new Error("--format must be pdf, png, or jpeg.");
|
|
65868
|
+
const scale = integerFlag(args, "--scale");
|
|
65869
|
+
if (scale != null && (scale < 1 || scale > 4))
|
|
65870
|
+
throw new Error("--scale must be 1 to 4.");
|
|
64618
65871
|
const searchParams = await readValue(flagValue(args, "--search-params"), "--search-params") ?? "{}";
|
|
64619
65872
|
JSON.parse(searchParams);
|
|
64620
65873
|
const body = await cliClient().printablePage(id).render({
|
|
64621
65874
|
searchParams,
|
|
65875
|
+
format: format2,
|
|
65876
|
+
scale,
|
|
64622
65877
|
timeoutMs: integerFlag(args, "--timeout", 6e4)
|
|
64623
65878
|
});
|
|
64624
65879
|
printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
|
|
64625
65880
|
};
|
|
64626
65881
|
|
|
64627
65882
|
// src/commands/recursiveSync.ts
|
|
64628
|
-
import { existsSync as
|
|
64629
|
-
import { join as
|
|
65883
|
+
import { existsSync as existsSync5, lstatSync as lstatSync2, readdirSync } from "fs";
|
|
65884
|
+
import { join as join8, relative } from "path";
|
|
64630
65885
|
|
|
64631
65886
|
// src/commands/versions.ts
|
|
64632
65887
|
import { spawnSync } from "child_process";
|
|
64633
|
-
import { join as
|
|
65888
|
+
import { join as join7 } from "path";
|
|
64634
65889
|
var parseRef = (raw2) => {
|
|
64635
65890
|
if (raw2 === "local" || raw2 === "base") return raw2;
|
|
64636
65891
|
const [ref] = resultOfSync(() => parseVersionRef(raw2));
|
|
@@ -64772,7 +66027,7 @@ var runDiff = async (args, clone2) => {
|
|
|
64772
66027
|
"--no-index",
|
|
64773
66028
|
"--src-prefix=base/",
|
|
64774
66029
|
"--dst-prefix=local/",
|
|
64775
|
-
|
|
66030
|
+
join7(".overai", "base", relPath),
|
|
64776
66031
|
missing ? "/dev/null" : relPath
|
|
64777
66032
|
],
|
|
64778
66033
|
{ stdio: "inherit", cwd: root }
|
|
@@ -64804,15 +66059,15 @@ var runRecursiveSync = async (command2, args) => {
|
|
|
64804
66059
|
const local = /* @__PURE__ */ new Map([[origin.manifest.workspaceId, origin]]);
|
|
64805
66060
|
const folders = [origin];
|
|
64806
66061
|
for (const folder of folders) {
|
|
64807
|
-
const container =
|
|
64808
|
-
if (!
|
|
66062
|
+
const container = join8(folder.root, "workspaces");
|
|
66063
|
+
if (!existsSync5(container)) continue;
|
|
64809
66064
|
if (lstatSync2(container).isSymbolicLink()) throw new Error(`Refusing symbolic link ${container}.`);
|
|
64810
66065
|
for (const name2 of readdirSync(container)) {
|
|
64811
|
-
const root =
|
|
66066
|
+
const root = join8(container, name2);
|
|
64812
66067
|
const stat2 = lstatSync2(root);
|
|
64813
66068
|
if (stat2.isSymbolicLink()) throw new Error(`Refusing symbolic link ${root}.`);
|
|
64814
|
-
if (!stat2.isDirectory() || !
|
|
64815
|
-
if (lstatSync2(
|
|
66069
|
+
if (!stat2.isDirectory() || !existsSync5(join8(root, ".overai/manifest.json"))) continue;
|
|
66070
|
+
if (lstatSync2(join8(root, ".overai")).isSymbolicLink() || lstatSync2(join8(root, ".overai/manifest.json")).isSymbolicLink())
|
|
64816
66071
|
throw new Error(`Refusing linked clone state in ${root}.`);
|
|
64817
66072
|
const manifest = readManifest(root);
|
|
64818
66073
|
if (manifest.organizationId !== origin.manifest.organizationId || local.has(manifest.workspaceId))
|
|
@@ -64835,7 +66090,7 @@ var runRecursiveSync = async (command2, args) => {
|
|
|
64835
66090
|
if (seen.has(child.id) || child.organizationId !== origin.manifest.organizationId)
|
|
64836
66091
|
throw new Error(`Invalid workspace hierarchy at ${child.id}. No workspaces synced.`);
|
|
64837
66092
|
seen.add(child.id);
|
|
64838
|
-
remote.push({ workspace: child, parentId: entry.workspace.id, root: local.get(child.id)?.root ??
|
|
66093
|
+
remote.push({ workspace: child, parentId: entry.workspace.id, root: local.get(child.id)?.root ?? join8(entry.root, "workspaces", `${slugify3(child.name)}.${child.id}`) });
|
|
64839
66094
|
}
|
|
64840
66095
|
}
|
|
64841
66096
|
const failures = [];
|
|
@@ -64862,7 +66117,7 @@ Workspace ${label} (${entry.workspace.id})
|
|
|
64862
66117
|
if (clone2 == null) {
|
|
64863
66118
|
if (entry.parentId != null && !available.has(entry.parentId))
|
|
64864
66119
|
throw new Error("Parent workspace could not be cloned; skipping this child.");
|
|
64865
|
-
if (
|
|
66120
|
+
if (existsSync5(entry.root))
|
|
64866
66121
|
throw new Error("Destination already exists, possibly from an incomplete clone. Local files kept; move the folder aside before retrying.");
|
|
64867
66122
|
await runClone([entry.workspace.id, entry.root], true);
|
|
64868
66123
|
available.add(entry.workspace.id);
|
|
@@ -65043,12 +66298,12 @@ var runRemote = async (args) => {
|
|
|
65043
66298
|
|
|
65044
66299
|
// src/commands/update.ts
|
|
65045
66300
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
65046
|
-
import { existsSync as
|
|
66301
|
+
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
65047
66302
|
import { fileURLToPath } from "url";
|
|
65048
66303
|
var PACKAGE_NAME = "@overaihq/cli";
|
|
65049
66304
|
var packageRootUrl = () => {
|
|
65050
66305
|
for (const up of ["..", "../..", "../../.."]) {
|
|
65051
|
-
if (
|
|
66306
|
+
if (existsSync6(new URL(`${up}/package.json`, import.meta.url))) {
|
|
65052
66307
|
return new URL(`${up}/`, import.meta.url);
|
|
65053
66308
|
}
|
|
65054
66309
|
}
|
|
@@ -65074,7 +66329,7 @@ var detectInstaller = () => {
|
|
|
65074
66329
|
};
|
|
65075
66330
|
var runUpdate = async () => {
|
|
65076
66331
|
const current = cliVersion();
|
|
65077
|
-
if (
|
|
66332
|
+
if (existsSync6(new URL("src", packageRootUrl()))) {
|
|
65078
66333
|
process.stdout.write(
|
|
65079
66334
|
"Development build \u2014 rebuild from the repo instead of updating from npm.\n"
|
|
65080
66335
|
);
|
|
@@ -65101,7 +66356,7 @@ var runUpdate = async () => {
|
|
|
65101
66356
|
const cmp = compareVersions(current, latest);
|
|
65102
66357
|
if (cmp > 0) {
|
|
65103
66358
|
process.stdout.write(
|
|
65104
|
-
`overai ${current} is ahead of latest (${latest}) \u2014 likely
|
|
66359
|
+
`overai ${current} is ahead of latest (${latest}) \u2014 likely an unreleased build; nothing to do.
|
|
65105
66360
|
`
|
|
65106
66361
|
);
|
|
65107
66362
|
return;
|
|
@@ -65743,6 +66998,16 @@ automatic conflict recovery \u2014 incorporate the remote changes and retry.
|
|
|
65743
66998
|
|
|
65744
66999
|
## Organization context
|
|
65745
67000
|
|
|
67001
|
+
\`overai create <type>\` writes the new resource's files when run inside its
|
|
67002
|
+
matching workspace clone, including with an explicit \`--workspace\`. It fetches
|
|
67003
|
+
only that resource and leaves other local edits untouched. Outside a matching
|
|
67004
|
+
clone it creates remotely without creating local files or a clone. The result's
|
|
67005
|
+
\`localFilesWritten\` and \`localFiles\` fields report writes and absolute paths.
|
|
67006
|
+
If local sync fails after creation, the result includes the created id and
|
|
67007
|
+
\`localSyncError\`. Preserve any existing destination files before running
|
|
67008
|
+
\`overai pull\` in the matching clone; pull also syncs other resources. Do not
|
|
67009
|
+
create the resource again.
|
|
67010
|
+
|
|
65746
67011
|
Commands in a clone select its org automatically. Outside a clone, put
|
|
65747
67012
|
--org <ref> before the command (overai --org acme sql ...), or set
|
|
65748
67013
|
OVERAI_ORG_ID for a whole shell. A ref is an org id, a local alias, or
|
|
@@ -65797,6 +67062,14 @@ around a clone-sync mismatch; use the correct workspace folder.
|
|
|
65797
67062
|
- \`overai automation run <id> --input k=v\` starts a real run of the DEPLOYED
|
|
65798
67063
|
version (fire-and-forget, returns automationRunId). Run read-only paths
|
|
65799
67064
|
first; verify before deploying mutating changes.
|
|
67065
|
+
- Add \`--wait --timeout 300\` to start and wait, or use
|
|
67066
|
+
\`overai automation wait <runId> --timeout 300\` for an existing run.
|
|
67067
|
+
Waiting defaults to 300 seconds and returns completion metadata, not node
|
|
67068
|
+
outputs. The run ID prints to stderr immediately; the final summary prints
|
|
67069
|
+
to stdout. Failure, cancellation, and timeout exit nonzero. Timeout or Ctrl-C
|
|
67070
|
+
stops waiting without cancelling the automation. An in-progress credential
|
|
67071
|
+
refresh may finish before the CLI exits. Use \`state\` separately
|
|
67072
|
+
for best-effort node outputs.
|
|
65800
67073
|
- Console logs from a page are visible in the webapp editor.
|
|
65801
67074
|
|
|
65802
67075
|
## SQL access
|
|
@@ -65814,6 +67087,10 @@ around a clone-sync mismatch; use the correct workspace folder.
|
|
|
65814
67087
|
supplied and permitted by organization policy.
|
|
65815
67088
|
- Give each service its own credential. List, rotate, or revoke it with
|
|
65816
67089
|
\`overai sql credential list|rotate|revoke\`.
|
|
67090
|
+
- A database outside OverAI (e.g. a customer's SQL Server behind their
|
|
67091
|
+
self-hosted runner) is reached through its node's action, not \`sql\`:
|
|
67092
|
+
\`overai action run <workspaceId> MS_SQL_DATABASE_TRANSACTION_REMOTE --runner <runnerId> -\`
|
|
67093
|
+
with the node's inputs as a JSON object on stdin.
|
|
65817
67094
|
|
|
65818
67095
|
## From a script
|
|
65819
67096
|
|
|
@@ -66068,7 +67345,8 @@ A node is "runnable" (can be executed) when ALL of these conditions are met:
|
|
|
66068
67345
|
1. **Debug mode is enabled** - Users must enable debug mode to run nodes step-by-step
|
|
66069
67346
|
2. **Parent resolution** - One of the following must be true:
|
|
66070
67347
|
- The node has NO parents (unconnected nodes can always run in debug mode)
|
|
66071
|
-
- ALL parent nodes have executed and resolved to the
|
|
67348
|
+
- ALL parent nodes have executed and resolved to the handle that connects to this node
|
|
67349
|
+
- For an **ALWAYS** node: ALL parent nodes have finished, whatever the outcome (success, failure, errored, or skipped), and at least one of them was not skipped
|
|
66072
67350
|
3. **Loop context** (if applicable) - If the node is inside a loop:
|
|
66073
67351
|
- The loop node must be in "loop" state (actively iterating)
|
|
66074
67352
|
- The loop completes when it reaches maxIterations or exhausts items
|
|
@@ -66081,6 +67359,15 @@ Nodes connect via "handles" which determine execution flow:
|
|
|
66081
67359
|
|
|
66082
67360
|
When a parent executes, it resolves to one of these handles. Child nodes only become runnable when their parent resolves to the handle they're connected to.
|
|
66083
67361
|
|
|
67362
|
+
### Skipped Nodes
|
|
67363
|
+
In a deployed run, every node ends in one of: success, failure, errored, or skipped. Skipped is derived from the parents' outcomes wherever state is shown, never recorded, so it appears in run history and while stepping in debug mode: once you run one lane of an IF, the other lane reads as skipped and an ALWAYS after the IF becomes runnable.
|
|
67364
|
+
- A node is **skipped** as soon as a parent makes it unreachable: the parent finished as skipped, or finished on a different handle than the one connecting to this node. An **errored** parent skips all its children except an ALWAYS, because no handle is named errored.
|
|
67365
|
+
- Skips propagate: a skipped node's children are skipped in turn, down to the end of the lane.
|
|
67366
|
+
- **ALWAYS is the join.** It runs once every parent has finished \u2014 succeeded, failed, errored, or skipped \u2014 and at least one of them ran, so an ALWAYS fed by both lanes of an IF runs after the taken lane finishes.
|
|
67367
|
+
- An ALWAYS whose every parent was skipped sits inside an untaken lane: it is skipped too, and the skip keeps propagating through it.
|
|
67368
|
+
- A parent connected through a loop's **loop** handle never causes a skip, and an ALWAYS entered from the loop counts that as a parent that ran. Inside a loop, each iteration applies these rules on its own.
|
|
67369
|
+
- Skipped nodes do not make a run errored. A run with skipped nodes and no errored nodes succeeds.
|
|
67370
|
+
|
|
66084
67371
|
### Special Node Types
|
|
66085
67372
|
- **Event nodes** (timer, webhook, emailReceived, fileUpload): Can always run if debug mode is on. These require a payload to simulate the trigger \u2014 see "Simulating Event Nodes" below.
|
|
66086
67373
|
- **Loop nodes** (loopArray, loopRange): Execute iteratively, maintaining "loop" state until complete, then always resolve to the **success** handle \u2014 even if some or all iterations errored. A failed iteration does not stop the loop or take a failure path. To react to per-iteration failures, handle errors on the nodes inside the loop, or inspect \`iterations\`. (If any node errored, the run is still marked errored overall, but the loop's success handle still runs.)
|
|
@@ -66125,9 +67412,13 @@ var automationsDoc = {
|
|
|
66125
67412
|
id: "automations",
|
|
66126
67413
|
summary: "Automations overview: node model, IF vs legacy IF_ELSE, debugging, webhook/email/run endpoints, SEND_EMAIL, code nodes, Excel input, elements graph rules.",
|
|
66127
67414
|
body: `
|
|
67415
|
+
## Error alerts
|
|
67416
|
+
|
|
67417
|
+
When configuring alerts through GraphQL, \`emailRecipients\` is an object: \`{"recipients": ["alerts@example.com"]}\`, not a bare list. Omit \`recipients\` or use an empty array to send no email. Entries must be strings; additional object fields are preserved.
|
|
67418
|
+
|
|
66128
67419
|
## Working with Automations
|
|
66129
67420
|
|
|
66130
|
-
Automations are step-by-step workflows. Automations are initiated by a trigger (timer, email, webhook, file upload) and then proceed to run additional steps or nodes such as \`TYPESCRIPT_CODE\`, \`IF\`, \`SEND_EMAIL\`, \`PARSE_EXCEL\`, \`GENERATE_OBJECT\`, \`GENERATE_TEXT\`. An automation node will run once all of its parent nodes have resolved. Control flow is done through \`LOOP_ARRAY\` and \`LOOP_RANGE\` nodes along with \`IF\`, \`ERROR\`, and \`ALWAYS\`. The \`ALWAYS\` node helps to bring different branches of an \`IF\` node back together. To branch on a condition use the \`IF\` node \u2014 its only input is \`expression\`, a Liquid predicate that renders \`true\` or \`false\` (e.g. \`{{ S1.result.count > 0 }}\`). The \`IF_ELSE\` node is legacy and deprecated: never add it, and replace any existing \`IF_ELSE\` node with an \`IF\` node.
|
|
67421
|
+
Automations are step-by-step workflows. Automations are initiated by a trigger (timer, email, webhook, file upload) and then proceed to run additional steps or nodes such as \`TYPESCRIPT_CODE\`, \`IF\`, \`SEND_EMAIL\`, \`PARSE_EXCEL\`, \`GENERATE_OBJECT\`, \`GENERATE_TEXT\`. An automation node will run once all of its parent nodes have resolved. Control flow is done through \`LOOP_ARRAY\` and \`LOOP_RANGE\` nodes along with \`IF\`, \`ERROR\`, and \`ALWAYS\`. The \`ALWAYS\` node helps to bring different branches of an \`IF\` node back together. The untaken branch of an \`IF\` reads as skipped, and \`ALWAYS\` runs once every parent has finished or been skipped and at least one of them ran; an \`ALWAYS\` whose every parent was skipped is skipped too. To branch on a condition use the \`IF\` node \u2014 its only input is \`expression\`, a Liquid predicate that renders \`true\` or \`false\` (e.g. \`{{ S1.result.count > 0 }}\`). The \`IF_ELSE\` node is legacy and deprecated: never add it, and replace any existing \`IF_ELSE\` node with an \`IF\` node.
|
|
66131
67422
|
|
|
66132
67423
|
Besides full runs, an automation can be worked on piece by piece:
|
|
66133
67424
|
- simulate the trigger event in debug mode (same trigger-specific inputs as a full run \u2014 e.g. \`fileUrl\`, \`method\`/\`body\` \u2014 but it only seeds the EVENT node, without starting a run),
|
|
@@ -66147,6 +67438,14 @@ Important nodes:
|
|
|
66147
67438
|
- \`SEND_EMAIL\` sends an email from \`noreply@overai.com\` without needing a 3rd party integration. Inside an automation always use this node rather than sending from a \`TYPESCRIPT_CODE\` node \u2014 it is visible on the canvas, configurable without reading code, and re-runnable on its own in debug. Outside an automation (a Function), send with \`env.EMAIL.send(...)\`.
|
|
66148
67439
|
- \`TYPESCRIPT_CODE\` runs a TypeScript module in a Deno sandbox. Use \`export default async function step(state: StepState, ctx: StepContext, env: Env) { \u2026 }\`; the return value is the node output. Annotate every parameter you declare \u2014 module code is checked with noImplicitAny, so an unannotated one is an error. Read upstream outputs with \`await state.get("S1")\` (fetched on first read, cached for that node's execution; \`undefined\` for a skipped step; rejects for an id not visible from the node) \u2014 \`state.S1\` does not exist. Keep each code node small and focused \u2014 when the logic grows, break it across multiple nodes and let the automation handle orchestration rather than writing one large block.
|
|
66149
67440
|
|
|
67441
|
+
## Querying Amazon Athena
|
|
67442
|
+
|
|
67443
|
+
Use \`AWS_ATHENA_RUN_QUERY\` with an existing AWS integration (credentials and region). Set database/workgroup on the action; catalog defaults to \`AwsDataCatalog\` and workgroup to \`primary\`. Leave the S3 results location empty to use workgroup storage, including managed results. Enforced workgroup settings take precedence. Grant Athena query/status/results/cancel permissions plus catalog, source and results access (and KMS/Lake Formation where applicable).
|
|
67444
|
+
|
|
67445
|
+
The action accepts one SQL statement, including writes allowed by AWS permissions. Liquid interpolation is not parameter binding; never interpolate untrusted text into SQL. Results are \`rowData\` arrays aligned with \`columns\`; cells remain strings or null. CSV mode streams to OverAI storage and returns \`fileUrl\`, with \`rowData: null\`; it includes headers and writes null as an empty field. Both modes return column metadata, \`queryId\`, \`bytesScanned\` and \`truncated\`.
|
|
67446
|
+
|
|
67447
|
+
Row limit defaults to 0 (unlimited) and applies only to returned rows, not scanned data. Check \`truncated\` before treating output as complete. Inline output is capped at 150 MiB of serialized rows; use CSV for larger results. Set SQL filters/partitions and workgroup scan limits to control costs. The default 60-second timeout covers submission/execution, not download. Cancellation is attempted on timeout or runner abort, but is not guaranteed and does not roll back writes. Re-running a write can repeat it. Customer-hosted runners need a version that includes this action.
|
|
67448
|
+
|
|
66150
67449
|
## Excel inside automations
|
|
66151
67450
|
|
|
66152
67451
|
When an automation needs to read an uploaded \`.xlsx\`/\`.xls\` workbook at runtime (e.g. a \`fileUpload\` event), prefer the \`parseExcel\` node over writing TypeScript. It pulls every sheet in one shot and avoids re-deriving brittle parsing code each run.
|
|
@@ -66495,13 +67794,13 @@ Generate text or structured objects using LLMs:
|
|
|
66495
67794
|
// Generate text. Functions always use non-streaming under the hood, so
|
|
66496
67795
|
// invalid-PDF / prompt-too-long / rate-limit errors throw with a classified
|
|
66497
67796
|
// message instead of returning an empty string.
|
|
66498
|
-
const text = await env.AI.generateText("Summarize this document", { system: "You are a helpful assistant", model: "claude-sonnet-
|
|
67797
|
+
const text = await env.AI.generateText("Summarize this document", { system: "You are a helpful assistant", model: "claude-sonnet-5-5" });
|
|
66499
67798
|
|
|
66500
67799
|
// Generate structured object
|
|
66501
67800
|
const result = await env.AI.generateObject(
|
|
66502
67801
|
"Extract the key information",
|
|
66503
67802
|
{ type: "object", properties: { title: { type: "string" }, summary: { type: "string" } } },
|
|
66504
|
-
{ model: "claude-sonnet-
|
|
67803
|
+
{ model: "claude-sonnet-5-5" }
|
|
66505
67804
|
);
|
|
66506
67805
|
|
|
66507
67806
|
// With file attachments \u2014 pass Blobs of images or PDFs alongside the prompt
|
|
@@ -66522,7 +67821,9 @@ const transcript = await env.AI.speechToText(fileUrl, { language: "en" });
|
|
|
66522
67821
|
|
|
66523
67822
|
**Attachment types:** \`image/png\`, \`image/jpeg\`, \`image/gif\`, \`image/webp\`, \`application/pdf\`. The Blob's \`type\` is forwarded as the mediaType \u2014 make sure it's set (e.g. when constructing via \`new Blob([buf], { type: "image/png" })\`).
|
|
66524
67823
|
|
|
66525
|
-
**
|
|
67824
|
+
**Output budgets:** Pass \`maxOutputTokens\` in the options for \`env.AI.generateText\` or \`env.AI.generateObject\` to set a positive integer output limit. Omitted means 16,000 tokens per model call, including each web-search step; this is not a total workflow budget. Provider/model limits still apply, and reasoning tokens can consume the budget. Larger budgets allow longer answers and greater spend. Truncated structured output fails with an error: increase the budget within the model's limit or request a smaller result.
|
|
67825
|
+
|
|
67826
|
+
**generateObject schema limit:** Anthropic models reject schemas with more than 16 nullable or union-typed fields. Prefer non-nullable fields, split into multiple calls, or switch model to ${LARGE_SCHEMA_MODELS.map((model) => `\`${model}\``).join(" or ")} for larger schemas. Same applies to the agent \`generateObject\` below.
|
|
66526
67827
|
|
|
66527
67828
|
## Agent Access
|
|
66528
67829
|
|
|
@@ -66686,6 +67987,8 @@ Each version has a timeout (ms, default 30000) and memory limit (MB, default 512
|
|
|
66686
67987
|
|
|
66687
67988
|
## Error alerts
|
|
66688
67989
|
|
|
67990
|
+
When configuring alerts through GraphQL, \`emailRecipients\` is an object: \`{"recipients": ["alerts@example.com"]}\`, not a bare list. Omit \`recipients\` or use an empty array to send no email. Entries must be strings; additional object fields are preserved. Functions allow at most 20 recipients.
|
|
67991
|
+
|
|
66689
67992
|
A function can email recipients when it breaks: the handler throws, times out, or crashes (non-zero exit, output over the size limit, malformed response). A status the handler returns, even a 4xx or 5xx, never alerts \u2014 so catching an error and returning \`new Response(..., { status: 500 })\` silences it. After one alert, later failures send nothing until the cooldown ends (60 minutes by default; 0 sends on every failure). Runs from the function editor never alert, including your \`runFunction\` calls; calls from automations, pages, agents, and HTTP do. The user turns alerts on and picks recipients from the "Alerts" chip in the function's status bar.
|
|
66690
67993
|
`
|
|
66691
67994
|
};
|
|
@@ -66907,7 +68210,7 @@ var platformApiDoc = {
|
|
|
66907
68210
|
|
|
66908
68211
|
OverAI's own data model \u2014 organizations, workspaces, identities, workspace membership and roles (\`workspaceIdentityRole\`), automations, functions, pages, integrations, runs, and more \u2014 is queryable over a **v2 GraphQL API** at \`<api_base_url>/v2/graphql\`. Reach for it whenever a build needs to read or manage the platform itself (e.g. "export every user and their workspace permissions", "list automations that failed today"), not just the user's own tables. It is available anywhere the env SDK runs \u2014 code nodes, functions, and pages.
|
|
66909
68212
|
|
|
66910
|
-
- **From env SDK**: \`env.GRAPHQL.request(query, vars)\`. It authenticates
|
|
68213
|
+
- **From env SDK**: \`env.GRAPHQL.request(query, vars)\`. It authenticates with the running code's own token \u2014 the workspace in code nodes and functions, the page's selected authorization mode (workspace or viewer) in pages \u2014 and is row-level-security scoped: an out-of-scope read returns fewer rows with **no error**. Good for reading the workspace you're in; not for org-wide data.
|
|
66911
68214
|
- **For org-wide / cross-workspace reads**, \`env.GRAPHQL\` is not enough. \`fetch()\` \`<api_base_url>/v2/graphql\` directly with an **org-scoped access token** as \`Authorization: Bearer <token>\`. Keep the token out of code: store it in an HTTP integration and read it with \`env.IN<id>.get()\`. Sandboxed \`fetch()\` sends your headers **verbatim** \u2014 nothing rewrites auth headers, and no action runner is involved (runners are only for endpoints the cloud can't reach, e.g. on-prem).
|
|
66912
68215
|
- It is **v2 PostGraphile**, not the legacy Hasura API: **cursor** pagination (\`first\`/\`after\` + \`pageInfo { hasNextPage endCursor }\`) and connection shapes (\`{ nodes { ... } }\`), never \`limit\`/\`offset\`.
|
|
66913
68216
|
- The schema is large, so **do not guess field names \u2014 introspect on demand** (introspection is enabled). List top-level queries with \`{ __schema { queryType { fields { name } } } }\`; inspect one type with \`{ __type(name: "Workspace") { fields { name type { name kind ofType { name kind } } } } }\`. Introspect the exact type before writing the query.
|
|
@@ -66971,6 +68274,13 @@ requests. That distinguishes "my code is broken" from "my edit isn't deployed
|
|
|
66971
68274
|
yet" \u2014 which otherwise look like the same blank page. A guess about why a render
|
|
66972
68275
|
failed, written down as a conclusion, will mislead every step that follows it.
|
|
66973
68276
|
|
|
68277
|
+
## Rendering to an image
|
|
68278
|
+
|
|
68279
|
+
To get a page as an image (for a document, email, or slide), run the Printable
|
|
68280
|
+
Page to PDF action with the image \`format\`; never rasterize page HTML with
|
|
68281
|
+
html2canvas or similar. The action's input and output descriptions carry
|
|
68282
|
+
formats, scale, and the \`fileUrls\` output.
|
|
68283
|
+
|
|
66974
68284
|
## \`data\` and \`items\` are legacy \u2014 fetch in the page instead
|
|
66975
68285
|
|
|
66976
68286
|
\`data\` (from \`dataSourceUrl\`) and \`items\` (from \`filter\`) are the original way a
|
|
@@ -67351,7 +68661,7 @@ declare global {
|
|
|
67351
68661
|
/** Filenames over 128 characters are shortened in the middle, preserving both ends. */
|
|
67352
68662
|
const uploadFile: (file: File, filename: string, disableRandomPrefix?: boolean) => Promise<string>;
|
|
67353
68663
|
const presignFile: (fileUrl: string, expiresIn?: number) => Promise<string>;
|
|
67354
|
-
const graphqlRequest: (document: string, variables?: Record<string, unknown>) => Promise<
|
|
68664
|
+
const graphqlRequest: (document: string, variables?: Record<string, unknown>) => Promise<unknown>; // POSTs to the v2 API (/v2/graphql) with the page's own token, so it sees what the page's authorization mode grants; Hasura-dialect documents are not accepted. Resolves to { data, errors }.
|
|
67355
68665
|
/** @deprecated Use useLLMText, useLLMObject, or useLLMChat instead. */
|
|
67356
68666
|
const llmCompletion: (message: string, systemPrompt?: string, model?: string) => Promise<Record<string, unknown>>;
|
|
67357
68667
|
const callFunction: (functionId: string, options?: { body?: unknown; method?: string; query?: Record<string, string>; path?: string }) => Promise<Response>;
|
|
@@ -67451,6 +68761,8 @@ If the warning gives a listed function's spelling, use that spelling instead of
|
|
|
67451
68761
|
|
|
67452
68762
|
The \`env\` proxy matches the API available in Functions and Automations \u2014 the same code works in all three.
|
|
67453
68763
|
|
|
68764
|
+
Generic AI calls and hooks (generateText, generateObject, useLLMText, useLLMObject, useLLMChat, and env.AI) accept \`maxOutputTokens\`: a positive integer, default 16,000. It limits each model call, including each web-search step, not the whole conversation. Provider/model limits still apply; reasoning can consume the budget. Larger budgets allow longer answers and greater spend. Truncated structured output fails: increase the budget within the model's limit or request a smaller result. Text/chat keep their existing partial-output behavior.
|
|
68765
|
+
|
|
67454
68766
|
For AI in React components, prefer the reactive hooks (useLLMText, useLLMObject, useLLMChat, useAgentChat) \u2014 they re-render as the response streams in. In event handlers or imperative code, call generateText/generateObject (or env.AI.*) directly.
|
|
67455
68767
|
useAgentChat persists every turn server-side for a signed-in viewer: pass a conversationId to resume a past thread (full transcript, tool calls included, loads automatically), or omit it to start fresh and read the new thread's id off the returned conversationId. useAgentConversations(agentId) backs a history sidebar \u2014 call its refresh() after a first send so the newly created thread appears. listAgentConversations, getAgentConversationMessages, createAgentConversation, renameAgentConversation, and deleteAgentConversation are the imperative equivalents. On a public page none of that persistence exists (see Public pages) \u2014 useAgentChat still streams, holding the transcript in memory.
|
|
67456
68768
|
All AI functions/hooks accept optional File[] attachments for images/PDFs, and webSearch: true to enable web search.
|
|
@@ -67614,6 +68926,7 @@ These populate the \`data\`/\`items\` globals once, at render start, from the ol
|
|
|
67614
68926
|
11. **All visualizations must be responsive.** Never hard-code width or height. Use a \`ResizeObserver\` hook to measure the container and pass width/height to your chart. Wrap every chart in a resizable container sized by CSS grid or flex.
|
|
67615
68927
|
12. **Sanity-check chart math with console.log.** You cannot see the rendered output. When building or debugging visualizations, log intermediate values (scales, domains, ranges, computed positions, angles) and verify they make sense before saving. For example: \`console.log("gauge", { min, max, value, fraction, startAngle, endAngle, valueAngle })\`. Remove logs once the chart is working.
|
|
67616
68928
|
13. **Rebuild imported HTML natively \u2014 never embed it.** When the user brings HTML from somewhere else (an exported dashboard, a design mockup, a page from another tool), recreate it as a native page: an \`App\` component, Tailwind, d3 for charts. Pay close attention to preserving the original styling \u2014 colors, spacing, type scale, layout. Do NOT load a foreign HTML file into a \`srcDoc\` iframe or inject it into the DOM. Embedded HTML is opaque to code outlines and reachable only by blind string patches that silently do nothing when the source drifts \u2014 so every later request turns into guesswork. Port it once and every edit after that is a normal edit. (A Liquid printable page is the exception: Liquid is HTML templating, so imported markup becomes the template body directly.)
|
|
68929
|
+
14. **A PDF, image, or print export of page content is a printable page.** Never rasterize the DOM with html2canvas, dom-to-image, or jsPDF \u2014 they re-implement layout off-screen, so badge text clips, photos stretch, and the result drifts from what the page shows. Move the exportable section into a printable page (read the \`printablePages\` topic) and render it with the Printable Page to PDF action, which also outputs PNG/JPEG for embedding in documents; for a user-facing download, call \`openPrintablePage\`.
|
|
67617
68930
|
|
|
67618
68931
|
## Best Practices
|
|
67619
68932
|
|
|
@@ -67769,8 +69082,18 @@ Archived workspaces are hidden from the workspace tree but are not deleted. Arch
|
|
|
67769
69082
|
|
|
67770
69083
|
Individual resources (pages, automations, functions, tablespaces, integrations, \u2026) can likewise be archived \u2014 there is no hard delete. An archived resource disappears from the side navigation, from all listings and search, but its data is intact \u2014 except an integration's credentials, which archiving deletes, so a restored integration must be reconnected before anything can use it. When the user says a resource is missing or asks where it went, check archived resources before concluding it doesn't exist, and offer to unarchive it. In the UI, archived resources are listed on the Workspace Overview page under the **\u22EF menu \u2192 Show archived resources**, where each row's menu offers **Unarchive**.
|
|
67771
69084
|
|
|
69085
|
+
Workspace managers can rename a workspace by right-clicking its name in the side nav and choosing **Rename**, or by clicking the name at the top of the workspace page.
|
|
69086
|
+
|
|
67772
69087
|
Workspace managers can duplicate an active workspace subtree by right-clicking its name in the side nav. The copy uses deployed resource versions, disables automations, and never copies run history or OAuth tokens. Direct grants, non-OAuth integration credentials, and TableSpace rows default on; managers can omit either set of credentials or choose schema-only TableSpaces. Editors and managers can also right-click one TableSpace to duplicate its schemas and optionally its rows. The modal shows progress for each copy phase and reports only items that unexpectedly failed.
|
|
67773
69088
|
|
|
69089
|
+
On the People page, open a person and click ? beside a workspace to see the direct grant\u2019s creator and creation date, or its parent workspace for inherited access. This is original grant attribution, not necessarily the inviter or the actor behind later role changes. If the record names its recipient as creator, the popover shows only the date; use access history for the recorded source and actor.
|
|
69090
|
+
|
|
69091
|
+
## Access and workspace history
|
|
69092
|
+
|
|
69093
|
+
Organization admins can open a person on the People page and choose **View access history** for their organization and workspace access changes. The People page\u2019s **\u22EF** menu \u2192 **Organization history** shows history across the organization. Workspace managers and organization admins can open the workspace\u2019s **\u22EF** menu \u2192 **Audit history** for its member access, resource, sharing, and parent-workspace changes. **Filters** narrow the history by **Change type**, **Action**, a **From**/**Through** date range, **Person ID**, or **Resource ID**. Related changes share an operation and are grouped together, without exposing other workspaces the viewer cannot manage.
|
|
69094
|
+
|
|
69095
|
+
Entries preserve the actor, source, timestamp, and before/after values. A baseline records existing state when logging begins; it is not proof of earlier roles or an original organization inviter. Unknown attribution stays unknown. History is retained until the organization is deleted. The audit history records access-relevant events only: creation, deletion, workspace moves, sharing, parent links, and access-setting changes. Resource saves and deployments stay in version history.
|
|
69096
|
+
|
|
67774
69097
|
## Public Workspaces
|
|
67775
69098
|
|
|
67776
69099
|
A workspace can be marked **public** (Managers only, by clicking the visibility chip next to the workspace name on the Workspace Overview page). When public, every web page in it is reachable at \`/public/<webPageId>\` without a sign-in \u2014 the visitor's iframe runs against an ephemeral workspace token that can read and write every table space the workspace reaches and call its functions, automations and agents. The visitor is not a member; they just see the page.
|
|
@@ -68305,11 +69628,11 @@ var runSql = async (args) => {
|
|
|
68305
69628
|
};
|
|
68306
69629
|
|
|
68307
69630
|
// src/commands/storage.ts
|
|
68308
|
-
import { openAsBlob as openAsBlob3, writeFileSync as
|
|
68309
|
-
var
|
|
69631
|
+
import { openAsBlob as openAsBlob3, writeFileSync as writeFileSync6 } from "fs";
|
|
69632
|
+
var USAGE5 = "Usage: overai storage upload <path> [--no-random-prefix] | storage download <key> [path|-] | storage exists <key> | storage head <key> [--lines N] | storage presign <key> [--expires-in <seconds>]";
|
|
68310
69633
|
var runStorage = async (args) => {
|
|
68311
69634
|
const [operation, first2, second] = args;
|
|
68312
|
-
if (operation == null) throw new Error(
|
|
69635
|
+
if (operation == null) throw new Error(USAGE5);
|
|
68313
69636
|
const storage = cliClient().storage;
|
|
68314
69637
|
if (operation === "upload") {
|
|
68315
69638
|
if (first2 == null || first2 === "-") {
|
|
@@ -68327,11 +69650,11 @@ var runStorage = async (args) => {
|
|
|
68327
69650
|
`);
|
|
68328
69651
|
return;
|
|
68329
69652
|
}
|
|
68330
|
-
if (first2 == null) throw new Error(
|
|
69653
|
+
if (first2 == null) throw new Error(USAGE5);
|
|
68331
69654
|
if (operation === "download") {
|
|
68332
69655
|
const response = await storage.download(first2);
|
|
68333
69656
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
68334
|
-
if (second != null && second !== "-")
|
|
69657
|
+
if (second != null && second !== "-") writeFileSync6(second, bytes);
|
|
68335
69658
|
else process.stdout.write(bytes);
|
|
68336
69659
|
return;
|
|
68337
69660
|
}
|
|
@@ -68363,7 +69686,7 @@ var runStorage = async (args) => {
|
|
|
68363
69686
|
);
|
|
68364
69687
|
return;
|
|
68365
69688
|
}
|
|
68366
|
-
throw new Error(
|
|
69689
|
+
throw new Error(USAGE5);
|
|
68367
69690
|
};
|
|
68368
69691
|
|
|
68369
69692
|
// src/commands/workspace.ts
|
|
@@ -68493,7 +69816,7 @@ var shareResource = async (args) => {
|
|
|
68493
69816
|
process.stdout.write(`Shared ${what} from ${fromId} into ${to}.
|
|
68494
69817
|
`);
|
|
68495
69818
|
};
|
|
68496
|
-
var
|
|
69819
|
+
var USAGE6 = `Usage:
|
|
68497
69820
|
overai workspace list [--archived] [--limit <n>]
|
|
68498
69821
|
overai workspace show [workspaceId]
|
|
68499
69822
|
overai workspace users [workspaceId]
|
|
@@ -68531,13 +69854,13 @@ var runWorkspace = async (args) => {
|
|
|
68531
69854
|
await shareResource(args.slice(1));
|
|
68532
69855
|
return;
|
|
68533
69856
|
}
|
|
68534
|
-
process.stderr.write(
|
|
69857
|
+
process.stderr.write(USAGE6);
|
|
68535
69858
|
process.exitCode = 1;
|
|
68536
69859
|
};
|
|
68537
69860
|
|
|
68538
69861
|
// src/updateCheck.ts
|
|
68539
69862
|
import { request as httpsRequest } from "https";
|
|
68540
|
-
import { existsSync as
|
|
69863
|
+
import { existsSync as existsSync7 } from "fs";
|
|
68541
69864
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
68542
69865
|
var CHECK_TIMEOUT_MS = 2e3;
|
|
68543
69866
|
var fetchLatestVersion = (signal) => {
|
|
@@ -68578,7 +69901,7 @@ var startUpdateCheck = () => {
|
|
|
68578
69901
|
const controller = new AbortController();
|
|
68579
69902
|
const promise2 = (async () => {
|
|
68580
69903
|
try {
|
|
68581
|
-
if (
|
|
69904
|
+
if (existsSync7(new URL("src", packageRootUrl()))) return null;
|
|
68582
69905
|
const path = fileURLToPath2(import.meta.url);
|
|
68583
69906
|
if (path.includes("_npx") || path.includes("dlx-")) return null;
|
|
68584
69907
|
const body = await fetchLatestVersion(controller.signal);
|
|
@@ -68646,7 +69969,7 @@ Usage:
|
|
|
68646
69969
|
agent, integration, action_runner), or
|
|
68647
69970
|
one resource, into a direct child
|
|
68648
69971
|
overai create <type> [--workspace <id>] [--name <name>]
|
|
68649
|
-
Create a
|
|
69972
|
+
Create a resource; write its files in a matching clone
|
|
68650
69973
|
overai resource show <id> Show metadata for any resource
|
|
68651
69974
|
overai resource update <id> [...] Edit metadata, state, or archive status
|
|
68652
69975
|
overai resource move <id> --to <workspaceId> [--dry-run]
|
|
@@ -68711,7 +70034,9 @@ Workspace sync (edit resources as local files):
|
|
|
68711
70034
|
Automations:
|
|
68712
70035
|
overai automation runs <automationId> [--limit N] [--failed] [--running]
|
|
68713
70036
|
overai automation state <runId> [--node <variableId>]
|
|
68714
|
-
overai automation run <automationId> [--input k=v ... | -]
|
|
70037
|
+
overai automation run <automationId> [--input k=v ... | -] [--wait] [--timeout seconds]
|
|
70038
|
+
overai automation wait <runId> [--timeout seconds]
|
|
70039
|
+
Wait up to 300 seconds by default. Timeout or Ctrl-C stops waiting, not the run.
|
|
68715
70040
|
|
|
68716
70041
|
Other resources:
|
|
68717
70042
|
overai agent generate <agentId> --message <text|@file|@->
|
|
@@ -68734,6 +70059,11 @@ Other resources:
|
|
|
68734
70059
|
overai integration secret unset <id> <KEY>
|
|
68735
70060
|
Remove one credential outright
|
|
68736
70061
|
overai printable-page render <id> [--search-params <json|@file>]
|
|
70062
|
+
[--format pdf|png|jpeg] [--scale <1-4>]
|
|
70063
|
+
Images: one per .page at the configured
|
|
70064
|
+
page size. Images clip at the sheet;
|
|
70065
|
+
the PDF flows overflow onto extra
|
|
70066
|
+
pages. fileUrls lists them all
|
|
68737
70067
|
|
|
68738
70068
|
Self-hosted runners (enabling remote access stays on-device \u2014 not a CLI action):
|
|
68739
70069
|
overai runner create <workspaceId> [--name <name>]
|
|
@@ -68742,6 +70072,13 @@ Self-hosted runners (enabling remote access stays on-device \u2014 not a CLI act
|
|
|
68742
70072
|
overai runner upload <runnerId> --path '<path>'
|
|
68743
70073
|
overai runner list [workspaceId]
|
|
68744
70074
|
|
|
70075
|
+
Actions (one automation node's action, outside any automation):
|
|
70076
|
+
overai action run <workspaceId> <ACTION_ID> [--runner <runnerId>] [--input k=v ... | -]
|
|
70077
|
+
ACTION_ID is a node type, e.g.
|
|
70078
|
+
MS_SQL_DATABASE_TRANSACTION_REMOTE; no
|
|
70079
|
+
--runner uses the org's cloud runner.
|
|
70080
|
+
- reads a JSON object of inputs from stdin
|
|
70081
|
+
|
|
68745
70082
|
Arguments that carry a document \u2014 the graphql query and --variables, the sql
|
|
68746
70083
|
statement, runner --code \u2014 also take @<file> to read it from disk, or @- to read
|
|
68747
70084
|
it from stdin. Prefer that for anything long or quote-heavy: an inline value is
|
|
@@ -69019,6 +70356,9 @@ var run = async () => {
|
|
|
69019
70356
|
case "runner":
|
|
69020
70357
|
await runRunner(rest);
|
|
69021
70358
|
return;
|
|
70359
|
+
case "action":
|
|
70360
|
+
await runAction2(rest);
|
|
70361
|
+
return;
|
|
69022
70362
|
case "update":
|
|
69023
70363
|
case "upgrade":
|
|
69024
70364
|
await runUpdate();
|