@on-mission/sdk 0.1.8 → 0.1.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.d.ts CHANGED
@@ -836,6 +836,27 @@ type MissionSDK = {
836
836
  */
837
837
  declare function createMissionSDK(options?: MissionSDKOptions): MissionSDK;
838
838
 
839
+ /**
840
+ * A skill tool failure that carries the upstream HTTP status.
841
+ *
842
+ * Skill clients (Airtable, Gmail, …) call third-party REST APIs. When one of
843
+ * those APIs rejects a request — a 422 for a bad field name, a 404 for a
844
+ * missing record — the client throws. A plain `Error` loses the status: the
845
+ * skill runtime's tool dispatch (`POST /_mission/tools/:toolName`) then can't
846
+ * tell a client mistake from a server fault and blankets every throw to
847
+ * HTTP 500. That 500 propagates to the executor, which (a) stamps a misleading
848
+ * "HTTP 500" into the model-facing tool result and (b) treats a deterministic
849
+ * client error as a retryable server fault.
850
+ *
851
+ * Throw this instead of a bare `Error` so the real status survives the hop.
852
+ * The dispatch layer reads `statusCode` and returns it verbatim, so a 422
853
+ * stays a 422 all the way to the model.
854
+ */
855
+ declare class SkillToolHttpError extends Error {
856
+ readonly statusCode: number;
857
+ constructor(statusCode: number, message: string);
858
+ }
859
+
839
860
  /**
840
861
  * Mission SDK
841
862
  *
@@ -867,4 +888,4 @@ type WebhookResult = {
867
888
  response?: WebhookResponse;
868
889
  };
869
890
 
870
- export { type AgentMessage, type ApiClient, type AttachmentLimits, type AuthCredentials, type AuthModule, type ConfigModule, EmailAttachments, type EventHandler, type EventHandlerRegistry, FileTransferTimeoutError, type FilesModule, type IngressHandler, type IngressModule, type IngressRequest, type IngressResponse, type IngressStreamEvents, type IngressUrl, type LogModule, type MimeBodyParts, type MissionSDK, type MissionSDKOptions, type OAuthCredentials, type RedeemedAttachment, type SendIntentClaimOutcome, type SendIntentCompletion, type SendIntentRecord, type SendIntentStatus, type SendIntentsModule, type SendMessageId, type SendMessageIdInput, type SkillContext, type SkillEvent, type ToolHandler, type ToolsModule, type WebhookRequest, type WebhookResponse, type WebhookResult, clearDebugLog, createMissionSDK, debugLog };
891
+ export { type AgentMessage, type ApiClient, type AttachmentLimits, type AuthCredentials, type AuthModule, type ConfigModule, EmailAttachments, type EventHandler, type EventHandlerRegistry, FileTransferTimeoutError, type FilesModule, type IngressHandler, type IngressModule, type IngressRequest, type IngressResponse, type IngressStreamEvents, type IngressUrl, type LogModule, type MimeBodyParts, type MissionSDK, type MissionSDKOptions, type OAuthCredentials, type RedeemedAttachment, type SendIntentClaimOutcome, type SendIntentCompletion, type SendIntentRecord, type SendIntentStatus, type SendIntentsModule, type SendMessageId, type SendMessageIdInput, type SkillContext, type SkillEvent, SkillToolHttpError, type ToolHandler, type ToolsModule, type WebhookRequest, type WebhookResponse, type WebhookResult, clearDebugLog, createMissionSDK, debugLog };
package/dist/index.js CHANGED
@@ -13798,10 +13798,6 @@ var eventSubscriptionSchema = external_exports.object({
13798
13798
  eventType: external_exports.string().min(1).describe("Specific event type to subscribe to."),
13799
13799
  reason: external_exports.string().min(1).describe("Why this event matters for the mission.")
13800
13800
  });
13801
- var appSubscriptionSchema = external_exports.object({
13802
- app: external_exports.string().min(1).describe("App slug to watch at the app level."),
13803
- reason: external_exports.string().min(1).describe("Why this app-level subscription matters.")
13804
- });
13805
13801
  var toolSettingSchema = external_exports.enum(["disabled", "approval", "enabled"]).describe("Execution setting for the tool.");
13806
13802
  var promiseSchema = external_exports.object({
13807
13803
  text: external_exports.string().min(1).describe("Promise text to add to the plan."),
@@ -13829,40 +13825,37 @@ var agentPlanPatchSchema = external_exports.discriminatedUnion("op", [
13829
13825
  context: inputContextSchema.describe("New planner input context.")
13830
13826
  }),
13831
13827
  external_exports.object({
13832
- op: external_exports.literal("add_plan_schedule").describe("Append a new schedule to the plan."),
13833
- schedule: scheduleSchema.describe("Schedule to add. Omit the id field.")
13828
+ op: external_exports.literal("add_plan_schedule").describe("Append a new schedule trigger to the agent."),
13829
+ schedule: scheduleSchema.describe("Schedule trigger to add.")
13834
13830
  }),
13835
13831
  external_exports.object({
13836
- op: external_exports.literal("remove_plan_schedule").describe("Remove an existing schedule by id."),
13837
- id: external_exports.string().min(1).describe("Schedule id copied from read_agent_plan.")
13832
+ op: external_exports.literal("remove_plan_schedule").describe("Remove an existing schedule trigger by label."),
13833
+ label: external_exports.string().min(1).describe(
13834
+ "Label of the schedule to remove. Schedule triggers carry no id \u2014 the label is the identity (it also derives the deterministic Temporal schedule handle)."
13835
+ )
13838
13836
  }),
13839
13837
  external_exports.object({
13840
- op: external_exports.literal("update_plan_schedule").describe("Replace an existing schedule by id."),
13841
- id: external_exports.string().min(1).describe("Schedule id copied from read_agent_plan."),
13842
- schedule: scheduleSchema.describe(
13843
- "Full replacement schedule. Omit the id field."
13844
- )
13838
+ op: external_exports.literal("update_plan_schedule").describe("Replace an existing schedule trigger by label."),
13839
+ label: external_exports.string().min(1).describe(
13840
+ "Label of the schedule to replace. Schedule triggers carry no id \u2014 the label is the identity."
13841
+ ),
13842
+ schedule: scheduleSchema.describe("Full replacement schedule trigger.")
13845
13843
  }),
13846
13844
  external_exports.object({
13847
- op: external_exports.literal("add_plan_event_subscription").describe("Append a new event subscription to the plan."),
13845
+ op: external_exports.literal("add_plan_event_subscription").describe("Append a new event-subscription trigger to the agent."),
13848
13846
  eventSubscription: eventSubscriptionSchema.describe(
13849
- "Event subscription to add. Omit the id field."
13847
+ "Event-subscription trigger to add."
13850
13848
  )
13851
13849
  }),
13852
13850
  external_exports.object({
13853
- op: external_exports.literal("remove_plan_event_subscription").describe("Remove an existing event subscription by id."),
13854
- id: external_exports.string().min(1).describe("Event subscription id copied from read_agent_plan.")
13855
- }),
13856
- external_exports.object({
13857
- op: external_exports.literal("add_plan_app_subscription").describe("Append a new app subscription to the plan."),
13858
- appSubscription: appSubscriptionSchema.describe(
13859
- "App subscription to add. Omit the id field."
13851
+ op: external_exports.literal("remove_plan_event_subscription").describe(
13852
+ "Remove an existing event-subscription trigger by (app, eventType)."
13853
+ ),
13854
+ app: external_exports.string().min(1).describe("App slug of the subscription to remove."),
13855
+ eventType: external_exports.string().min(1).describe(
13856
+ "Event type of the subscription to remove. Event triggers carry no id \u2014 (app, eventType) is the identity."
13860
13857
  )
13861
13858
  }),
13862
- external_exports.object({
13863
- op: external_exports.literal("remove_plan_app_subscription").describe("Remove an existing app subscription by id."),
13864
- id: external_exports.string().min(1).describe("App subscription id copied from read_agent_plan.")
13865
- }),
13866
13859
  external_exports.object({
13867
13860
  op: external_exports.literal("set_plan_tool_setting").describe("Replace the setting for an existing tool entry."),
13868
13861
  toolName: qualifiedToolNameSchema.describe(
@@ -14131,8 +14124,8 @@ var tryParseId = (model, raw) => {
14131
14124
 
14132
14125
  // ../models/src/governance.ts
14133
14126
  var qualifiedToolNameSchema2 = external_exports.string().max(200, "qualified tool name must be \u2264200 chars").regex(
14134
- /^[A-Za-z0-9_.-]+__[A-Za-z0-9_.-]+$/,
14135
- "qualified tool name must be `namespace__toolName`"
14127
+ /^(?:[A-Za-z0-9_.-]+__[A-Za-z0-9_.-]+|(?!.*__)[A-Za-z0-9_.-]+)$/,
14128
+ "qualified tool name must be bare `toolName` or `namespace__toolName`"
14136
14129
  ).transform((name) => name);
14137
14130
  var brandedIdSchema = (model) => external_exports.string().max(64).superRefine((raw, ctx) => {
14138
14131
  if (tryParseId(model, raw) === null) {
@@ -14183,6 +14176,31 @@ var thresholdKinds = new Set(
14183
14176
  thresholdKindValues
14184
14177
  );
14185
14178
 
14179
+ // ../models/src/schedule-input.ts
14180
+ var scheduleInputItemSchema = external_exports.object({
14181
+ label: external_exports.string().min(1).max(200).describe("Stable schedule label unique per agent."),
14182
+ intent: external_exports.string().min(1).max(2e3).describe("What the schedule should make the agent do."),
14183
+ cron: external_exports.string().min(1).max(200).describe("Cron expression in canonical storage format."),
14184
+ timezone: external_exports.string().min(1).max(64).describe(
14185
+ `IANA timezone for cron interpretation. Use the user's current timezone from the environment context unless they name a different one (e.g. "in London time"). If no timezone is in context and the user has not named one, you MUST ask the user \u2014 never supply a guessed or inferred zone, and never default to UTC. An unconfirmed guess is worse than asking.`
14186
+ ),
14187
+ status: external_exports.enum(["active", "paused"]).describe("Whether the schedule should exist in Temporal.")
14188
+ });
14189
+ var scheduleInputArraySchema = external_exports.array(scheduleInputItemSchema).max(50).superRefine((schedules, ctx) => {
14190
+ const seen = /* @__PURE__ */ new Set();
14191
+ for (const s of schedules) {
14192
+ if (seen.has(s.label)) {
14193
+ ctx.addIssue({
14194
+ code: "custom",
14195
+ message: `Duplicate schedule label: ${s.label}`,
14196
+ path: ["label"]
14197
+ });
14198
+ return;
14199
+ }
14200
+ seen.add(s.label);
14201
+ }
14202
+ });
14203
+
14186
14204
  // ../models/src/skill-runtime/result.ts
