openmates 0.17.0-alpha.0 → 0.17.0-alpha.10

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.
@@ -13940,6 +13940,7 @@ Required: ${schema.required.join(", ")}`
13940
13940
  try {
13941
13941
  const baseSyncPayload = {
13942
13942
  ...teamId ? { team_id: teamId } : {},
13943
+ context_epoch: 0,
13943
13944
  client_chat_versions: clientChatVersions,
13944
13945
  client_chat_ids: clientChatIds,
13945
13946
  client_embed_ids: clientEmbedIds
@@ -14392,6 +14393,17 @@ var APP_SKILL_METADATA = [
14392
14393
  "required": [
14393
14394
  "prompt"
14394
14395
  ]
14396
+ },
14397
+ "output_schema": {
14398
+ "type": "object",
14399
+ "properties": {
14400
+ "answer": {
14401
+ "type": "string"
14402
+ },
14403
+ "conversation": {
14404
+ "type": "string"
14405
+ }
14406
+ }
14395
14407
  }
14396
14408
  },
14397
14409
  {
@@ -14682,6 +14694,23 @@ var APP_SKILL_METADATA = [
14682
14694
  "required": [
14683
14695
  "companies"
14684
14696
  ]
14697
+ },
14698
+ "output_schema": {
14699
+ "type": "object",
14700
+ "properties": {
14701
+ "summary": {
14702
+ "type": "string"
14703
+ },
14704
+ "result_count": {
14705
+ "type": "integer"
14706
+ },
14707
+ "provider": {
14708
+ "type": "string"
14709
+ },
14710
+ "results": {
14711
+ "type": "array"
14712
+ }
14713
+ }
14685
14714
  }
14686
14715
  },
14687
14716
  {
@@ -14752,6 +14781,251 @@ var APP_SKILL_METADATA = [
14752
14781
  ]
14753
14782
  }
14754
14783
  },
14784
+ {
14785
+ "app_id": "code",
14786
+ "skill_id": "run",
14787
+ "app_namespace_ts": "code",
14788
+ "skill_method_ts": "run",
14789
+ "app_namespace_py": "code",
14790
+ "skill_method_py": "run",
14791
+ "description_key": "app_skills.code.run.description",
14792
+ "description": "Run a code embed in an isolated E2B sandbox. Use automatically only for code the assistant created or edited in the current turn; ask the user before running unmodified user-supplied code or after the initial run plus two unprompted reruns. The sandbox receives code files from the current chat, installs supported dependency manifests, executes the selected file, streams terminal status, and returns safe artifact metadata. Pricing is 5 credits per started minute of sandbox runtime.",
14793
+ "schema": {
14794
+ "type": "object",
14795
+ "properties": {
14796
+ "requests": {
14797
+ "type": "array",
14798
+ "minItems": 1,
14799
+ "maxItems": 10,
14800
+ "description": "Array of direct or chat-bound Code Run requests for the custom REST/SDK route.",
14801
+ "items": {
14802
+ "type": "object",
14803
+ "properties": {
14804
+ "mode": {
14805
+ "type": "string",
14806
+ "enum": [
14807
+ "direct",
14808
+ "chat_bound"
14809
+ ],
14810
+ "default": "direct",
14811
+ "description": "Direct runs use caller-supplied files and stay transient; chat_bound runs use a chat/embed target and persist encrypted output."
14812
+ },
14813
+ "entry_path": {
14814
+ "type": "string",
14815
+ "description": "Entrypoint file path for direct runs."
14816
+ },
14817
+ "files": {
14818
+ "type": "array",
14819
+ "maxItems": 50,
14820
+ "description": "Direct-run files with base64-encoded content. The backend never fetches local paths or URLs.",
14821
+ "items": {
14822
+ "type": "object",
14823
+ "properties": {
14824
+ "path": {
14825
+ "type": "string"
14826
+ },
14827
+ "content_base64": {
14828
+ "type": "string"
14829
+ },
14830
+ "language": {
14831
+ "type": "string"
14832
+ },
14833
+ "mime_type": {
14834
+ "type": "string",
14835
+ "default": "text/plain"
14836
+ },
14837
+ "is_target": {
14838
+ "type": "boolean",
14839
+ "default": false
14840
+ }
14841
+ },
14842
+ "required": [
14843
+ "path",
14844
+ "content_base64"
14845
+ ]
14846
+ }
14847
+ },
14848
+ "chat_id": {
14849
+ "type": "string",
14850
+ "description": "Chat ID for chat-bound runs."
14851
+ },
14852
+ "target_embed_id": {
14853
+ "type": "string",
14854
+ "description": "Target code embed ID for chat-bound runs."
14855
+ },
14856
+ "selected_embed_ids": {
14857
+ "type": "array",
14858
+ "items": {
14859
+ "type": "string"
14860
+ },
14861
+ "description": "Optional related embed IDs to include in chat-bound runs."
14862
+ },
14863
+ "dependency_installs": {
14864
+ "type": "array",
14865
+ "maxItems": 20,
14866
+ "description": "Optional explicit dependency installs.",
14867
+ "items": {
14868
+ "type": "object",
14869
+ "properties": {
14870
+ "ecosystem": {
14871
+ "type": "string",
14872
+ "enum": [
14873
+ "python",
14874
+ "npm"
14875
+ ]
14876
+ },
14877
+ "packages": {
14878
+ "type": "array",
14879
+ "items": {
14880
+ "type": "string"
14881
+ }
14882
+ }
14883
+ },
14884
+ "required": [
14885
+ "ecosystem",
14886
+ "packages"
14887
+ ]
14888
+ }
14889
+ },
14890
+ "enable_internet": {
14891
+ "type": "boolean",
14892
+ "default": true,
14893
+ "description": "Allow outbound internet access from the E2B sandbox."
14894
+ }
14895
+ }
14896
+ }
14897
+ }
14898
+ },
14899
+ "required": [
14900
+ "requests"
14901
+ ]
14902
+ },
14903
+ "output_schema": {
14904
+ "type": "object",
14905
+ "properties": {
14906
+ "results": {
14907
+ "type": "array",
14908
+ "items": {
14909
+ "type": "object",
14910
+ "properties": {
14911
+ "execution_id": {
14912
+ "type": "string"
14913
+ },
14914
+ "status": {
14915
+ "type": "string"
14916
+ },
14917
+ "target_filename": {
14918
+ "type": "string"
14919
+ },
14920
+ "files": {
14921
+ "type": "array",
14922
+ "items": {
14923
+ "type": "string"
14924
+ }
14925
+ },
14926
+ "credits_per_minute": {
14927
+ "type": "integer"
14928
+ },
14929
+ "persisted_output": {
14930
+ "type": "boolean"
14931
+ },
14932
+ "stream_path": {
14933
+ "type": "string"
14934
+ },
14935
+ "status_path": {
14936
+ "type": "string"
14937
+ },
14938
+ "final": {
14939
+ "type": "object",
14940
+ "description": "Final status fetched from status_path by SDK helpers. Direct runs remain transient.",
14941
+ "properties": {
14942
+ "status": {
14943
+ "type": "string"
14944
+ },
14945
+ "exit_code": {
14946
+ "type": "integer"
14947
+ },
14948
+ "output": {
14949
+ "type": "string"
14950
+ },
14951
+ "error": {
14952
+ "type": "string"
14953
+ },
14954
+ "duration_seconds": {
14955
+ "type": "number"
14956
+ },
14957
+ "charged_credits": {
14958
+ "type": "integer"
14959
+ },
14960
+ "charged_minutes": {
14961
+ "type": "integer"
14962
+ },
14963
+ "artifacts": {
14964
+ "type": "array",
14965
+ "items": {
14966
+ "type": "object",
14967
+ "properties": {
14968
+ "path": {
14969
+ "type": "string"
14970
+ },
14971
+ "normalized_path": {
14972
+ "type": "string"
14973
+ },
14974
+ "mime_type": {
14975
+ "type": "string"
14976
+ },
14977
+ "kind": {
14978
+ "type": "string"
14979
+ },
14980
+ "size_bytes": {
14981
+ "type": "integer"
14982
+ },
14983
+ "status": {
14984
+ "type": "string"
14985
+ },
14986
+ "asset_id": {
14987
+ "type": "string"
14988
+ },
14989
+ "file_id": {
14990
+ "type": "string"
14991
+ },
14992
+ "variant": {
14993
+ "type": "string"
14994
+ },
14995
+ "version": {
14996
+ "type": "integer"
14997
+ },
14998
+ "download_url": {
14999
+ "type": "string"
15000
+ }
15001
+ }
15002
+ }
15003
+ },
15004
+ "skipped_artifacts": {
15005
+ "type": "array",
15006
+ "items": {
15007
+ "type": "object",
15008
+ "properties": {
15009
+ "path": {
15010
+ "type": "string"
15011
+ },
15012
+ "normalized_path": {
15013
+ "type": "string"
15014
+ },
15015
+ "reason": {
15016
+ "type": "string"
15017
+ }
15018
+ }
15019
+ }
15020
+ }
15021
+ }
15022
+ }
15023
+ }
15024
+ }
15025
+ }
15026
+ }
15027
+ }
15028
+ },
14755
15029
  {
14756
15030
  "app_id": "code",
14757
15031
  "skill_id": "image_to_html",
@@ -15190,6 +15464,17 @@ Note: The 'id' field is auto-generated if not provided.
15190
15464
  "required": [
15191
15465
  "requests"
15192
15466
  ]
15467
+ },
15468
+ "output_schema": {
15469
+ "type": "object",
15470
+ "properties": {
15471
+ "summary": {
15472
+ "type": "string"
15473
+ },
15474
+ "result_count": {
15475
+ "type": "integer"
15476
+ }
15477
+ }
15193
15478
  }
15194
15479
  },
15195
15480
  {
@@ -16202,6 +16487,17 @@ Note: The 'id' field is auto-generated if not provided - you don't need to inclu
16202
16487
  "required": [
16203
16488
  "requests"
16204
16489
  ]
16490
+ },
16491
+ "output_schema": {
16492
+ "type": "object",
16493
+ "properties": {
16494
+ "summary": {
16495
+ "type": "string"
16496
+ },
16497
+ "result_count": {
16498
+ "type": "integer"
16499
+ }
16500
+ }
16205
16501
  }
16206
16502
  },
16207
16503
  {
@@ -17929,6 +18225,20 @@ Note: The 'id' field is auto-generated if not provided - you don't need to inclu
17929
18225
  "required": [
17930
18226
  "location"
17931
18227
  ]
18228
+ },
18229
+ "output_schema": {
18230
+ "type": "object",
18231
+ "properties": {
18232
+ "summary": {
18233
+ "type": "string"
18234
+ },
18235
+ "rain_probability": {
18236
+ "type": "number"
18237
+ },
18238
+ "max_temperature_c": {
18239
+ "type": "number"
18240
+ }
18241
+ }
17932
18242
  }
17933
18243
  },
17934
18244
  {
@@ -18120,6 +18430,17 @@ Note: The 'id' field is auto-generated if not provided - you don't need to inclu
18120
18430
  "required": [
18121
18431
  "requests"
18122
18432
  ]
18433
+ },
18434
+ "output_schema": {
18435
+ "type": "object",
18436
+ "properties": {
18437
+ "summary": {
18438
+ "type": "string"
18439
+ },
18440
+ "result_count": {
18441
+ "type": "integer"
18442
+ }
18443
+ }
18123
18444
  }
18124
18445
  },
18125
18446
  {
@@ -18363,6 +18684,14 @@ var CodeAppSkills = class {
18363
18684
  async removeSecrets(input, options) {
18364
18685
  return this.runSkill("code", "remove_secrets", input, options);
18365
18686
  }
18687
+ /**
18688
+ * Run a code embed in an isolated E2B sandbox. Use automatically only for code the assistant created or edited in the current turn; ask the user before running unmodified user-supplied code or after the initial run plus two unprompted reruns. The sandbox receives code files from the current chat, installs supported dependency manifests, executes the selected file, streams terminal status, and returns safe artifact metadata. Pricing is 5 credits per started minute of sandbox runtime.
18689
+ * Description key: app_skills.code.run.description
18690
+ * Skill: code/run
18691
+ */
18692
+ async run(input, options) {
18693
+ return this.runSkill("code", "run", input, options);
18694
+ }
18366
18695
  /**
18367
18696
  * Search GitHub repositories. Use this instead of web.search whenever the user asks to find GitHub repos, repositories, open-source libraries, starred repos, or repo examples by topic, language, framework, or project need. Returns licensed repository embeds. Costs 10 credits per search.
18368
18697
  * Description key: code.search_repos.description
@@ -19383,6 +19712,9 @@ var DEFAULT_RECOVERY_TIMEOUT_MS = 6e4;
19383
19712
  var SKILL_TASK_POLL_INTERVAL_MS2 = 2e3;
19384
19713
  var SKILL_TASK_POLL_TIMEOUT_MS2 = 12e5;
19385
19714
  var SKILL_TASK_POLL_TRANSIENT_ERROR_STATUS2 = 500;
19715
+ var CODE_RUN_POLL_INTERVAL_MS = 1e3;
19716
+ var CODE_RUN_POLL_TIMEOUT_MS = 12e5;
19717
+ var CODE_RUN_TERMINAL_STATUSES = /* @__PURE__ */ new Set(["finished", "failed", "timeout", "cancelled"]);
19386
19718
  var PROMPT_INJECTION_DISABLED2 = "disabled";
19387
19719
  var CANONICAL_UUID_PATTERN2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
19388
19720
  function withAppSkillRunOptions(input, options) {
@@ -19498,6 +19830,9 @@ var OpenMates = class {
19498
19830
  }
19499
19831
  async runAppSkill(appId, skillId, input, options) {
19500
19832
  const response = await this.request(`/v1/apps/${appId}/skills/${skillId}`, withAppSkillRunOptions(input, options));
19833
+ if (appId === "code" && skillId === "run") {
19834
+ return this.resolveCodeRunSkillResponse(response);
19835
+ }
19501
19836
  return this.resolveAsyncSkillResponse(response);
19502
19837
  }
19503
19838
  async runConnectedAccountSkill(appId, skillId, input, options = {}) {
@@ -19766,6 +20101,65 @@ var OpenMates = class {
19766
20101
  }
19767
20102
  return responseData;
19768
20103
  }
20104
+ async resolveCodeRunSkillResponse(responseData) {
20105
+ const envelope = responseData;
20106
+ const data = envelope?.data ?? envelope;
20107
+ const results = Array.isArray(data?.results) ? data.results : [];
20108
+ if (results.length === 0) return responseData;
20109
+ const resolvedResults = await Promise.all(results.map(async (result) => {
20110
+ if (!result || typeof result !== "object" || Array.isArray(result)) return result;
20111
+ const item = result;
20112
+ const statusPath = typeof item.status_path === "string" ? item.status_path : null;
20113
+ if (!statusPath) return item;
20114
+ return { ...item, final: await this.pollCodeRunUntilComplete(statusPath) };
20115
+ }));
20116
+ const resolvedData = { ...data, results: resolvedResults };
20117
+ if (envelope && typeof envelope === "object" && "success" in envelope) {
20118
+ return { ...envelope, data: resolvedData };
20119
+ }
20120
+ return resolvedData;
20121
+ }
20122
+ async pollCodeRunUntilComplete(statusPath) {
20123
+ const path2 = this.normalizeCodeRunStatusPath(statusPath);
20124
+ const started = Date.now();
20125
+ let lastTransientError = null;
20126
+ while (Date.now() - started < CODE_RUN_POLL_TIMEOUT_MS) {
20127
+ let response;
20128
+ try {
20129
+ response = await fetch(`${this.apiUrl}${path2}`, {
20130
+ method: "GET",
20131
+ headers: this.headers(false)
20132
+ });
20133
+ } catch (error) {
20134
+ lastTransientError = error instanceof Error ? error.message : String(error);
20135
+ await new Promise((resolve10) => setTimeout(resolve10, CODE_RUN_POLL_INTERVAL_MS));
20136
+ continue;
20137
+ }
20138
+ if (!response.ok) {
20139
+ if (response.status >= SKILL_TASK_POLL_TRANSIENT_ERROR_STATUS2) {
20140
+ lastTransientError = `HTTP ${response.status}`;
20141
+ await new Promise((resolve10) => setTimeout(resolve10, CODE_RUN_POLL_INTERVAL_MS));
20142
+ continue;
20143
+ }
20144
+ throw new OpenMatesApiError(response.status, await this.safeJson(response));
20145
+ }
20146
+ lastTransientError = null;
20147
+ const status = await this.parseResponse(response);
20148
+ const value = typeof status.status === "string" ? status.status : "";
20149
+ if (CODE_RUN_TERMINAL_STATUSES.has(value)) return status;
20150
+ await new Promise((resolve10) => setTimeout(resolve10, CODE_RUN_POLL_INTERVAL_MS));
20151
+ }
20152
+ if (lastTransientError) {
20153
+ throw new Error(`Code Run did not complete within ${CODE_RUN_POLL_TIMEOUT_MS / 1e3}s; last polling error: ${lastTransientError}`);
20154
+ }
20155
+ throw new Error(`Code Run did not complete within ${CODE_RUN_POLL_TIMEOUT_MS / 1e3}s`);
20156
+ }
20157
+ normalizeCodeRunStatusPath(statusPath) {
20158
+ if (!statusPath.startsWith("/v1/code/run/")) {
20159
+ throw new OpenMatesConfigError("Code Run returned an invalid status path.");
20160
+ }
20161
+ return statusPath;
20162
+ }
19769
20163
  async pollTaskUntilComplete(taskId) {
19770
20164
  const started = Date.now();
19771
20165
  let lastTransientError = null;
@@ -25987,6 +26381,8 @@ var HEARTBEAT_AFTER_MS = 24 * 60 * 60 * 1e3;
25987
26381
  var OPERATIONAL_REPORT_STALE_AFTER_MS = 26 * 60 * 60 * 1e3;
25988
26382
  var ALLOWED_WEBHOOK_PORTS = /* @__PURE__ */ new Set([443]);
25989
26383
  var IMMEDIATE_FAILURE_CLASSES = /* @__PURE__ */ new Set(["credential", "configuration", "config", "critical_availability"]);
26384
+ var BREVO_API_HOST = "api.brevo.com";
26385
+ var BREVO_REQUEST_TIMEOUT_MS = 1e4;
25990
26386
  function planOperationalMonitoring(options) {
25991
26387
  const emailEnabled = Boolean(options.adminEmail?.trim()) && options.emailServiceAvailable;
25992
26388
  const configurationStatus = !options.adminEmail?.trim() ? "missing_admin_email" : options.emailServiceAvailable ? "ready" : "email_service_unavailable";
@@ -26073,22 +26469,56 @@ function buildOperationalDeliveryReceipt(input) {
26073
26469
  state: input.state,
26074
26470
  attemptCount: input.attemptCount,
26075
26471
  occurredAt: input.occurredAt,
26076
- ...input.sanitizedFailureClass ? { sanitizedFailureClass: input.sanitizedFailureClass } : {}
26472
+ ...input.sanitizedFailureClass ? { sanitizedFailureClass: input.sanitizedFailureClass } : {},
26473
+ ...input.destinationSource ? { destinationSource: input.destinationSource } : {},
26474
+ ...input.fallbackUsed !== void 0 ? { fallbackUsed: input.fallbackUsed } : {}
26077
26475
  };
26078
26476
  }
26079
26477
  async function probeRuntimeEmailService(config) {
26080
26478
  try {
26081
- const response = await fetch("https://api.brevo.com/v3/account", {
26082
- method: "GET",
26083
- redirect: "error",
26084
- headers: { "api-key": config.apiKey },
26085
- signal: AbortSignal.timeout(1e4)
26086
- });
26087
- return response.ok;
26479
+ await requestBrevo("/v3/account", "GET", config.apiKey);
26480
+ return true;
26088
26481
  } catch {
26089
26482
  return false;
26090
26483
  }
26091
26484
  }
26485
+ function buildBrevoRequestOptions(pathName, method, apiKey, body) {
26486
+ return {
26487
+ protocol: "https:",
26488
+ hostname: BREVO_API_HOST,
26489
+ servername: BREVO_API_HOST,
26490
+ port: 443,
26491
+ path: pathName,
26492
+ method,
26493
+ family: 4,
26494
+ lookup: (hostname, options, callback) => dnsModule.lookup(hostname, { ...options, family: 4 }, callback),
26495
+ headers: {
26496
+ "api-key": apiKey,
26497
+ ...body ? { "content-type": "application/json", "Content-Length": Buffer.byteLength(body) } : {}
26498
+ },
26499
+ timeout: BREVO_REQUEST_TIMEOUT_MS
26500
+ };
26501
+ }
26502
+ async function requestBrevo(pathName, method, apiKey, payload) {
26503
+ const body = payload ? JSON.stringify(payload) : void 0;
26504
+ await new Promise((resolve10, reject) => {
26505
+ const request = httpsRequest(buildBrevoRequestOptions(pathName, method, apiKey, body), (response) => {
26506
+ let responseBytes = 0;
26507
+ response.on("data", (chunk) => {
26508
+ responseBytes += chunk.length;
26509
+ if (responseBytes > 64 * 1024) request.destroy(new Error("brevo_response_too_large"));
26510
+ });
26511
+ response.on("end", () => {
26512
+ const status = response.statusCode ?? 0;
26513
+ if (status >= 200 && status < 300) resolve10();
26514
+ else reject(new Error(`brevo_delivery_failed:${status}`));
26515
+ });
26516
+ });
26517
+ request.on("timeout", () => request.destroy(new Error("brevo_delivery_timeout")));
26518
+ request.on("error", reject);
26519
+ request.end(body);
26520
+ });
26521
+ }
26092
26522
  async function readOperationalReportState(installDir, role) {
26093
26523
  const statePath = path.join(installDir, ".openmates", "runtime-health", `${role}-operational-report.json`);
26094
26524
  try {
@@ -26262,21 +26692,14 @@ async function sendDiscordWebhook(target, payload) {
26262
26692
  if (!response.ok) throw new Error(`discord_delivery_failed:${response.status}`);
26263
26693
  }
26264
26694
  async function sendRuntimeEmail(config, payload) {
26265
- const response = await fetch("https://api.brevo.com/v3/smtp/email", {
26266
- method: "POST",
26267
- redirect: "error",
26268
- headers: { "api-key": config.apiKey, "content-type": "application/json" },
26269
- body: JSON.stringify({
26270
- sender: { email: config.from },
26271
- to: [{ email: config.to }],
26272
- subject: `[OpenMates ${payload.role}] ${payload.kind}`,
26273
- textContent: `${payload.sanitizedReason}
26695
+ await requestBrevo("/v3/smtp/email", "POST", config.apiKey, {
26696
+ sender: { email: config.from },
26697
+ to: [{ email: config.to }],
26698
+ subject: `[OpenMates ${payload.role}] ${payload.kind}`,
26699
+ textContent: `${payload.sanitizedReason}
26274
26700
  Checks: ${payload.checkIds.join(", ")}
26275
26701
  Time: ${payload.occurredAt}`
26276
- }),
26277
- signal: AbortSignal.timeout(1e4)
26278
26702
  });
