@automagik/omni 2.260910.7 → 2.260910.9

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 CHANGED
@@ -34839,6 +34839,37 @@ var init_agent_task = __esm(() => {
34839
34839
  });
34840
34840
  });
34841
34841
 
34842
+ // ../core/src/schemas/agent-usage.ts
34843
+ function agentUsageFromResult(metadata) {
34844
+ const cost = metadata.cost;
34845
+ if (!cost)
34846
+ return null;
34847
+ const parsed = AgentUsageSchema.safeParse({
34848
+ providerId: metadata.providerId,
34849
+ runId: metadata.runId,
34850
+ costUsd: cost.costUsd,
34851
+ tokensIn: cost.inputTokens,
34852
+ tokensOut: cost.outputTokens,
34853
+ model: cost.model
34854
+ });
34855
+ if (!parsed.success)
34856
+ return null;
34857
+ const { providerId: _p, runId: _r, ...fields } = parsed.data;
34858
+ return Object.values(fields).some((v) => v !== undefined) ? parsed.data : null;
34859
+ }
34860
+ var AgentUsageSchema, AGENT_USAGE_METADATA_KEY = "agentUsage";
34861
+ var init_agent_usage = __esm(() => {
34862
+ init_zod();
34863
+ AgentUsageSchema = exports_external.object({
34864
+ providerId: exports_external.string(),
34865
+ runId: exports_external.string(),
34866
+ costUsd: exports_external.number().nonnegative().optional(),
34867
+ tokensIn: exports_external.number().int().nonnegative().optional(),
34868
+ tokensOut: exports_external.number().int().nonnegative().optional(),
34869
+ model: exports_external.string().min(1).optional()
34870
+ });
34871
+ });
34872
+
34842
34873
  // ../core/src/schemas/conversation.ts
34843
34874
  var ConversationSchema, CreateConversationSchema, UpdateConversationSchema;