14187
14205
  var changeSourceSchema = external_exports.union([
14188
14206
  external_exports.literal("broker"),
@@ -14394,10 +14412,83 @@ var stagingProvenanceSchema = zod_default.object({
14394
14412
  });
14395
14413
  var sha256HexSchema = zod_default.string().regex(/^[a-f0-9]{64}$/, "expected a lowercase sha256 hex").brand();
14396
14414
 
14415
+ // ../models/src/streaming.ts
14416
+ var DEVICE_TOOL_RESULT_BODY_LIMIT_BYTES = 4 * 1024 * 1024;
14417
+
14397
14418
  // ../models/src/token-unit.ts
14398
14419
  var MAX = Number.MAX_SAFE_INTEGER;
14399
14420
  var MAX_BIGINT = BigInt(MAX);
14400
14421
 
14422
+ // ../models/src/tools.ts
14423
+ var DEVICE_WRITE_TOOL_NAME_LIST = [
14424
+ "file_write",
14425
+ "file_update",
14426
+ "file_apply",
14427
+ "pdf_create",
14428
+ "pdf_edit",
14429
+ "word_create",
14430
+ "word_edit",
14431
+ "excel_create",
14432
+ "excel_edit"
14433
+ ];
14434
+ var DEVICE_WRITE_TOOL_NAMES = new Set(
14435
+ DEVICE_WRITE_TOOL_NAME_LIST
14436
+ );
14437
+ var DEVICE_DELIVERABLE_TOOL_NAME_LIST = [
14438
+ ...DEVICE_WRITE_TOOL_NAME_LIST,
14439
+ "file_move"
14440
+ ];
14441
+ var DEVICE_READ_TOOL_NAME_LIST = [
14442
+ "file_read",
14443
+ "file_list",
14444
+ "file_find",
14445
+ "excel_read",
14446
+ "word_read",
14447
+ "pdf_read",
14448
+ "pdf_render_page"
14449
+ ];
14450
+ var DEVICE_READ_TOOL_NAMES = new Set(
14451
+ DEVICE_READ_TOOL_NAME_LIST
14452
+ );
14453
+ var PLATFORM_READ_OR_GATHER_TOOL_NAME_LIST = [
14454
+ // Search / discovery over the library, catalog, and activity store.
14455
+ "library_search",
14456
+ "library_expand",
14457
+ "browse_library",
14458
+ "describe_library",
14459
+ "search_catalog",
14460
+ // Doc / conversation-history & memory reads.
14461
+ "conversation_history_search",
14462
+ "conversation_history_read",
14463
+ "memory_search",
14464
+ // Agent / workspace / connection / inbound state reads.
14465
+ "read_agent_state",
14466
+ "read_agent_plan",
14467
+ "read_agent_config",
14468
+ "list_pending_items",
14469
+ "list_connected_apps",
14470
+ "list_devices",
14471
+ "list_agents",
14472
+ "get_workspace_settings",
14473
+ "view_inbound_access",
14474
+ // Activity (analytics) reads / queries.
14475
+ "query_activity",
14476
+ "describe_activity_schema",
14477
+ "execute_activity_sql",
14478
+ // Self / clock reads.
14479
+ "self_read_mission",
14480
+ "self_read_config",
14481
+ "get_current_time",
14482
+ // Sandbox reads.
14483
+ "read_sandbox_file",
14484
+ "list_sandbox_files",
14485
+ // Library stage-out mints a single-use READ FileRef for a granted file.
14486
+ "library_stage_out"
14487
+ ];
14488
+ var PLATFORM_READ_OR_GATHER_TOOL_NAMES = new Set(
14489
+ PLATFORM_READ_OR_GATHER_TOOL_NAME_LIST
14490
+ );
14491
+
14401
14492
  // src/email-attachments.ts
14402
14493
  import { createHash, randomBytes } from "crypto";
14403
14494
  var GMAIL_ATTACHMENT_LIMITS = {
@@ -15294,6 +15385,16 @@ function createSendIntentsModule(api2) {
15294
15385
  return { claim, markSent, release };
15295
15386
  }
15296
15387
 
15388
+ // src/skill-tool-http-error.ts
15389
+ var SkillToolHttpError = class extends Error {
15390
+ statusCode;
15391
+ constructor(statusCode, message) {
15392
+ super(message);
15393
+ this.name = "SkillToolHttpError";
15394
+ this.statusCode = statusCode;
15395
+ }
15396
+ };
15397
+
15297
15398
  // src/tool-registry.ts
15298
15399
  function createToolRegistry() {
15299
15400
  const handlers = /* @__PURE__ */ new Map();
@@ -15326,6 +15427,11 @@ function createToolRegistry() {
15326
15427
  }
15327
15428
 
15328
15429
  // src/sdk.ts
15430
+ var skillToolStatus = (err) => {
15431
+ if (err instanceof SkillToolHttpError) return err.statusCode;
15432
+ if (err instanceof Error && err.message.startsWith("Unknown tool")) return 404;
15433
+ return 500;
15434
+ };
15329
15435
  var HEARTBEAT_INTERVAL_MS = (() => {
15330
15436
  const fromEnv = process.env.MISSION_HEARTBEAT_INTERVAL_MS;
15331
15437
  if (fromEnv) {
@@ -15558,7 +15664,12 @@ function createMissionSDK(options) {
15558
15664
  const message = err instanceof Error ? err.message : String(err);
15559
15665
  logStderr(`[SDK] Tool call '${toolName}' failed: ${message}`);
15560
15666
  return {
15561
- status: err instanceof Error && err.message.startsWith("Unknown tool") ? 404 : 500,
15667
+ // Preserve the upstream status when the client knew it: a third-party
15668
+ // 422 (bad field) must not masquerade as a 500 (server fault), or the
15669
+ // executor mislabels the model-facing result and treats a
15670
+ // deterministic client error as retryable. Fall back to 404 for an
15671
+ // unknown tool, else 500 for a genuinely unexpected throw.
15672
+ status: skillToolStatus(err),
15562
15673
  body: JSON.stringify({ error: message })
15563
15674
  };
15564
15675
  }
@@ -15724,6 +15835,7 @@ export {
15724
15835
  EmailAttachments,
15725
15836
  FileTransferTimeoutError,
15726
15837
  MAX_STAGING_UPLOAD_BYTES,
15838
+ SkillToolHttpError,
15727
15839
  clearDebugLog,
15728
15840
  createMissionSDK,
15729
15841
  debugLog,