26279
- if (!response.ok) throw new Error(`email_delivery_failed:${response.status}`);
26280
26703
  }
26281
26704
  async function deliverWithRetries(channel, send) {
26282
26705
  for (let attempt = 1; attempt <= 3; attempt += 1) {
@@ -28351,10 +28774,14 @@ function runtimeNotificationConfig(installPath) {
28351
28774
  const webhookSecret = value("OPENMATES_RUNTIME_HEALTH_WEBHOOK_SECRET");
28352
28775
  const allowLocalDevelopmentFixture = value("SERVER_ENVIRONMENT") === "development" && value("OPENMATES_RUNTIME_HEALTH_ALLOW_LOCAL_WEBHOOK_FIXTURE") === "true";
28353
28776
  const genericWebhook = webhookUrl && webhookSecret ? { url: webhookUrl, secret: webhookSecret, allowLocalDevelopmentFixture } : void 0;
28354
- const discordWebhookUrl = value("OPENMATES_RUNTIME_HEALTH_DISCORD_WEBHOOK_URL") || (deploymentMode === "self_host" ? value("OPENMATES_RUNTIME_HEALTH_DISCORD_WEBHOOK_URL_SELF_HOST") : serverEnvironment === "production" ? value("OPENMATES_RUNTIME_HEALTH_DISCORD_WEBHOOK_URL_PRODUCTION") || value("DISCORD_WEBHOOK_PROD_SMOKE") : value("OPENMATES_RUNTIME_HEALTH_DISCORD_WEBHOOK_URL_DEVELOPMENT") || value("DISCORD_WEBHOOK_DEV_SMOKE"));
28777
+ const canonicalDiscordWebhookUrl = deploymentMode === "self_host" ? value("DISCORD_WEBHOOK_OPERATIONAL_MONITORING_SELF_HOST") || value("OPENMATES_RUNTIME_HEALTH_DISCORD_WEBHOOK_URL_SELF_HOST") || value("OPENMATES_RUNTIME_HEALTH_DISCORD_WEBHOOK_URL") : serverEnvironment === "production" ? value("OPENMATES_RUNTIME_HEALTH_DISCORD_WEBHOOK_URL_PRODUCTION") || value("DISCORD_WEBHOOK_OPERATIONAL_MONITORING_PRODUCTION") : value("OPENMATES_RUNTIME_HEALTH_DISCORD_WEBHOOK_URL_DEVELOPMENT") || value("DISCORD_WEBHOOK_OPERATIONAL_MONITORING_DEVELOPMENT");
28778
+ const fallbackDiscordWebhookUrl = deploymentMode === "self_host" ? void 0 : serverEnvironment === "production" ? value("DISCORD_WEBHOOK_PROD_SMOKE") : value("DISCORD_WEBHOOK_DEV_NIGHTLY") || value("DISCORD_WEBHOOK_DEV_SMOKE");
28779
+ const discordWebhookUrl = canonicalDiscordWebhookUrl || fallbackDiscordWebhookUrl;
28355
28780
  return {
28356
28781
  email,
28357
28782
  discordWebhookUrl,
28783
+ discordDestinationSource: canonicalDiscordWebhookUrl ? "canonical" : fallbackDiscordWebhookUrl ? serverEnvironment === "production" ? "prod_smoke_fallback" : "dev_fallback" : "missing",
28784
+ discordFallbackUsed: !canonicalDiscordWebhookUrl && Boolean(fallbackDiscordWebhookUrl),
28358
28785
  genericWebhook
28359
28786
  };
28360
28787
  }
@@ -28903,7 +29330,9 @@ async function serverMonitoring(rest, flags) {
28903
29330
  state: receipt.state,
28904
29331
  attemptCount: receipt.attempt_count,
28905
29332
  occurredAt: receipt.occurred_at,
28906
- sanitizedFailureClass: receipt.sanitized_failure_class
29333
+ sanitizedFailureClass: receipt.sanitized_failure_class,
29334
+ destinationSource: receipt.destination_source,
29335
+ fallbackUsed: receipt.fallback_used
28907
29336
  }));