34844
34875
  var init_conversation = __esm(() => {
@@ -35711,6 +35742,7 @@ var init_schemas = __esm(() => {
35711
35742
  init_agent_route();
35712
35743
  init_agent_state();
35713
35744
  init_agent_task();
35745
+ init_agent_usage();
35714
35746
  init_common();
35715
35747
  init_conversation();
35716
35748
  init_follow_up();
@@ -40165,6 +40197,12 @@ function resolveTemplatePath(path, context) {
40165
40197
  const specialValue = resolveSpecialValue(trimmed, root, rest, context);
40166
40198
  if (specialValue !== undefined)
40167
40199
  return specialValue;
40200
+ if (trimmed === "payload_json")
40201
+ return JSON.stringify(context.payload);
40202
+ if (trimmed === "event_json") {
40203
+ const { id = null, type = null, timestamp = null, metadata = null } = context.event ?? {};
40204
+ return JSON.stringify({ id, type, timestamp, metadata, payload: context.payload });
40205
+ }
40168
40206
  if (root === "payload")
40169
40207
  return rest ? getNestedValue(context.payload, rest) : context.payload;
40170
40208
  if (root === "env")
@@ -42992,7 +43030,8 @@ class AgnoClient {
42992
43030
  metrics: data2.metrics ? {
42993
43031
  inputTokens: data2.metrics.input_tokens ?? 0,
42994
43032
  outputTokens: data2.metrics.output_tokens ?? 0,
42995
- durationMs: data2.metrics.duration ?? 0
43033
+ durationMs: data2.metrics.duration ?? 0,
43034
+ model: data2.model
42996
43035
  } : undefined
42997
43036
  };
42998
43037
  }
@@ -66613,6 +66652,12 @@ Please migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resour
66613
66652
  });
66614
66653
 
66615
66654
  // ../core/src/providers/claude-code-client.ts
66655
+ function extractModel(msg) {
66656
+ const usage = msg.modelUsage;
66657
+ if (!usage || typeof usage !== "object")
66658
+ return;
66659
+ return Object.keys(usage)[0];
66660
+ }
66616
66661
  function getToolPreview(name, input) {
66617
66662
  if (name === "Bash" && input.command)
66618
66663
  return String(input.command).slice(0, 100);
@@ -66825,7 +66870,8 @@ function handleResult2(msg, acc, startTime, currentSessionId) {
66825
66870
  inputTokens: tokens.input,
66826
66871
  outputTokens: tokens.output,
66827
66872
  costUsd: totalCost,
66828
- durationMs
66873
+ durationMs,
66874
+ model: extractModel(msg)
66829
66875
  },
66830
66876
  sessionId: sid2
66831
66877
  };
@@ -66885,6 +66931,7 @@ function processRunMessage(message2, acc, startTime) {
66885
66931
  if (message2.subtype === "success") {
66886
66932
  acc.content = message2.result ?? "";
66887
66933
  acc.costUsd = message2.total_cost_usd ?? 0;
66934
+ acc.model = extractModel(message2);
66888
66935
  const tokens = extractTokens(message2.usage);
66889
66936
  acc.inputTokens = tokens.input;
66890
66937
  acc.outputTokens = tokens.output;
@@ -67092,7 +67139,13 @@ class ClaudeCodeClient {
67092
67139
  runId: crypto.randomUUID(),
67093
67140
  sessionId: acc.sessionId,
67094
67141
  status: "completed",
67095
- metrics: { inputTokens: acc.inputTokens, outputTokens: acc.outputTokens, durationMs }
67142
+ metrics: {
67143
+ inputTokens: acc.inputTokens,
67144
+ outputTokens: acc.outputTokens,
67145
+ durationMs,
67146
+ costUsd: acc.costUsd,
67147
+ model: acc.model
67148
+ }
67096
67149
  };
67097
67150
  }
67098
67151
  streamRun(request, streamConfig, abortSignal) {
@@ -67285,7 +67338,9 @@ class AgnoAgentProvider {
67285
67338
  durationMs,
67286
67339
  cost: response.metrics ? {
67287
67340
  inputTokens: response.metrics.inputTokens,
67288
- outputTokens: response.metrics.outputTokens
67341
+ outputTokens: response.metrics.outputTokens,
67342
+ costUsd: response.metrics.costUsd,
67343
+ model: response.metrics.model
67289
67344
  } : undefined,
67290
67345
  customerErrorBlocked
67291
67346
  }
@@ -67543,7 +67598,12 @@ ${fileList}`;
67543
67598
  runId: response.runId,
67544
67599
  providerId: this.id,
67545
67600
  durationMs,
67546
- cost: response.metrics ? { inputTokens: response.metrics.inputTokens, outputTokens: response.metrics.outputTokens } : undefined
67601
+ cost: response.metrics ? {
67602
+ inputTokens: response.metrics.inputTokens,
67603
+ outputTokens: response.metrics.outputTokens,
67604
+ costUsd: response.metrics.costUsd,
67605
+ model: response.metrics.model
67606
+ } : undefined
67547
67607
  }
67548
67608
  };
67549
67609
  }
@@ -70773,6 +70833,7 @@ __export(exports_src, {
70773
70833
  boundedTenantLabel: () => boundedTenantLabel,
70774
70834
  armSequence: () => armSequence,
70775
70835
  appUptime: () => appUptime,
70836
+ agentUsageFromResult: () => agentUsageFromResult,
70776
70837
  agentStateKey: () => agentStateKey,
70777
70838
  WhatsAppTemplateComponentSchema: () => WhatsAppTemplateComponentSchema,
70778
70839
  WhatsAppFlowSendSchema: () => WhatsAppFlowSendSchema,
@@ -70956,6 +71017,7 @@ __export(exports_src, {
70956
71017
  AutomationEngine: () => AutomationEngine,
70957
71018
  AgnoClient: () => AgnoClient,
70958
71019
  AgnoAgentProvider: () => AgnoAgentProvider,
71020
+ AgentUsageSchema: () => AgentUsageSchema,
70959
71021
  AgentTypeSchema: () => AgentTypeSchema,
70960
71022
  AgentTaskStatusSchema: () => AgentTaskStatusSchema,
70961
71023
  AgentTaskSchema: () => AgentTaskSchema,
@@ -70978,6 +71040,7 @@ __export(exports_src, {
70978
71040
  AUTO_RETRY_DELAYS_MS: () => AUTO_RETRY_DELAYS_MS,
70979
71041
  AUTOMATION_LOG_STATUSES: () => AUTOMATION_LOG_STATUSES,
70980
71042
  AUTOMATION_DEBOUNCE_MODES: () => AUTOMATION_DEBOUNCE_MODES,
71043
+ AGENT_USAGE_METADATA_KEY: () => AGENT_USAGE_METADATA_KEY,
70981
71044
  AGENT_TYPES: () => AGENT_TYPES,
70982
71045
  AGENT_STATE_KV_BUCKET: () => AGENT_STATE_KV_BUCKET,
70983
71046
  ACTION_TYPES: () => ACTION_TYPES,
@@ -74642,7 +74705,7 @@ __export(exports_embedded_canonical_migration, {
74642
74705
  EMBEDDED_PGSERVE_DATA_DIR: () => EMBEDDED_PGSERVE_DATA_DIR
74643
74706
  });
74644
74707
  import { execFileSync as execFileSync3, spawn, spawnSync as spawnSync2 } from "child_process";
74645
- import { existsSync as existsSync10, mkdirSync as mkdirSync7, mkdtempSync, readFileSync as readFileSync8, readdirSync as readdirSync3, symlinkSync as symlinkSync2 } from "fs";
74708
+ import { existsSync as existsSync10, mkdirSync as mkdirSync7, mkdtempSync, readFileSync as readFileSync9, readdirSync as readdirSync3, symlinkSync as symlinkSync2 } from "fs";
74646
74709
  import { createServer } from "net";
74647
74710
  import { arch, homedir as homedir8, platform, tmpdir } from "os";
74648
74711
  import { dirname as dirname2, join as join12 } from "path";
@@ -74668,7 +74731,7 @@ function defaultLog(line) {
74668
74731
  }
74669
74732
  function readDataDirMajor(dataDir) {
74670
74733
  try {
74671
- const major = Number.parseInt(readFileSync8(join12(dataDir, "PG_VERSION"), "utf8").trim(), 10);
74734
+ const major = Number.parseInt(readFileSync9(join12(dataDir, "PG_VERSION"), "utf8").trim(), 10);
74672
74735
  return Number.isFinite(major) ? major : null;
74673
74736
  } catch {
74674
74737
  return null;
@@ -74743,7 +74806,7 @@ function materializeReaderLibs(nativeDir) {
74743
74806
  const libDir = join12(nativeDir, "lib");
74744
74807
  try {
74745
74808
  const pkgRoot = dirname2(nativeDir);
74746
- const pairs = JSON.parse(readFileSync8(join12(nativeDir, "pg-symlinks.json"), "utf8"));
74809
+ const pairs = JSON.parse(readFileSync9(join12(nativeDir, "pg-symlinks.json"), "utf8"));
74747
74810
  for (const { source, target } of pairs) {
74748
74811
  const tgt = join12(pkgRoot, target);
74749
74812
  if (!existsSync10(tgt)) {
@@ -84091,13 +84154,13 @@ var init_postgres_js = __esm(() => {
84091
84154
  });
84092
84155
 
84093
84156
  // ../db/src/client.ts
84094
- import { readFileSync as readFileSync13 } from "fs";
84157
+ import { readFileSync as readFileSync14 } from "fs";
84095
84158
  function resolveSslConfig(caFile, env2 = process.env) {
84096
84159
  const path = caFile || env2.DATABASE_SSL_CA_FILE;
84097
84160
  if (!path) {
84098
84161
  return;
84099
84162
  }
84100
- return { ca: readFileSync13(path, "utf8"), rejectUnauthorized: true };
84163
+ return { ca: readFileSync14(path, "utf8"), rejectUnauthorized: true };
84101
84164
  }
84102
84165
  function getDefaultDatabaseUrl() {
84103
84166
  const url = process.env.DATABASE_URL;
@@ -100593,7 +100656,7 @@ var require_google_genai = __commonJS((exports) => {
100593
100656
  var constants = require_constants7();
100594
100657
  var streaming = require_streaming3();
100595
100658
  var utils$1 = require_utils11();
100596
- function extractModel(params, context) {
100659
+ function extractModel2(params, context) {
100597
100660
  if ("model" in params && typeof params.model === "string") {
100598
100661
  return params.model;
100599
100662
  }
@@ -100637,7 +100700,7 @@ var require_google_genai = __commonJS((exports) => {
100637
100700
  [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.ai.google_genai"
100638
100701
  };
100639
100702
  if (params) {
100640
- attributes[genAiAttributes.GEN_AI_REQUEST_MODEL_ATTRIBUTE] = extractModel(params, context);
100703
+ attributes[genAiAttributes.GEN_AI_REQUEST_MODEL_ATTRIBUTE] = extractModel2(params, context);
100641
100704
  if ("config" in params && typeof params.config === "object" && params.config) {
100642
100705
  const config2 = params.config;
100643
100706
  Object.assign(attributes, extractConfigAttributes(config2));
@@ -100647,7 +100710,7 @@ var require_google_genai = __commonJS((exports) => {
100647
100710
  }
100648
100711
  }
100649
100712
  } else {
100650
- attributes[genAiAttributes.GEN_AI_REQUEST_MODEL_ATTRIBUTE] = extractModel({}, context);
100713
+ attributes[genAiAttributes.GEN_AI_REQUEST_MODEL_ATTRIBUTE] = extractModel2({}, context);
100651
100714
  }
100652
100715
  return attributes;
100653
100716
  }
@@ -100817,7 +100880,7 @@ var require_google_genai = __commonJS((exports) => {
100817
100880
  function instrumentGoogleGenAIClient(client, options3) {
100818
100881
  return createDeepProxy(client, "", utils4.resolveAIRecordingOptions(options3));
100819
100882
  }
100820
- exports.extractModel = extractModel;
100883
+ exports.extractModel = extractModel2;
100821
100884
  exports.instrumentGoogleGenAIClient = instrumentGoogleGenAIClient;
100822
100885
  });
100823
100886
 
@@ -137125,7 +137188,7 @@ import { fileURLToPath } from "url";
137125
137188
  // package.json
137126
137189
  var package_default = {
137127
137190
  name: "@automagik/omni",
137128
- version: "2.260910.7",
137191
+ version: "2.260910.9",
137129
137192
  repository: {
137130
137193
  type: "git",
137131
137194
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -139224,51 +139287,108 @@ one, or the entry named by the global flag:
139224
139287
  }
139225
139288
 
139226
139289
  // src/commands/automations.ts
139290
+ import { readFileSync as readFileSync7 } from "fs";
139227
139291
  init_output();
139292
+ function collectRepeated(value, previous) {
139293
+ return [...previous ?? [], value];
139294
+ }
139228
139295
  function parseJson(json, fieldName) {
139229
139296
  try {
139230
- return { ok: true, value: JSON.parse(json) };
139297
+ return JSON.parse(json);
139231
139298
  } catch {
139232
- return { ok: false, error: `Invalid JSON for ${fieldName}` };
139299
+ throw new Error(`Invalid JSON for ${fieldName}`);
139233
139300
  }
139234
139301
  }
139235
- function buildActionConfig(options) {
139236
- let config2 = {};
139237
- if (options.actionConfig) {
139238
- const result = parseJson(options.actionConfig, "--action-config");
139239
- if (!result.ok)
139240
- return result;
139241
- config2 = result.value;
139242
- }
139243
- if (options.action === "call_agent") {
139244
- if (options.agentId)
139245
- config2.agentId = options.agentId;
139246
- if (options.providerId)
139247
- config2.providerId = options.providerId;
139248
- if (options.responseAs)
139249
- config2.responseAs = options.responseAs;
139250
- if (!config2.agentId) {
139251
- return { ok: false, error: "call_agent action requires --agent-id or agentId in --action-config" };
139252
- }
139253
- }
139254
- return { ok: true, config: config2 };
139255
- }
139256
- function parseConditions(options) {
139257
- let conditions2;
139258
- let logic;
139259
- if (options.condition) {
139260
- const result = parseJson(options.condition, "--condition");
139261
- if (!result.ok)
139262
- return result;
139263
- conditions2 = result.value;
139302
+ function readDefinitionFile(path) {
139303
+ let text;
139304
+ try {
139305
+ text = readFileSync7(path, "utf-8");
139306
+ } catch (err2) {
139307
+ const reason = err2 instanceof Error ? err2.message : "Unknown error";
139308
+ throw new Error(`Cannot read --file '${path}': ${reason}`);
139264
139309
  }
139265
- if (options.conditionLogic) {
139266
- if (options.conditionLogic !== "and" && options.conditionLogic !== "or") {
139267
- return { ok: false, error: '--condition-logic must be "and" or "or"' };
139268
- }
139269
- logic = options.conditionLogic;
139310
+ const parsed = parseJson(text, "--file");
139311
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
139312
+ throw new Error("--file must contain a JSON object");
139313
+ }
139314
+ const readOnly = new Set(["id", "createdAt", "updatedAt", "managedByAgentId"]);
139315
+ const body = Object.fromEntries(Object.entries(parsed).filter(([key, value]) => !readOnly.has(key) && value !== null));
139316
+ return body;
139317
+ }
139318
+ function applyCallAgentShortcuts(config2, options) {
139319
+ if (options.agentId)
139320
+ config2.agentId = options.agentId;
139321
+ if (options.providerId)
139322
+ config2.providerId = options.providerId;
139323
+ if (options.responseAs)
139324
+ config2.responseAs = options.responseAs;
139325
+ }
139326
+ function buildActions(options) {
139327
+ const types8 = options.action ?? [];
139328
+ const configs = options.actionConfig ?? [];
139329
+ if (types8.length === 0) {
139330
+ if (configs.length > 0)
139331
+ throw new Error("--action-config requires a matching --action");
139332
+ return;
139270
139333
  }
139271
- return { ok: true, conditions: conditions2, logic };
139334
+ if (configs.length > types8.length) {
139335
+ throw new Error(`Got ${configs.length} --action-config for ${types8.length} --action`);
139336
+ }
139337
+ const firstCallAgent = types8.indexOf("call_agent");
139338
+ return types8.map((type, i6) => {
139339
+ const raw2 = configs[i6];
139340
+ const config2 = raw2 ? parseJson(raw2, `--action-config #${i6 + 1}`) : {};
139341
+ if (type === "call_agent") {
139342
+ if (i6 === firstCallAgent)
139343
+ applyCallAgentShortcuts(config2, options);
139344
+ if (!config2.agentId) {
139345
+ throw new Error("call_agent action requires --agent-id or agentId in --action-config");
139346
+ }
139347
+ }
139348
+ return { type, config: config2 };
139349
+ });
139350
+ }
139351
+ function parseConditionLogic(logic) {
139352
+ if (logic === undefined)
139353
+ return;
139354
+ if (logic !== "and" && logic !== "or")
139355
+ throw new Error('--condition-logic must be "and" or "or"');
139356
+ return logic;
139357
+ }
139358
+ function buildDefinition(options) {
139359
+ const body = options.file ? readDefinitionFile(options.file) : {};
139360
+ const actions2 = buildActions(options);
139361
+ if (actions2)
139362
+ body.actions = actions2;
139363
+ if (options.name !== undefined)
139364
+ body.name = options.name;
139365
+ if (options.description !== undefined)
139366
+ body.description = options.description;
139367
+ if (options.trigger !== undefined)
139368
+ body.triggerEventType = options.trigger;
139369
+ if (options.condition !== undefined)
139370
+ body.triggerConditions = parseJson(options.condition, "--condition");
139371
+ const logic = parseConditionLogic(options.conditionLogic);
139372
+ if (logic !== undefined)
139373
+ body.conditionLogic = logic;
139374
+ if (options.priority !== undefined)
139375
+ body.priority = options.priority;
139376
+ if (options.transactionalEmissions !== undefined)
139377
+ body.transactionalEmissions = options.transactionalEmissions;
139378
+ return body;
139379
+ }
139380
+ function buildCreateBody(options) {
139381
+ const body = buildDefinition(options);
139382
+ if (!body.name)
139383
+ throw new Error('--name is required (or "name" in --file)');
139384
+ if (!body.triggerEventType)
139385
+ throw new Error('--trigger is required (or "triggerEventType" in --file)');
139386
+ if (!body.actions || body.actions.length === 0) {
139387
+ throw new Error('At least one --action is required (or "actions" in --file)');
139388
+ }
139389
+ if (options.disabled)
139390
+ body.enabled = false;
139391
+ return body;
139272
139392
  }
139273
139393
  function createAutomationsCommand() {
139274
139394
  const automations2 = new Command("automations").description("Manage automations");
@@ -139306,39 +139426,15 @@ function createAutomationsCommand() {
139306
139426
  error(`Failed to get automation: ${message2}`);
139307
139427
  }
139308
139428
  });