28908
29337
  const receiptDir = join6(installPath, ".openmates", "runtime-health", "receipts");
28909
29338
  mkdirSync5(receiptDir, { recursive: true, mode: 448 });
@@ -28998,7 +29427,13 @@ async function serverNotifications(rest, flags) {
28998
29427
  checkIds: ["monitor"],
28999
29428
  sanitizedReason: "operator_requested_delivery_test"
29000
29429
  });
29001
- const output = { command: "notifications test", role, configured: deliveries.length > 0, deliveries };
29430
+ const output = {
29431
+ command: "notifications test",
29432
+ role,
29433
+ configured: deliveries.length > 0,
29434
+ discordDestination: channel === "discord" || channel === "all" ? { source: notificationConfig.discordDestinationSource, fallbackUsed: notificationConfig.discordFallbackUsed } : void 0,
29435
+ deliveries
29436
+ };
29002
29437
  if (flags.json === true) printJson(output);
29003
29438
  else console.log(JSON.stringify(output, null, 2));
29004
29439
  if (deliveries.some((delivery) => delivery.status === "exhausted")) throw new Error("One or more notification delivery tests failed.");
@@ -29825,7 +30260,7 @@ Examples:
29825
30260
  openmates server features enable embed:code:application
29826
30261
  openmates server update