139309
- automations2.command("create").description("Create an automation").requiredOption("--name <name>", "Automation name").requiredOption("--trigger <event>", "Trigger event type (e.g., message.received)").requiredOption("--action <type>", "Action type (webhook, send_message, emit_event, log, call_agent)").option("--action-config <json>", "Action config as JSON").option("--condition <json>", "Trigger conditions as JSON array").option("--condition-logic <logic>", 'Condition logic: "and" (all must match) or "or" (any must match)').option("--description <desc>", "Automation description").option("--priority <n>", "Priority (higher = runs first)", (v4) => Number.parseInt(v4, 10)).option("--disabled", "Create in disabled state").option("--transactional-emissions", "Buffer the run's emit_event publishes and flush them in order only when every action succeeded; " + "a failed run publishes zero (#988). Defaults to off (immediate publishing)").option("--agent-id <id>", "Agent ID (for call_agent action)").option("--provider-id <id>", "Provider ID (for call_agent action)").option("--response-as <var>", "Store agent response as variable (for call_agent action)").action(async (options) => {
139429
+ automations2.command("create").description("Create an automation").option("--file <path>", "Full definition as JSON (the `get` output works as-is); explicit flags override it").option("--name <name>", "Automation name").option("--trigger <event>", "Trigger event type (e.g., message.received)").option("--action <type>", "Action type (webhook, send_message, emit_event, log, call_agent); repeat for ordered multi-action", collectRepeated).option("--action-config <json>", "Action config as JSON; the i-th pairs with the i-th --action", collectRepeated).option("--condition <json>", "Trigger conditions as JSON array").option("--condition-logic <logic>", 'Condition logic: "and" (all must match) or "or" (any must match)').option("--description <desc>", "Automation description").option("--priority <n>", "Priority (higher = runs first)", (v4) => Number.parseInt(v4, 10)).option("--disabled", "Create in disabled state").option("--transactional-emissions", "Buffer the run's emit_event publishes and flush them in order only when every action succeeded; " + "a failed run publishes zero (#988). Defaults to off (immediate publishing)").option("--agent-id <id>", "Agent ID (for the first call_agent action)").option("--provider-id <id>", "Provider ID (for the first call_agent action)").option("--response-as <var>", "Store agent response as variable (for the first call_agent action)").action(async (options) => {
139310
139430
  const client = getClient();
139311
139431
  try {
139312
- const actionResult = buildActionConfig(options);
139313
- if (!actionResult.ok) {
139314
- error(actionResult.error);
139315
- return;
139316
- }
139317
- const conditionResult = parseConditions(options);
139318
- if (!conditionResult.ok) {
139319
- error(conditionResult.error);
139320
- return;
139321
- }
139322
- const automation = await client.automations.create({
139323
- name: options.name,
139324
- description: options.description,
139325
- triggerEventType: options.trigger,
139326
- triggerConditions: conditionResult.conditions,
139327
- conditionLogic: conditionResult.logic,
139328
- actions: [
139329
- {
139330
- type: options.action,
139331
- config: actionResult.config
139332
- }
139333
- ],
139334
- priority: options.priority,
139335
- enabled: !options.disabled,
139336
- transactionalEmissions: options.transactionalEmissions
139337
- });
139432
+ const automation = await client.automations.create(buildCreateBody(options));
139338
139433
  success(`Automation created: ${automation.id}`, {
139339
139434
  id: automation.id,
139340
139435
  name: automation.name,
139341
139436
  trigger: automation.triggerEventType,
139437
+ actions: automation.actions.length,
139342
139438
  enabled: automation.enabled
139343
139439
  });
139344
139440
  } catch (err2) {
@@ -139346,19 +139442,21 @@ function createAutomationsCommand() {
139346
139442
  error(`Failed to create automation: ${message2}`);
139347
139443
  }
139348
139444
  });
139349
- automations2.command("update <id>").description("Update an automation").option("--name <name>", "New name").option("--description <desc>", "New description").option("--priority <n>", "New priority", (v4) => Number.parseInt(v4, 10)).option("--transactional-emissions", "Buffer the run's emit_event publishes and flush them in order only when every action succeeded; " + "a failed run publishes zero (#988)").option("--no-transactional-emissions", "Return the automation to immediate mid-sequence publishing").action(async (id, options) => {
139445
+ automations2.command("update <id>").description("Update an automation in place (id and execution logs are kept)").option("--file <path>", "Full definition as JSON (the `get` output works as-is); explicit flags override it").option("--name <name>", "New name").option("--description <desc>", "New description").option("--trigger <event>", "New trigger event type").option("--condition <json>", "Replace trigger conditions (JSON array)").option("--condition-logic <logic>", 'Condition logic: "and" or "or"').option("--action <type>", "Replace the actions list; repeat for ordered multi-action", collectRepeated).option("--action-config <json>", "Action config as JSON; the i-th pairs with the i-th --action", collectRepeated).option("--priority <n>", "New priority", (v4) => Number.parseInt(v4, 10)).option("--transactional-emissions", "Buffer the run's emit_event publishes and flush them in order only when every action succeeded; " + "a failed run publishes zero (#988)").option("--no-transactional-emissions", "Return the automation to immediate mid-sequence publishing").option("--agent-id <id>", "Agent ID (for the first call_agent action)").option("--provider-id <id>", "Provider ID (for the first call_agent action)").option("--response-as <var>", "Store agent response as variable (for the first call_agent action)").action(async (id, options) => {
139350
139446
  const client = getClient();
139351
139447
  try {
139448
+ const body = buildDefinition(options);
139449
+ if (Object.keys(body).length === 0) {
139450
+ error("Nothing to update: pass at least one field flag or --file");
139451
+ return;
139452
+ }
139352
139453
  const automationId = await resolveAutomationId(id);
139353
- const automation = await client.automations.update(automationId, {
139354
- name: options.name,
139355
- description: options.description,
139356
- priority: options.priority,
139357
- transactionalEmissions: options.transactionalEmissions
139358
- });
139454
+ const automation = await client.automations.update(automationId, body);
139359
139455
  success(`Automation updated: ${automation.id}`, {
139360
139456
  id: automation.id,
139361
- name: automation.name
139457
+ name: automation.name,
139458
+ trigger: automation.triggerEventType,
139459
+ actions: automation.actions.length
139362
139460
  });
139363
139461
  } catch (err2) {
139364
139462
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
@@ -142418,7 +142516,7 @@ init_src2();
142418
142516
  init_config();
142419
142517
  init_output();
142420
142518
  import { spawnSync } from "child_process";
142421
- import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync2, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
142519
+ import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync8, renameSync as renameSync2, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
142422
142520
  import { homedir as homedir7 } from "os";
142423
142521
  import { join as join11 } from "path";
142424
142522
  import { gunzipSync as gunzipSync2, gzipSync as gzipSync2 } from "zlib";
@@ -142611,7 +142709,7 @@ function getEmbeddedPgserveDataDir() {
142611
142709
  }
142612
142710
  function embeddedServerMajor() {
142613
142711
  try {
142614
- const v4 = Number.parseInt(readFileSync7(join11(getEmbeddedPgserveDataDir(), "PG_VERSION"), "utf8").trim(), 10);
142712
+ const v4 = Number.parseInt(readFileSync8(join11(getEmbeddedPgserveDataDir(), "PG_VERSION"), "utf8").trim(), 10);
142615
142713
  return Number.isFinite(v4) ? v4 : null;
142616
142714
  } catch {
142617
142715
  return null;
@@ -142626,7 +142724,7 @@ function getCanonicalPgserveDataDir() {
142626
142724
  if (!existsSync9(PGSERVE_CONFIG_PATH))
142627
142725
  return PGSERVE_DEFAULT_DATA_DIR;
142628
142726
  try {
142629
- const raw2 = readFileSync7(PGSERVE_CONFIG_PATH, "utf8");
142727
+ const raw2 = readFileSync8(PGSERVE_CONFIG_PATH, "utf8");
142630
142728
  const parsed = JSON.parse(raw2);
142631
142729
  return typeof parsed.dataDir === "string" && parsed.dataDir.length > 0 ? parsed.dataDir : PGSERVE_DEFAULT_DATA_DIR;
142632
142730
  } catch {
@@ -142708,7 +142806,7 @@ async function restoreSnapshotToCanonical(dump, canonicalDatabaseUrl) {
142708
142806
  raw(` snapshot: ${dump.snapshotPath}`);
142709
142807
  raw(` canonical data dir: ${getCanonicalPgserveDataDir()}`);
142710
142808
  raw(` canonical URL: ${canonicalDatabaseUrl}`);
142711
- const compressed = readFileSync7(dump.snapshotPath);
142809
+ const compressed = readFileSync8(dump.snapshotPath);
142712
142810
  const sql = gunzipSync2(compressed);
142713
142811
  const result = spawnSync("psql", ["-v", "ON_ERROR_STOP=1"], {
142714
142812
  env: { ...process.env, ...pgEnvFromUrl(canonicalDatabaseUrl) },
@@ -143616,7 +143714,7 @@ Safety:
143616
143714
  }
143617
143715
 
143618
143716
  // src/commands/done.ts
143619
- import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
143717
+ import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
143620
143718
  import { basename, extname } from "path";
143621
143719
 
143622
143720
  // src/context.ts
@@ -143730,7 +143828,7 @@ async function handleMedia(client, ctx, mediaPath, caption) {
143730
143828
  }
143731
143829
  try {
143732
143830
  const mediaType = getMediaType(mediaPath);
143733
- const buffer3 = readFileSync9(mediaPath);
143831
+ const buffer3 = readFileSync10(mediaPath);
143734
143832
  const base64 = buffer3.toString("base64");
143735
143833
  const filename = basename(mediaPath);
143736
143834
  await client.messages.sendMedia({
@@ -143789,7 +143887,7 @@ function createDoneCommand() {
143789
143887
 
143790
143888
  // src/commands/events.ts
143791
143889
  init_src();
143792
- import { readFileSync as readFileSync10 } from "fs";
143890
+ import { readFileSync as readFileSync11 } from "fs";
143793
143891
  init_zod();
143794
143892
  init_config();
143795
143893
  init_output();
@@ -143892,6 +143990,7 @@ function displayAnalytics(data2) {
143892
143990
  successRate: data2.successRate,
143893
143991
  avgProcessingMs: data2.avgProcessingTimeMs,
143894
143992
  avgAgentMs: data2.avgAgentTimeMs,
143993
+ totalCostUsd: data2.totalCostUsd ?? 0,
143895
143994
  messageTypes: data2.messageTypes,
143896
143995
  instances: data2.instances,
143897
143996
  errorStages: data2.errorStages
@@ -143903,7 +144002,8 @@ function displayAnalytics(data2) {
143903
144002
  failed: data2.failedMessages,
143904
144003
  successRate: `${data2.successRate.toFixed(1)}%`,
143905
144004
  avgProcessingMs: data2.avgProcessingTimeMs ?? "-",
143906
- avgAgentMs: data2.avgAgentTimeMs ?? "-"
144005
+ avgAgentMs: data2.avgAgentTimeMs ?? "-",
144006
+ totalCostUsd: `$${(data2.totalCostUsd ?? 0).toFixed(4)}`
143907
144007
  });
143908
144008
  displayRecordBreakdown("Message Types", data2.messageTypes, "type");
143909
144009
  displayRecordBreakdown("Per Instance", data2.instances, "instanceId");
@@ -143975,13 +144075,19 @@ function loadSchemaArtifact(options) {
143975
144075
  if ((options.file ? 1 : 0) + (options.schema ? 1 : 0) !== 1) {
143976
144076
  throw new Error("Provide the JSON Schema via exactly one of --file <path> or --schema <json>");
143977
144077
  }
143978
- const raw2 = options.file ? readFileSync10(options.file, "utf-8") : options.schema;
144078
+ const raw2 = options.file ? readFileSync11(options.file, "utf-8") : options.schema;
143979
144079
  const parsed = JSON.parse(raw2);
143980
144080
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
143981
144081
  throw new Error("The JSON Schema artifact must be a JSON object");
143982
144082
  }
143983
144083
  return parsed;
143984
144084
  }
144085
+ function loadPayload(options) {
144086
+ if ((options.file ? 1 : 0) + (options.payload ? 1 : 0) !== 1) {
144087
+ throw new Error("Provide the payload via exactly one of --file <path> or --payload <json>");
144088
+ }
144089
+ return JSON.parse(options.file ? readFileSync11(options.file, "utf-8") : options.payload);
144090
+ }
143985
144091
  function summarizeSchemaRow(row) {
143986
144092
  return {
143987
144093
  eventType: row.eventType,
@@ -144034,6 +144140,29 @@ function createSchemaCommand() {
144034
144140
  error(`Failed to get schema: ${message2}`);
144035
144141
  }
144036
144142
  });
144143
+ schema.command("validate <eventType>").description("Validate a payload against the registered schema without emitting an event (exit 1 on violations)").option("--file <path>", "Path to a JSON payload file").option("--payload <json>", "Inline JSON payload").action(async (eventType, options) => {
144144
+ let result;
144145
+ try {
144146
+ const payload = loadPayload(options);
144147
+ const res = await schemaApiRequest(`/${encodeURIComponent(eventType)}/validate`, {
144148
+ method: "POST",
144149
+ body: JSON.stringify({ payload })
144150
+ });
144151
+ result = res.data;
144152
+ } catch (err2) {
144153
+ const message2 = err2 instanceof Error ? err2.message : "Unknown error";
144154
+ error(`Failed to validate payload: ${message2}`, undefined, 2);
144155
+ }
144156
+ if (result.valid) {
144157
+ success(`Payload is valid for ${result.eventType} (schema version ${result.version})`, result);
144158
+ return;
144159
+ }
144160
+ if (getCurrentFormat() === "human") {
144161
+ for (const line of result.errors)
144162
+ raw(` - ${line}`);
144163
+ }
144164
+ error(`Payload violates the schema for ${result.eventType} (schema version ${result.version}): ${result.errors.length} issue(s)`, getCurrentFormat() === "json" ? result : undefined);
144165
+ });
144037
144166
  return schema;
144038
144167
  }
144039
144168
  function eventListRow(e10) {
@@ -144567,7 +144696,7 @@ function createEventsCommand() {
144567
144696
  }
144568
144697
 
144569
144698
  // src/commands/film.ts
144570
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
144699
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "fs";
144571
144700
  import { resolve as resolvePath } from "path";
144572
144701
  init_output();
144573
144702
  function createFilmCommand() {
@@ -144611,7 +144740,7 @@ function createFilmCommand() {
144611
144740
  let imageMimeType;
144612
144741
  if (options.reference) {
144613
144742
  try {
144614
- const ref = readFileSync11(resolvePath(options.reference));
144743
+ const ref = readFileSync12(resolvePath(options.reference));
144615
144744
  imageBase64 = ref.toString("base64");
144616
144745
  imageMimeType = mimeForImagePath(options.reference);
144617
144746
  } catch (err2) {
@@ -144683,7 +144812,7 @@ function mimeForImagePath(path) {
144683
144812
  }
144684
144813
 
144685
144814
  // src/commands/follow-up.ts
144686
- import { readFileSync as readFileSync12 } from "fs";
144815
+ import { readFileSync as readFileSync13 } from "fs";
144687
144816
  init_output();
144688
144817
  var VALID_SCOPES = ["agents", "instances", "chats"];
144689
144818
  function assertScope(scope) {
@@ -144701,9 +144830,9 @@ async function resolveScopedId(scope, id) {
144701
144830
  function readJsonArg(raw2) {
144702
144831
  let body = raw2;
144703
144832
  if (body === "-") {
144704
- body = readFileSync12(0, "utf8");
144833
+ body = readFileSync13(0, "utf8");
144705
144834
  } else if (body.startsWith("@")) {
144706
- body = readFileSync12(body.slice(1), "utf8");
144835
+ body = readFileSync13(body.slice(1), "utf8");
144707
144836
  }
144708
144837
  try {
144709
144838
  return JSON.parse(body);
@@ -146417,7 +146546,7 @@ function formatKeyRow(key) {
146417
146546
  function parseCommaSeparated(value) {
146418
146547
  return value.split(",").map((s2) => s2.trim()).filter(Boolean);
146419
146548
  }
146420
- function collectRepeated(value, previous) {
146549
+ function collectRepeated2(value, previous) {
146421
146550
  return [...previous ?? [], value];
146422
146551
  }
146423
146552
  async function readLineFromStdin() {
@@ -146636,7 +146765,7 @@ async function handleDelete(client, id) {
146636
146765
  }
146637
146766
  function createKeysCommand() {
146638
146767
  const keys = new Command("keys").description("Manage API keys");
146639
- keys.command("create").description("Create a new API key (optionally from a profile template)").requiredOption("--name <name>", "Key name").option("--profile <name>", "Profile template: cs | personal | scout | coworker | admin").option("--scopes <scopes>", "Comma-separated scopes (legacy \u2014 omit when --profile is set; scopes derive from the profile)").option("--lock-chat <jid>", "Lock this key to a chat (repeat for multiple)", collectRepeated).option("--lock-instance <id>", "Lock this key to an instance (repeat for multiple)", collectRepeated).option("--owner <jid>", "Scout: owner JID \u2014 populates outboundRecipientAllowlist").option("--denylist-preset <key>", "Coworker: denylist preset key (overrides profile default)").option("--instances <ids>", "Comma-separated instance IDs to restrict access (legacy)").option("--description <desc>", "Key description").option("--rate-limit <n>", "Rate limit (requests/minute)", Number.parseInt).option("--expires <date>", "Expiration date (ISO 8601)").action(async (options) => {
146768
+ keys.command("create").description("Create a new API key (optionally from a profile template)").requiredOption("--name <name>", "Key name").option("--profile <name>", "Profile template: cs | personal | scout | coworker | admin").option("--scopes <scopes>", "Comma-separated scopes (legacy \u2014 omit when --profile is set; scopes derive from the profile)").option("--lock-chat <jid>", "Lock this key to a chat (repeat for multiple)", collectRepeated2).option("--lock-instance <id>", "Lock this key to an instance (repeat for multiple)", collectRepeated2).option("--owner <jid>", "Scout: owner JID \u2014 populates outboundRecipientAllowlist").option("--denylist-preset <key>", "Coworker: denylist preset key (overrides profile default)").option("--instances <ids>", "Comma-separated instance IDs to restrict access (legacy)").option("--description <desc>", "Key description").option("--rate-limit <n>", "Rate limit (requests/minute)", Number.parseInt).option("--expires <date>", "Expiration date (ISO 8601)").action(async (options) => {
146640
146769
  const needsClient = options.profile !== "admin";
146641
146770
  const client = needsClient ? getClient() : null;
146642
146771
  try {
@@ -148039,7 +148168,7 @@ init_output();
148039
148168
  init_src();
148040
148169
  import { execFileSync as execFileSync4, execSync } from "child_process";
148041
148170
  import * as nodeCrypto2 from "crypto";
148042
- import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "fs";
148171
+ import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "fs";
148043
148172
  import { homedir as homedir11 } from "os";
148044
148173
  import { dirname as dirname6, resolve as resolve3 } from "path";
148045
148174
  import { createInterface as createInterface2 } from "readline";
@@ -148272,7 +148401,7 @@ var PLUGIN_MARKER = "plugin-openclaw/omni.ts";
148272
148401
  function readOpenClawConfig(configPath) {
148273
148402
  if (!existsSync15(configPath))
148274
148403
  return {};
148275
- const raw2 = readFileSync14(configPath, "utf-8").trim();
148404
+ const raw2 = readFileSync15(configPath, "utf-8").trim();
148276
148405
  if (!raw2)
148277
148406
  return {};
148278
148407
  return JSON.parse(raw2);
@@ -149444,7 +149573,7 @@ function createScheduleCommand() {
149444
149573
  }
149445
149574
 
149446
149575
  // src/commands/see.ts
149447
- import { existsSync as existsSync16, readFileSync as readFileSync15, statSync as statSync5 } from "fs";
149576
+ import { existsSync as existsSync16, readFileSync as readFileSync16, statSync as statSync5 } from "fs";
149448
149577
  import { extname as extname4 } from "path";
149449
149578
  init_output();
149450
149579
  var MIME_BY_EXT = {
@@ -149487,7 +149616,7 @@ function loadMedia(file) {
149487
149616
  error(`File is empty: ${file}`);
149488
149617
  }
149489
149618
  try {
149490
- return { buffer: readFileSync15(file), mimeType: guessMimeType(file) };
149619
+ return { buffer: readFileSync16(file), mimeType: guessMimeType(file) };
149491
149620
  } catch (err2) {
149492
149621
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
149493
149622
  return error(`Failed to read ${file}: ${message2}`);
@@ -149562,7 +149691,7 @@ function createSeeCommand() {
149562
149691
  }
149563
149692
 
149564
149693
  // src/commands/send.ts
149565
- import { existsSync as existsSync17, readFileSync as readFileSync16 } from "fs";
149694
+ import { existsSync as existsSync17, readFileSync as readFileSync17 } from "fs";
149566
149695
  import { basename as basename5, extname as extname5 } from "path";
149567
149696
  init_source();
149568
149697
  init_zod();
@@ -149583,7 +149712,7 @@ function getMediaType2(path) {
149583
149712
  return "document";
149584
149713
  }
149585
149714
  function readFileAsBase64(path) {
149586
- const buffer3 = readFileSync16(path);
149715
+ const buffer3 = readFileSync17(path);
149587
149716
  return buffer3.toString("base64");
149588
149717
  }
149589
149718
  function parseLoadingMessages(value) {
@@ -151656,7 +151785,7 @@ async function cleanupLegacyArtifacts(skipList) {
151656
151785
  init_output();
151657
151786
 
151658
151787
  // src/update-diagnostics.ts
151659
- import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync17, writeFileSync as writeFileSync11 } from "fs";
151788
+ import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync18, writeFileSync as writeFileSync11 } from "fs";
151660
151789
  import { homedir as homedir13 } from "os";
151661
151790
  import { join as join18 } from "path";
151662
151791
  var UPDATE_DIAGNOSTICS_SCHEMA_VERSION = 1;
@@ -151691,7 +151820,7 @@ function tailFileLines(path, maxLines) {
151691
151820
  if (!existsSync19(path))
151692
151821
  return [];
151693
151822
  try {
151694
- const raw2 = readFileSync17(path, "utf8");
151823
+ const raw2 = readFileSync18(path, "utf8");
151695
151824
  const lines = raw2.split(/\r?\n/);
151696
151825
  if (lines.length > 0 && lines[lines.length - 1] === "")
151697
151826
  lines.pop();
@@ -152375,7 +152504,7 @@ ${lines.join(`
152375
152504
  }
152376
152505
 
152377
152506
  // src/commands/webhooks.ts
152378
- import { readFileSync as readFileSync18 } from "fs";
152507
+ import { readFileSync as readFileSync19 } from "fs";
152379
152508
  init_zod();
152380
152509
  init_output();
152381
152510
  var SIGNATURE_ALGORITHMS = ["hmac-sha256", "hmac-sha1", "token-match"];
@@ -152463,7 +152592,7 @@ function resolveEventTypeMapping(raw2) {
152463
152592
  if (raw2.startsWith("@")) {
152464
152593
  const path = raw2.slice(1);
152465
152594
  try {
152466
- text3 = readFileSync18(path, "utf-8");
152595
+ text3 = readFileSync19(path, "utf-8");
152467
152596
  } catch (err2) {
152468
152597
  const reason = err2 instanceof Error ? err2.message : "Unknown error";
152469
152598
  throw new Error(`Cannot read --event-type-mapping file '${path}': ${reason}`);
@@ -152678,7 +152807,7 @@ function createWebhooksCommand() {
152678
152807
  error(`Failed to delete webhook source: ${message2}`);
152679
152808
  }
152680
152809
  });
152681
- webhooks.command("trigger").description("Trigger a custom event").requiredOption("--type <type>", "Event type").requiredOption("--payload <json>", "Event payload as JSON").option("--instance <id>", "Instance ID").option("--correlation-id <id>", "Correlation ID").action(async (options3) => {
152810
+ webhooks.command("trigger").description("Trigger a custom event").requiredOption("--type <type>", "Event type").requiredOption("--payload <json>", "Event payload as JSON").option("--instance <id>", "Instance ID").option("--correlation-id <id>", "Correlation ID").option("--causation-id <event-id>", "Parent event ID (keeps the causality tree for mid-flow emissions, #1072)").action(async (options3) => {
152682
152811
  const client = getClient();
152683
152812
  try {
152684
152813
  let payload;
@@ -152692,7 +152821,8 @@ function createWebhooksCommand() {
152692
152821
  eventType: options3.type,
152693
152822
  payload,
152694
152823
  instanceId: options3.instance,
152695
- correlationId: options3.correlationId
152824
+ correlationId: options3.correlationId,
152825
+ causationId: options3.causationId
152696
152826
  });
152697
152827
  success(`Event triggered: ${result.eventId}`, {
152698
152828
  eventId: result.eventId,
@@ -152749,7 +152879,7 @@ init_config();
152749
152879
  init_output();
152750
152880
 
152751
152881
  // src/manifest-pin.ts
152752
- import { existsSync as existsSync21, readFileSync as readFileSync19, renameSync as renameSync3, writeFileSync as writeFileSync12 } from "fs";
152882
+ import { existsSync as existsSync21, readFileSync as readFileSync20, renameSync as renameSync3, writeFileSync as writeFileSync12 } from "fs";
152753
152883
  import { homedir as homedir14 } from "os";
152754
152884
  import { join as join20 } from "path";
152755
152885
  var PACKAGE_NAME2 = "@automagik/omni";
@@ -152759,7 +152889,7 @@ function pinManifestEntry(manifestPath, exactVersion) {
152759
152889
  return false;
152760
152890
  let manifest;
152761
152891
  try {
152762
- manifest = JSON.parse(readFileSync19(manifestPath, "utf-8"));
152892
+ manifest = JSON.parse(readFileSync20(manifestPath, "utf-8"));
152763
152893
  } catch {
152764
152894
  return false;
152765
152895
  }