29827
30262
  openmates server update --dry-run
29828
- openmates server update --image-tag v0.17.0
30263
+ openmates server update --image-tag v0.16.0
29829
30264
  openmates server update --channel dev
29830
30265
  openmates server restart --rebuild
29831
30266
  `.trim());
@@ -30004,6 +30439,28 @@ function buildCodeRunStreamUrl(params) {
30004
30439
  const query = new URLSearchParams({ sessionId: params.sessionId, token: params.token });
30005
30440
  return `${base}/v1/code/run/${encodeURIComponent(params.executionId)}/stream?${query.toString()}`;
30006
30441
  }
30442
+ function formatCodeRunFinalStatusOutput(status, options = {}) {
30443
+ let output = "";
30444
+ if (options.includeOutput !== false && typeof status.output === "string" && status.output.length > 0) {
30445
+ output += status.output.endsWith("\n") ? status.output : `${status.output}
30446
+ `;
30447
+ }
30448
+ const artifactLines = formatCodeRunArtifactLines(status.artifacts);
30449
+ if (artifactLines.length > 0) {
30450
+ if (output.length > 0 && !output.endsWith("\n\n")) output += "\n";
30451
+ output += `Artifacts:
30452
+ ${artifactLines.join("\n")}
30453
+ `;
30454
+ }
30455
+ const skippedLines = formatCodeRunSkippedArtifactLines(status.skipped_artifacts);
30456
+ if (skippedLines.length > 0) {
30457
+ if (output.length > 0 && !output.endsWith("\n\n")) output += "\n";
30458
+ output += `Skipped artifacts:
30459
+ ${skippedLines.join("\n")}
30460
+ `;
30461
+ }
30462
+ return output;
30463
+ }
30007
30464
  function normalizeCodeRunPath(rawPath) {
30008
30465
  const path2 = rawPath.trim().replace(/\\/g, "/");
30009
30466
  if (!path2 || path2.includes("\0") || path2.startsWith("/") || path2.startsWith("~/") || /^[A-Za-z]:\//.test(path2)) {
@@ -30059,6 +30516,31 @@ function toList(value) {
30059
30516
  if (typeof value === "string") return value.split("\n").filter(Boolean);
30060
30517
  return [];
30061
30518
  }
30519
+ function formatCodeRunArtifactLines(value) {
30520
+ if (!Array.isArray(value)) return [];
30521
+ return value.filter((item) => item !== null && typeof item === "object" && !Array.isArray(item)).map((artifact) => {
30522
+ const path2 = stringValue(artifact.normalized_path) || stringValue(artifact.path) || "artifact";
30523
+ const mimeType = stringValue(artifact.mime_type) || "application/octet-stream";
30524
+ const sizeBytes = numberValue2(artifact.size_bytes);
30525
+ const size = sizeBytes === null ? "unknown size" : `${sizeBytes} bytes`;
30526
+ const downloadUrl = stringValue(artifact.download_url);
30527
+ return downloadUrl ? `- ${path2} (${mimeType}, ${size}; signed download available via --json)` : `- ${path2} (${mimeType}, ${size})`;
30528
+ });
30529
+ }
30530
+ function formatCodeRunSkippedArtifactLines(value) {
30531
+ if (!Array.isArray(value)) return [];
30532
+ return value.filter((item) => item !== null && typeof item === "object" && !Array.isArray(item)).map((artifact) => {
30533
+ const path2 = stringValue(artifact.normalized_path) || stringValue(artifact.path) || "artifact";
30534
+ const reason = stringValue(artifact.reason) || "skipped";
30535
+ return `- ${path2} (${reason})`;
30536
+ });
30537
+ }
30538
+ function stringValue(value) {
30539
+ return typeof value === "string" && value.length > 0 ? value : null;
30540
+ }
30541
+ function numberValue2(value) {
30542
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
30543
+ }
30062
30544
  function matchesAny(path2, patterns) {
30063
30545
  return patterns.some((pattern) => matchesPattern(path2, pattern));
30064
30546
  }
@@ -47055,7 +47537,7 @@ function stripQuotes(value) {
47055
47537
  }
47056
47538
  return value;
47057
47539
  }
47058
- function numberValue2(value) {
47540
+ function numberValue3(value) {
47059
47541
  if (typeof value === "number" && Number.isFinite(value)) return value;
47060
47542
  if (typeof value !== "string" || value.trim() === "") return null;
47061
47543
  const parsed = Number(value);
@@ -47216,11 +47698,11 @@ function plural(value, singular, pluralLabel = `${singular}s`) {
47216
47698
  }
47217
47699
  function buildMetadata(nodeType, type, record) {
47218
47700
  const parts = [labelForNodeType(nodeType, type)];
47219
- const lineCount = numberValue2(record.line_count ?? record.lineCount);
47220
- const pageCount = numberValue2(record.page_count ?? record.pageCount);
47221
- const wordCount = numberValue2(record.word_count ?? record.wordCount);
47222
- const duration = numberValue2(record.duration_seconds ?? record.durationSeconds);
47223
- const size = numberValue2(record.byte_length ?? record.size_bytes ?? record.sizeBytes);
47701
+ const lineCount = numberValue3(record.line_count ?? record.lineCount);
47702
+ const pageCount = numberValue3(record.page_count ?? record.pageCount);
47703
+ const wordCount = numberValue3(record.word_count ?? record.wordCount);
47704
+ const duration = numberValue3(record.duration_seconds ?? record.durationSeconds);
47705
+ const size = numberValue3(record.byte_length ?? record.size_bytes ?? record.sizeBytes);
47224
47706
  if (lineCount) parts.push(plural(lineCount, "line"));
47225
47707
  if (pageCount) parts.push(plural(pageCount, "page"));
47226
47708
  if (wordCount) parts.push(plural(wordCount, "word"));
@@ -47317,7 +47799,7 @@ function getEmbedFileReferences(embed) {
47317
47799
  const nodeType = inferNodeType(title, type);
47318
47800
  const url = urlForType(type, decoded);
47319
47801
  const mimeType = stringField2(decoded, ["mime_type", "file_type", "mimeType"]);
47320
- const createdAt = numberValue2(embed.created_at ?? embed.createdAt) ?? 0;
47802
+ const createdAt = numberValue3(embed.created_at ?? embed.createdAt) ?? 0;
47321
47803
  return [{
47322
47804
  embedId: normalizeEmbedId(embedId),
47323
47805
  contentRef: `embed:${normalizeEmbedId(embedId)}`,
@@ -48816,6 +49298,21 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
48816
49298
  hide_output: {
48817
49299
  text: "Hide output"
48818
49300
  },
49301
+ artifacts: {
49302
+ text: "Generated files"
49303
+ },
49304
+ skipped_artifacts: {
49305
+ text: "Skipped files"
49306
+ },
49307
+ download_artifact: {
49308
+ text: "Download"
49309
+ },
49310
+ download_unavailable: {
49311
+ text: "Download expired"
49312
+ },
49313
+ previous_versions: {
49314
+ text: "Previous versions"
49315
+ },
48819
49316
  hide_files: {
48820
49317
  text: "Hide files"
48821
49318
  },
@@ -49841,6 +50338,12 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
49841
50338
  }
49842
50339
  },
49843
50340
  apps: {
50341
+ file: {
50342
+ text: "File",
50343
+ description: {
50344
+ text: "Safely view metadata and download captured files without executing them."
50345
+ }
50346
+ },
49844
50347
  finance: {
49845
50348
  text: "Finance",
49846
50349
  description: {
@@ -74697,12 +75200,12 @@ async function handleProjectFiles(client, masterKey, rest, flags, context) {
74697
75200
  printProjectFileResult(action, project.projectId, source.source_id, result, flags);
74698
75201
  }
74699
75202
  var CliContractError = class extends Error {
75203
+ code;
74700
75204
  constructor(code, message) {
74701
75205
  super(message);
74702
75206
  this.code = code;
74703
75207
  this.name = "CliContractError";
74704
75208
  }
74705
- code;
74706
75209
  };
74707
75210
  function hasExplicitProjectContext(flags) {
74708
75211
  return flags.personal === true || typeof flags.team === "string" || typeof flags["team-id"] === "string";
@@ -78264,7 +78767,9 @@ async function handleCodeRun(client, flags, apiKey) {
78264
78767
  }
78265
78768
  const streamAuth = apiKey ? null : await client.getCodeRunStreamAuth();
78266
78769
  let finalStatus;
78770
+ let usedStream = false;
78267
78771
  if (streamAuth && result.stream_path) {
78772
+ usedStream = true;
78268
78773
  const url = buildCodeRunStreamUrl({
78269
78774
  apiUrl: client.apiUrl,
78270
78775
  executionId: result.execution_id,
@@ -78288,6 +78793,14 @@ async function handleCodeRun(client, flags, apiKey) {
78288
78793
  }
78289
78794
  if (flags.json === true) {
78290
78795
  printJson2({ ...result, final: finalStatus });
78796
+ } else {
78797
+ const finalOutput = formatCodeRunFinalStatusOutput(finalStatus, { includeOutput: !usedStream });
78798
+ if (finalOutput) process.stdout.write(finalOutput);
78799
+ }
78800
+ const finalExitCode = typeof finalStatus.exit_code === "number" ? finalStatus.exit_code : null;
78801
+ const finalState = typeof finalStatus.status === "string" ? finalStatus.status : "unknown";
78802
+ if (finalState !== "finished" || finalExitCode !== 0) {
78803
+ throw new Error(`Code Run ${finalState} with exit code ${finalExitCode ?? "unknown"}.`);
78291
78804
  }
78292
78805
  }
78293
78806
  async function streamCodeRunToTerminal(url, jsonMode) {
package/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  requireExactConfirmation,
9
9
  resolveProjectContext,
10
10
  serializeToYaml
11
- } from "./chunk-2E4EP5TA.js";
11
+ } from "./chunk-IRUJMHD5.js";
12
12
  import "./chunk-IWKP55ZB.js";
13
13
  import "./chunk-WBBDQZZI.js";
14
14
  export {
package/dist/index.d.ts CHANGED
@@ -34,6 +34,17 @@ declare const APP_SKILL_METADATA: readonly [{
34
34
  };
35
35
  readonly required: readonly ["prompt"];
36
36
  };
37
+ readonly output_schema: {
38
+ readonly type: "object";
39
+ readonly properties: {
40
+ readonly answer: {
41
+ readonly type: "string";
42
+ };
43
+ readonly conversation: {
44
+ readonly type: "string";
45
+ };
46
+ };
47
+ };
37
48
  }, {
38
49
  readonly app_id: "audio";
39
50
  readonly skill_id: "generate";
@@ -250,6 +261,23 @@ declare const APP_SKILL_METADATA: readonly [{
250
261
  };
251
262
  readonly required: readonly ["companies"];
252
263
  };
264
+ readonly output_schema: {
265
+ readonly type: "object";
266
+ readonly properties: {
267
+ readonly summary: {
268
+ readonly type: "string";
269
+ };
270
+ readonly result_count: {
271
+ readonly type: "integer";
272
+ };
273
+ readonly provider: {
274
+ readonly type: "string";
275
+ };
276
+ readonly results: {
277
+ readonly type: "array";
278
+ };
279
+ };
280
+ };
253
281
  }, {
254
282
  readonly app_id: "code";
255
283
  readonly skill_id: "search_repos";
@@ -309,6 +337,236 @@ declare const APP_SKILL_METADATA: readonly [{
309
337
  };
310
338
  readonly required: readonly ["library", "question"];
311
339
  };
340
+ }, {
341
+ readonly app_id: "code";
342
+ readonly skill_id: "run";
343
+ readonly app_namespace_ts: "code";
344
+ readonly skill_method_ts: "run";
345
+ readonly app_namespace_py: "code";
346
+ readonly skill_method_py: "run";
347
+ readonly description_key: "app_skills.code.run.description";
348
+ readonly description: "Run a code embed in an isolated E2B sandbox. Use automatically only for code the assistant created or edited in the current turn; ask the user before running unmodified user-supplied code or after the initial run plus two unprompted reruns. The sandbox receives code files from the current chat, installs supported dependency manifests, executes the selected file, streams terminal status, and returns safe artifact metadata. Pricing is 5 credits per started minute of sandbox runtime.";
349
+ readonly schema: {
350
+ readonly type: "object";
351
+ readonly properties: {
352
+ readonly requests: {
353
+ readonly type: "array";
354
+ readonly minItems: 1;
355
+ readonly maxItems: 10;
356
+ readonly description: "Array of direct or chat-bound Code Run requests for the custom REST/SDK route.";
357
+ readonly items: {
358
+ readonly type: "object";
359
+ readonly properties: {
360
+ readonly mode: {
361
+ readonly type: "string";
362
+ readonly enum: readonly ["direct", "chat_bound"];
363
+ readonly default: "direct";
364
+ readonly description: "Direct runs use caller-supplied files and stay transient; chat_bound runs use a chat/embed target and persist encrypted output.";
365
+ };
366
+ readonly entry_path: {
367
+ readonly type: "string";
368
+ readonly description: "Entrypoint file path for direct runs.";
369
+ };
370
+ readonly files: {
371
+ readonly type: "array";
372
+ readonly maxItems: 50;
373
+ readonly description: "Direct-run files with base64-encoded content. The backend never fetches local paths or URLs.";
374
+ readonly items: {
375
+ readonly type: "object";
376
+ readonly properties: {
377
+ readonly path: {
378
+ readonly type: "string";
379
+ };
380
+ readonly content_base64: {
381
+ readonly type: "string";
382
+ };
383
+ readonly language: {
384
+ readonly type: "string";
385
+ };
386
+ readonly mime_type: {
387
+ readonly type: "string";
388
+ readonly default: "text/plain";
389
+ };
390
+ readonly is_target: {
391
+ readonly type: "boolean";
392
+ readonly default: false;
393
+ };
394
+ };
395
+ readonly required: readonly ["path", "content_base64"];
396
+ };
397
+ };
398
+ readonly chat_id: {
399
+ readonly type: "string";
400
+ readonly description: "Chat ID for chat-bound runs.";
401
+ };
402
+ readonly target_embed_id: {
403
+ readonly type: "string";
404
+ readonly description: "Target code embed ID for chat-bound runs.";
405
+ };
406
+ readonly selected_embed_ids: {
407
+ readonly type: "array";
408
+ readonly items: {
409
+ readonly type: "string";
410
+ };
411
+ readonly description: "Optional related embed IDs to include in chat-bound runs.";
412
+ };
413
+ readonly dependency_installs: {
414
+ readonly type: "array";
415
+ readonly maxItems: 20;
416
+ readonly description: "Optional explicit dependency installs.";
417
+ readonly items: {
418
+ readonly type: "object";
419
+ readonly properties: {
420
+ readonly ecosystem: {
421
+ readonly type: "string";
422
+ readonly enum: readonly ["python", "npm"];
423
+ };
424
+ readonly packages: {
425
+ readonly type: "array";
426
+ readonly items: {
427
+ readonly type: "string";
428
+ };
429
+ };
430
+ };
431
+ readonly required: readonly ["ecosystem", "packages"];
432
+ };
433
+ };
434
+ readonly enable_internet: {
435
+ readonly type: "boolean";
436
+ readonly default: true;
437
+ readonly description: "Allow outbound internet access from the E2B sandbox.";
438
+ };
439
+ };
440
+ };
441
+ };
442
+ };
443
+ readonly required: readonly ["requests"];
444
+ };
445
+ readonly output_schema: {
446
+ readonly type: "object";
447
+ readonly properties: {
448
+ readonly results: {
449
+ readonly type: "array";
450
+ readonly items: {
451
+ readonly type: "object";
452
+ readonly properties: {
453
+ readonly execution_id: {
454
+ readonly type: "string";
455
+ };
456
+ readonly status: {
457
+ readonly type: "string";
458
+ };
459
+ readonly target_filename: {
460
+ readonly type: "string";
461
+ };
462
+ readonly files: {
463
+ readonly type: "array";
464
+ readonly items: {
465
+ readonly type: "string";
466
+ };
467
+ };
468
+ readonly credits_per_minute: {
469
+ readonly type: "integer";
470
+ };
471
+ readonly persisted_output: {
472
+ readonly type: "boolean";
473
+ };
474
+ readonly stream_path: {
475
+ readonly type: "string";
476
+ };
477
+ readonly status_path: {
478
+ readonly type: "string";
479
+ };
480
+ readonly final: {
481
+ readonly type: "object";
482
+ readonly description: "Final status fetched from status_path by SDK helpers. Direct runs remain transient.";
483
+ readonly properties: {
484
+ readonly status: {
485
+ readonly type: "string";
486
+ };
487
+ readonly exit_code: {
488
+ readonly type: "integer";
489
+ };
490
+ readonly output: {
491
+ readonly type: "string";
492
+ };
493
+ readonly error: {
494
+ readonly type: "string";
495
+ };
496
+ readonly duration_seconds: {
497
+ readonly type: "number";
498
+ };
499
+ readonly charged_credits: {
500
+ readonly type: "integer";
501
+ };
502
+ readonly charged_minutes: {
503
+ readonly type: "integer";
504
+ };
505
+ readonly artifacts: {
506
+ readonly type: "array";
507
+ readonly items: {
508
+ readonly type: "object";
509
+ readonly properties: {
510
+ readonly path: {
511
+ readonly type: "string";
512
+ };
513
+ readonly normalized_path: {
514
+ readonly type: "string";
515
+ };
516
+ readonly mime_type: {
517
+ readonly type: "string";
518
+ };
519
+ readonly kind: {
520
+ readonly type: "string";
521
+ };
522
+ readonly size_bytes: {
523
+ readonly type: "integer";
524
+ };
525
+ readonly status: {
526
+ readonly type: "string";
527
+ };
528
+ readonly asset_id: {
529
+ readonly type: "string";
530
+ };
531
+ readonly file_id: {
532
+ readonly type: "string";
533
+ };
534
+ readonly variant: {
535
+ readonly type: "string";
536
+ };
537
+ readonly version: {
538
+ readonly type: "integer";
539
+ };
540
+ readonly download_url: {
541
+ readonly type: "string";
542
+ };
543
+ };
544
+ };
545
+ };
546
+ readonly skipped_artifacts: {
547
+ readonly type: "array";
548
+ readonly items: {
549
+ readonly type: "object";
550
+ readonly properties: {
551
+ readonly path: {
552
+ readonly type: "string";
553
+ };
554
+ readonly normalized_path: {
555
+ readonly type: "string";
556
+ };
557
+ readonly reason: {
558
+ readonly type: "string";
559
+ };
560
+ };
561
+ };
562
+ };
563
+ };
564
+ };
565
+ };
566
+ };
567
+ };
568
+ };
569
+ };
312
570
  }, {
313
571
  readonly app_id: "code";
314
572
  readonly skill_id: "image_to_html";
@@ -654,6 +912,17 @@ declare const APP_SKILL_METADATA: readonly [{
654
912
  };
655
913
  readonly required: readonly ["requests"];
656
914
  };
915
+ readonly output_schema: {
916
+ readonly type: "object";
917
+ readonly properties: {
918
+ readonly summary: {
919
+ readonly type: "string";
920
+ };
921
+ readonly result_count: {
922
+ readonly type: "integer";
923
+ };
924
+ };
925
+ };
657
926
  }, {
658
927
  readonly app_id: "fitness";
659
928
  readonly skill_id: "search_locations";
@@ -1428,6 +1697,17 @@ declare const APP_SKILL_METADATA: readonly [{
1428
1697
  };
1429
1698
  readonly required: readonly ["requests"];
1430
1699
  };
1700
+ readonly output_schema: {
1701
+ readonly type: "object";
1702
+ readonly properties: {
1703
+ readonly summary: {
1704
+ readonly type: "string";
1705
+ };
1706
+ readonly result_count: {
1707
+ readonly type: "integer";
1708
+ };
1709
+ };
1710
+ };
1431
1711
  }, {
1432
1712
  readonly app_id: "nutrition";
1433
1713
  readonly skill_id: "search_recipes";
@@ -2754,6 +3034,20 @@ declare const APP_SKILL_METADATA: readonly [{
2754
3034
  };
2755
3035
  readonly required: readonly ["location"];
2756
3036
  };
3037
+ readonly output_schema: {
3038
+ readonly type: "object";
3039
+ readonly properties: {
3040
+ readonly summary: {
3041
+ readonly type: "string";
3042
+ };
3043
+ readonly rain_probability: {
3044
+ readonly type: "number";
3045
+ };
3046
+ readonly max_temperature_c: {
3047
+ readonly type: "number";
3048
+ };
3049
+ };
3050
+ };
2757
3051
  }, {
2758
3052
  readonly app_id: "weather";
2759
3053
  readonly skill_id: "rain_radar";
@@ -2850,6 +3144,17 @@ declare const APP_SKILL_METADATA: readonly [{
2850
3144
  };
2851
3145
  readonly required: readonly ["requests"];
2852
3146
  };
3147
+ readonly output_schema: {
3148
+ readonly type: "object";
3149
+ readonly properties: {
3150
+ readonly summary: {
3151
+ readonly type: "string";
3152
+ };
3153
+ readonly result_count: {
3154
+ readonly type: "integer";
3155
+ };
3156
+ };
3157
+ };
2853
3158
  }, {
2854
3159
  readonly app_id: "web";
2855
3160
  readonly skill_id: "read";
@@ -3041,6 +3346,12 @@ declare class CodeAppSkills {
3041
3346
  * Skill: code/remove_secrets
3042
3347
  */
3043
3348
  removeSecrets<T = unknown>(input: SkillInput, options?: AppSkillRunOptions): Promise<T>;
3349
+ /**
3350
+ * Run a code embed in an isolated E2B sandbox. Use automatically only for code the assistant created or edited in the current turn; ask the user before running unmodified user-supplied code or after the initial run plus two unprompted reruns. The sandbox receives code files from the current chat, installs supported dependency manifests, executes the selected file, streams terminal status, and returns safe artifact metadata. Pricing is 5 credits per started minute of sandbox runtime.
3351
+ * Description key: app_skills.code.run.description
3352
+ * Skill: code/run
3353
+ */
3354
+ run<T = unknown>(input: SkillInput, options?: AppSkillRunOptions): Promise<T>;
3044
3355
  /**
3045
3356
  * Search GitHub repositories. Use this instead of web.search whenever the user asks to find GitHub repos, repositories, open-source libraries, starred repos, or repo examples by topic, language, framework, or project need. Returns licensed repository embeds. Costs 10 credits per search.
3046
3357
  * Description key: code.search_repos.description
@@ -4266,6 +4577,9 @@ declare class OpenMates {
4266
4577
  private publicHeaders;
4267
4578
  private parseResponse;
4268
4579
  private resolveAsyncSkillResponse;
4580
+ private resolveCodeRunSkillResponse;
4581
+ private pollCodeRunUntilComplete;
4582
+ private normalizeCodeRunStatusPath;
4269
4583
  private pollTaskUntilComplete;
4270
4584
  private safeJson;
4271
4585
  private wrapResolvedSkillResult;
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  renderPlanList,
40
40
  renderSupportInfo,
41
41
  serializeToYaml
42
- } from "./chunk-2E4EP5TA.js";
42
+ } from "./chunk-IRUJMHD5.js";
43
43
  import "./chunk-IWKP55ZB.js";
44
44
  import "./chunk-WBBDQZZI.js";
45
45
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmates",
3
- "version": "0.17.0-alpha.0",
3
+ "version": "0.17.0-alpha.10",
4
4
  "description": "OpenMates CLI and SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",