@mindstudio-ai/agent 0.1.100 → 0.1.102

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
@@ -1968,12 +1968,14 @@ var Store = class {
1968
1968
  async put(content, options) {
1969
1969
  const ext = extensionFor(options?.filename);
1970
1970
  const key = options?.key ?? (options?.contentAddressed ? `${createHash("sha256").update(content).digest("hex")}${ext}` : `${randomUUID()}${ext}`);
1971
+ const cacheControl = options?.cacheControl ?? (!options?.key && this._access === "public" ? "public, max-age=31536000, immutable" : void 0);
1971
1972
  const meta = await this._call("put", {
1972
1973
  store: this._store,
1973
1974
  access: this._access,
1974
1975
  key,
1975
1976
  body: toBase64(content),
1976
- ...options?.contentType ? { contentType: options.contentType } : {}
1977
+ ...options?.contentType ? { contentType: options.contentType } : {},
1978
+ ...cacheControl ? { cacheControl } : {}
1977
1979
  });
1978
1980
  return this._toFile(key, meta);
1979
1981
  }
@@ -2082,7 +2084,8 @@ var Store = class {
2082
2084
  key,
2083
2085
  ...options?.contentType ? { contentType: options.contentType } : {},
2084
2086
  ...maxSize ? { maxSize } : {},
2085
- ...options?.expiresIn ? { expiresIn: options.expiresIn } : {}
2087
+ ...options?.expiresIn ? { expiresIn: options.expiresIn } : {},
2088
+ ...options?.cacheControl ? { cacheControl: options.cacheControl } : {}
2086
2089
  });
2087
2090
  return {
2088
2091
  key,
@@ -2275,6 +2278,9 @@ function createVoice(call) {
2275
2278
  };
2276
2279
  }
2277
2280
 
2281
+ // src/task/index.ts
2282
+ import { randomUUID as randomUUID2 } from "crypto";
2283
+
2278
2284
  // src/generated/metadata.ts
2279
2285
  var stepMetadata = {
2280
2286
  "activeCampaignAddNote": {
@@ -3134,28 +3140,28 @@ var stepMetadata = {
3134
3140
  "scrapeUrl": {
3135
3141
  stepType: "scrapeUrl",
3136
3142
  description: "Extract text, HTML, or structured content from one or more web pages.",
3137
- usageNotes: '- Accepts a single URL or multiple URLs (as a JSON array, comma-separated, or newline-separated).\n- Output format controls the result shape: "text" returns markdown, "html" returns raw HTML, "json" returns structured scraper data.\n- Can optionally capture a screenshot of each page.',
3138
- inputSchema: { "type": "object", "properties": { "url": { "type": "string", "description": "URL(s) to scrape. Accepts a single URL, JSON array, or comma/newline-separated list" }, "service": { "enum": ["default", "firecrawl"], "type": "string", "description": "Scraping service to use" }, "autoEnhance": { "type": "boolean", "description": "Whether to enable enhanced scraping for social media URLs (e.g. Twitter, LinkedIn)" }, "outputFormat": { "enum": ["text", "json", "html"], "type": "string", "description": "Output format: text returns markdown, html returns raw HTML, json returns structured scraper data" }, "pageOptions": { "type": "object", "properties": { "onlyMainContent": { "type": "boolean", "description": "Whether to extract only the main content of the page, excluding navigation, footers, etc." }, "screenshot": { "type": "boolean", "description": "Whether to capture a screenshot of the page" }, "waitFor": { "type": "number", "description": "Milliseconds to wait before scraping (0 for immediate)" }, "replaceAllPathsWithAbsolutePaths": { "type": "boolean", "description": "Whether to convert relative URLs to absolute URLs in the result" }, "headers": { "type": "object", "properties": {}, "required": [], "description": "Custom HTTP request headers as key-value pairs" }, "removeTags": { "type": "array", "items": { "type": "string" }, "description": "HTML tags to remove from the scraped result" }, "mobile": { "type": "boolean", "description": "Whether to scrape using a mobile user-agent" } }, "required": ["onlyMainContent", "screenshot", "waitFor", "replaceAllPathsWithAbsolutePaths", "headers", "removeTags", "mobile"], "description": "Page-level scraping options (content filtering, screenshots, headers, etc.)" } }, "required": ["url"] },
3139
- outputSchema: { "type": "object", "properties": { "content": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "object", "properties": { "text": { "type": "string", "description": "Markdown/plain-text content of the scraped page" }, "html": { "type": "string", "description": "Raw HTML content of the scraped page" }, "json": { "type": "object", "properties": {}, "required": [], "description": "Structured data extracted from the page" }, "screenshotUrl": { "type": "string", "description": "Screenshot URL of the page (if requested)" }, "metadata": { "type": "object", "properties": { "title": { "type": "string", "description": "Page title" }, "description": { "type": "string", "description": "Page meta description" }, "url": { "type": "string", "description": "Canonical URL" }, "image": { "type": "string", "description": "Open Graph image URL" } }, "required": ["title", "description", "url", "image"], "description": "Page metadata (Open Graph / meta tags)" }, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": ["code", "message"], "description": "Set when the scrape failed. `text`/`html` still carry the human-readable error so existing callers behave as before, but callers that care \u2014 billing, in particular \u2014 can tell a failure from real page content." } }, "required": ["text", "html"] }, { "type": "array", "items": { "type": "object", "properties": { "text": { "type": "string", "description": "Markdown/plain-text content of the scraped page" }, "html": { "type": "string", "description": "Raw HTML content of the scraped page" }, "json": { "type": "object", "properties": {}, "required": [], "description": "Structured data extracted from the page" }, "screenshotUrl": { "type": "string", "description": "Screenshot URL of the page (if requested)" }, "metadata": { "type": "object", "properties": { "title": { "type": "string", "description": "Page title" }, "description": { "type": "string", "description": "Page meta description" }, "url": { "type": "string", "description": "Canonical URL" }, "image": { "type": "string", "description": "Open Graph image URL" } }, "required": ["title", "description", "url", "image"], "description": "Page metadata (Open Graph / meta tags)" }, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": ["code", "message"], "description": "Set when the scrape failed. `text`/`html` still carry the human-readable error so existing callers behave as before, but callers that care \u2014 billing, in particular \u2014 can tell a failure from real page content." } }, "required": ["text", "html"] } }] }, "screenshot": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] } }, "required": ["content"] }
3143
+ usageNotes: '- Accepts a single URL or multiple URLs (as a JSON array, comma-separated, or newline-separated).\n- Output format controls the result shape: "text" returns markdown, "html" returns raw HTML, "json" returns structured scraper data, "summary" returns a model-written summary and requires the "firecrawl" service.\n- Can optionally capture a screenshot of each page.\n- Handles bot protection automatically; no proxy or rendering configuration is needed.',
3144
+ inputSchema: { "type": "object", "properties": { "url": { "type": "string", "description": "URL(s) to scrape. Accepts a single URL, JSON array, or comma/newline-separated list" }, "service": { "enum": ["default", "firecrawl"], "type": "string", "description": "Scraping service to use" }, "autoEnhance": { "type": "boolean", "description": "No longer selects a provider \u2014 the default service's anti-bot engine decides per request how hard to work. Retained because existing workflows set it and the builder still renders it." }, "outputFormat": { "enum": ["text", "json", "html", "summary"], "type": "string", "description": "Output format: text returns markdown, html returns raw HTML, json returns structured scraper data, summary returns a model-written summary (Firecrawl only)" }, "pageOptions": { "type": "object", "properties": { "onlyMainContent": { "type": "boolean", "description": "Whether to extract only the main content of the page, excluding navigation, footers, etc." }, "screenshot": { "type": "boolean", "description": "Whether to capture a screenshot of the page" }, "waitFor": { "type": "number", "description": "Milliseconds to wait before scraping (0 for immediate)" }, "replaceAllPathsWithAbsolutePaths": { "type": "boolean", "description": "Whether to convert relative URLs to absolute URLs in the result" }, "headers": { "type": "object", "properties": {}, "required": [], "description": "Custom HTTP request headers as key-value pairs" }, "removeTags": { "type": "array", "items": { "type": "string" }, "description": "HTML tags to remove from the scraped result" }, "mobile": { "type": "boolean", "description": "Whether to scrape using a mobile user-agent" } }, "required": ["onlyMainContent", "screenshot", "waitFor", "replaceAllPathsWithAbsolutePaths", "headers", "removeTags", "mobile"], "description": "Page-level scraping options (content filtering, screenshots, headers, etc.)" } }, "required": ["url"] },
3145
+ outputSchema: { "type": "object", "properties": { "content": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "object", "properties": { "text": { "type": "string", "description": "Markdown/plain-text content of the scraped page" }, "html": { "type": "string", "description": "Raw HTML content of the scraped page" }, "json": { "type": "object", "properties": {}, "required": [], "description": "Structured data extracted from the page" }, "screenshotUrl": { "type": "string", "description": "Screenshot URL of the page (if requested)" }, "metadata": { "type": "object", "properties": { "title": { "type": "string", "description": "Page title" }, "description": { "type": "string", "description": "Page meta description" }, "url": { "type": "string", "description": "Canonical URL" }, "image": { "type": "string", "description": "Open Graph image URL" } }, "required": ["title", "description", "url", "image"], "description": "Page metadata (Open Graph / meta tags)" }, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": ["code", "message"], "description": "Set when the scrape failed. `text`/`html` still carry the human-readable error so existing callers behave as before, but callers that care \u2014 billing, in particular \u2014 can tell a failure from real page content." }, "costUnits": { "type": "number", "description": "What the provider actually charged, when it tells us. Scrapfly returns an exact per-request credit total that varies with how hard the target fought back (6 for an unprotected page, 80 for Glassdoor), so billing a flat rate would either overcharge the easy case or eat the hard one. Providers that report nothing leave this undefined and fall back to the route's estimate.\n\nIncludes every attempt made on the caller's behalf, not just the last one." } }, "required": ["text", "html"] }, { "type": "array", "items": { "type": "object", "properties": { "text": { "type": "string", "description": "Markdown/plain-text content of the scraped page" }, "html": { "type": "string", "description": "Raw HTML content of the scraped page" }, "json": { "type": "object", "properties": {}, "required": [], "description": "Structured data extracted from the page" }, "screenshotUrl": { "type": "string", "description": "Screenshot URL of the page (if requested)" }, "metadata": { "type": "object", "properties": { "title": { "type": "string", "description": "Page title" }, "description": { "type": "string", "description": "Page meta description" }, "url": { "type": "string", "description": "Canonical URL" }, "image": { "type": "string", "description": "Open Graph image URL" } }, "required": ["title", "description", "url", "image"], "description": "Page metadata (Open Graph / meta tags)" }, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": ["code", "message"], "description": "Set when the scrape failed. `text`/`html` still carry the human-readable error so existing callers behave as before, but callers that care \u2014 billing, in particular \u2014 can tell a failure from real page content." }, "costUnits": { "type": "number", "description": "What the provider actually charged, when it tells us. Scrapfly returns an exact per-request credit total that varies with how hard the target fought back (6 for an unprotected page, 80 for Glassdoor), so billing a flat rate would either overcharge the easy case or eat the hard one. Providers that report nothing leave this undefined and fall back to the route's estimate.\n\nIncludes every attempt made on the caller's behalf, not just the last one." } }, "required": ["text", "html"] } }] }, "screenshot": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] } }, "required": ["content"] }
3140
3146
  },
3141
3147
  "scrapeXPost": {
3142
3148
  stepType: "scrapeXPost",
3143
3149
  description: "Scrape data from a single X (Twitter) post by URL.",
3144
3150
  usageNotes: "- Returns structured post data (text, html, optional json/screenshot/metadata).\n- Optionally saves the text content to a variable.",
3145
3151
  inputSchema: { "type": "object", "properties": { "url": { "type": "string", "description": "Full URL to the X post (e.g. https://x.com/elonmusk/status/1655608985058267139)" } }, "required": ["url"] },
3146
- outputSchema: { "type": "object", "properties": { "post": { "type": "object", "properties": { "text": { "type": "string", "description": "Markdown/plain-text content of the scraped page" }, "html": { "type": "string", "description": "Raw HTML content of the scraped page" }, "json": { "type": "object", "properties": {}, "required": [], "description": "Structured data extracted from the page" }, "screenshotUrl": { "type": "string", "description": "Screenshot URL of the page (if requested)" }, "metadata": { "type": "object", "properties": { "title": { "type": "string", "description": "Page title" }, "description": { "type": "string", "description": "Page meta description" }, "url": { "type": "string", "description": "Canonical URL" }, "image": { "type": "string", "description": "Open Graph image URL" } }, "required": ["title", "description", "url", "image"], "description": "Page metadata (Open Graph / meta tags)" }, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": ["code", "message"], "description": "Set when the scrape failed. `text`/`html` still carry the human-readable error so existing callers behave as before, but callers that care \u2014 billing, in particular \u2014 can tell a failure from real page content." } }, "required": ["text", "html"], "description": "Scraped post data including text, HTML, and optional structured JSON" } }, "required": ["post"] }
3152
+ outputSchema: { "type": "object", "properties": { "post": { "type": "object", "properties": { "text": { "type": "string", "description": "Markdown/plain-text content of the scraped page" }, "html": { "type": "string", "description": "Raw HTML content of the scraped page" }, "json": { "type": "object", "properties": {}, "required": [], "description": "Structured data extracted from the page" }, "screenshotUrl": { "type": "string", "description": "Screenshot URL of the page (if requested)" }, "metadata": { "type": "object", "properties": { "title": { "type": "string", "description": "Page title" }, "description": { "type": "string", "description": "Page meta description" }, "url": { "type": "string", "description": "Canonical URL" }, "image": { "type": "string", "description": "Open Graph image URL" } }, "required": ["title", "description", "url", "image"], "description": "Page metadata (Open Graph / meta tags)" }, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": ["code", "message"], "description": "Set when the scrape failed. `text`/`html` still carry the human-readable error so existing callers behave as before, but callers that care \u2014 billing, in particular \u2014 can tell a failure from real page content." }, "costUnits": { "type": "number", "description": "What the provider actually charged, when it tells us. Scrapfly returns an exact per-request credit total that varies with how hard the target fought back (6 for an unprotected page, 80 for Glassdoor), so billing a flat rate would either overcharge the easy case or eat the hard one. Providers that report nothing leave this undefined and fall back to the route's estimate.\n\nIncludes every attempt made on the caller's behalf, not just the last one." } }, "required": ["text", "html"], "description": "Scraped post data including text, HTML, and optional structured JSON" } }, "required": ["post"] }
3147
3153
  },
3148
3154
  "scrapeXProfile": {
3149
3155
  stepType: "scrapeXProfile",
3150
3156
  description: "Scrape public profile data from an X (Twitter) account by URL.",
3151
3157
  usageNotes: "- Returns structured profile data.\n- Optionally saves the result to a variable.",
3152
3158
  inputSchema: { "type": "object", "properties": { "url": { "type": "string", "description": "Full URL or username for the X profile (e.g. https://x.com/elonmusk)" } }, "required": ["url"] },
3153
- outputSchema: { "type": "object", "properties": { "profile": { "type": "object", "properties": { "text": { "type": "string", "description": "Markdown/plain-text content of the scraped page" }, "html": { "type": "string", "description": "Raw HTML content of the scraped page" }, "json": { "type": "object", "properties": {}, "required": [], "description": "Structured data extracted from the page" }, "screenshotUrl": { "type": "string", "description": "Screenshot URL of the page (if requested)" }, "metadata": { "type": "object", "properties": { "title": { "type": "string", "description": "Page title" }, "description": { "type": "string", "description": "Page meta description" }, "url": { "type": "string", "description": "Canonical URL" }, "image": { "type": "string", "description": "Open Graph image URL" } }, "required": ["title", "description", "url", "image"], "description": "Page metadata (Open Graph / meta tags)" }, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": ["code", "message"], "description": "Set when the scrape failed. `text`/`html` still carry the human-readable error so existing callers behave as before, but callers that care \u2014 billing, in particular \u2014 can tell a failure from real page content." } }, "required": ["text", "html"], "description": "Scraped profile data including text, HTML, and optional structured JSON" } }, "required": ["profile"] }
3159
+ outputSchema: { "type": "object", "properties": { "profile": { "type": "object", "properties": { "text": { "type": "string", "description": "Markdown/plain-text content of the scraped page" }, "html": { "type": "string", "description": "Raw HTML content of the scraped page" }, "json": { "type": "object", "properties": {}, "required": [], "description": "Structured data extracted from the page" }, "screenshotUrl": { "type": "string", "description": "Screenshot URL of the page (if requested)" }, "metadata": { "type": "object", "properties": { "title": { "type": "string", "description": "Page title" }, "description": { "type": "string", "description": "Page meta description" }, "url": { "type": "string", "description": "Canonical URL" }, "image": { "type": "string", "description": "Open Graph image URL" } }, "required": ["title", "description", "url", "image"], "description": "Page metadata (Open Graph / meta tags)" }, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } }, "required": ["code", "message"], "description": "Set when the scrape failed. `text`/`html` still carry the human-readable error so existing callers behave as before, but callers that care \u2014 billing, in particular \u2014 can tell a failure from real page content." }, "costUnits": { "type": "number", "description": "What the provider actually charged, when it tells us. Scrapfly returns an exact per-request credit total that varies with how hard the target fought back (6 for an unprotected page, 80 for Glassdoor), so billing a flat rate would either overcharge the easy case or eat the hard one. Providers that report nothing leave this undefined and fall back to the route's estimate.\n\nIncludes every attempt made on the caller's behalf, not just the last one." } }, "required": ["text", "html"], "description": "Scraped profile data including text, HTML, and optional structured JSON" } }, "required": ["profile"] }
3154
3160
  },
3155
3161
  "screenshotUrl": {
3156
3162
  stepType: "screenshotUrl",
3157
3163
  description: "Capture a screenshot of a web page as a PNG image.",
3158
- usageNotes: "- Takes a viewport or full-page screenshot of the given URL.\n- Returns a CDN-hosted PNG image URL.\n- Viewport mode captures only the visible area; fullPage captures the entire scrollable page.\n- You can customize viewport width/height, add a delay, or wait for a CSS selector before capturing.",
3164
+ usageNotes: "- Takes a viewport or full-page screenshot of the given URL.\n- Returns a CDN-hosted PNG image URL.\n- Viewport mode captures only the visible area; fullPage captures the entire scrollable page, scrolling it first so lazy-loaded content is included.\n- Works on sites behind bot protection (Cloudflare and similar).\n- Cookie-consent banners and similar overlays are suppressed automatically.\n- `width` and `height` are the exact output pixel dimensions.\n- You can add a delay or wait for a CSS selector before capturing. A selector that never appears fails the step rather than capturing early.",
3159
3165
  inputSchema: { "type": "object", "properties": { "url": { "type": "string", "description": "URL to screenshot" }, "mode": { "enum": ["viewport", "fullPage"], "type": "string", "description": "Screenshot mode: viewport captures visible area, fullPage captures entire page" }, "width": { "type": "number", "description": "Viewport width in pixels (default: 1280)" }, "height": { "type": "number", "description": "Viewport height in pixels (default: 800, ignored for fullPage mode)" }, "delay": { "type": "number", "description": "Milliseconds to wait before capturing (default: 0)" }, "waitFor": { "type": "string", "description": "CSS selector to wait for before capturing" } }, "required": ["url"] },
3160
3166
  outputSchema: { "type": "object", "properties": { "screenshotUrl": { "type": "string" } }, "required": ["screenshotUrl"] }
3161
3167
  },
@@ -3747,6 +3753,7 @@ function logTaskResult(result) {
3747
3753
  );
3748
3754
  }
3749
3755
  async function runTaskPoll(httpConfig, body) {
3756
+ const traceId = randomUUID2();
3750
3757
  const { data } = await request(
3751
3758
  httpConfig,
3752
3759
  "POST",
@@ -3805,13 +3812,15 @@ async function runTaskPoll(httpConfig, body) {
3805
3812
  outputTokens: 0,
3806
3813
  totalBillingCost: 0
3807
3814
  },
3808
- toolCalls: poll.toolCalls ?? []
3815
+ toolCalls: poll.toolCalls ?? [],
3816
+ traceId
3809
3817
  };
3810
3818
  logTaskResult(result);
3811
3819
  return result;
3812
3820
  }
3813
3821
  }
3814
3822
  async function runTaskStream(httpConfig, body, onEvent) {
3823
+ const traceId = randomUUID2();
3815
3824
  const url = `${httpConfig.baseUrl}/developer/v2/task`;
3816
3825
  const res = await fetch(url, {
3817
3826
  method: "POST",
@@ -3876,7 +3885,8 @@ async function runTaskStream(httpConfig, body, onEvent) {
3876
3885
  outputTokens: 0,
3877
3886
  totalBillingCost: 0
3878
3887
  },
3879
- toolCalls: event.toolCalls ?? []
3888
+ toolCalls: event.toolCalls ?? [],
3889
+ traceId
3880
3890
  };
3881
3891
  }
3882
3892
  } catch (err) {
@@ -3906,7 +3916,8 @@ async function runTaskStream(httpConfig, body, onEvent) {
3906
3916
  outputTokens: 0,
3907
3917
  totalBillingCost: 0
3908
3918
  },
3909
- toolCalls: event.toolCalls ?? []
3919
+ toolCalls: event.toolCalls ?? [],
3920
+ traceId
3910
3921
  };
3911
3922
  }
3912
3923
  } catch (err) {
@@ -3925,6 +3936,7 @@ async function runTaskStream(httpConfig, body, onEvent) {
3925
3936
  }
3926
3937
 
3927
3938
  // src/task/local.ts
3939
+ import { randomUUID as randomUUID3 } from "crypto";
3928
3940
  var DEFAULT_MAX_TURNS = 20;
3929
3941
  var MAX_TURNS_LIMIT = 100;
3930
3942
  var MAX_SCHEMA_REPAIR_ATTEMPTS = 3;
@@ -4156,6 +4168,7 @@ ${structuredOutputExample}
4156
4168
  Math.max(options.maxTurns || DEFAULT_MAX_TURNS, 1),
4157
4169
  MAX_TURNS_LIMIT
4158
4170
  );
4171
+ const traceId = randomUUID3();
4159
4172
  const messages = [
4160
4173
  { role: "user", content: JSON.stringify(options.input) }
4161
4174
  ];
@@ -4175,7 +4188,8 @@ ${structuredOutputExample}
4175
4188
  parsedSuccessfully: parsedSuccessfully2,
4176
4189
  turns,
4177
4190
  usage: totalUsage,
4178
- toolCalls: toolCallLog
4191
+ toolCalls: toolCallLog,
4192
+ traceId
4179
4193
  });
4180
4194
  const accumulate = (turn) => {
4181
4195
  totalUsage.inputTokens += turn.usage.inputTokens ?? 0;
@@ -4243,7 +4257,8 @@ ${structuredOutputExample}
4243
4257
  model: options.model,
4244
4258
  system,
4245
4259
  messages,
4246
- tools: wireTools
4260
+ tools: wireTools,
4261
+ traceId
4247
4262
  });
4248
4263
  } catch (err) {
4249
4264
  if (loopCount === 1 && err instanceof TurnError && err.status === 404 && err.errorCode === "not_found") {
@@ -4355,7 +4370,8 @@ ${formatValidationErrors(errors)}`
4355
4370
  model: options.model,
4356
4371
  system,
4357
4372
  messages,
4358
- tools: []
4373
+ tools: [],
4374
+ traceId
4359
4375
  });
4360
4376
  accumulate(turn);
4361
4377
  finalText = turn.text;
@@ -5958,6 +5974,79 @@ var MindStudioAgent = class {
5958
5974
  get files() {
5959
5975
  return this._files ??= createFiles(this._filesRequest.bind(this));
5960
5976
  }
5977
+ /**
5978
+ * Jewel surfaces: arrival-shaped triggers (`propose`) and the app-native
5979
+ * approval queue (`queue.list` / `queue.resolve`). See {@link JewelsApi}.
5980
+ */
5981
+ get jewels() {
5982
+ return {
5983
+ propose: (methodId, subject, opts) => {
5984
+ if (!methodId || typeof methodId !== "string") {
5985
+ throw new MindStudioError(
5986
+ "methodId is required",
5987
+ "missing_method_id",
5988
+ 400
5989
+ );
5990
+ }
5991
+ return this._jewelsRequest("propose", {
5992
+ methodId,
5993
+ subject,
5994
+ ...opts?.idempotencyKey !== void 0 && {
5995
+ idempotencyKey: opts.idempotencyKey
5996
+ }
5997
+ });
5998
+ },
5999
+ queue: {
6000
+ list: (opts) => this._jewelsRequest("queue/list", {
6001
+ ...opts?.methodId !== void 0 && { methodId: opts.methodId },
6002
+ ...opts?.limit !== void 0 && { limit: opts.limit }
6003
+ }),
6004
+ resolve: (itemId, opts) => this._jewelsRequest("queue/resolve", {
6005
+ itemId,
6006
+ action: opts.action,
6007
+ ...opts.input !== void 0 && { input: opts.input }
6008
+ })
6009
+ }
6010
+ };
6011
+ }
6012
+ /**
6013
+ * Raw hook-token call shared by the jewels surfaces (mirrors reportIssue).
6014
+ * No retries: propose holds the request for the jewel run and is idempotent
6015
+ * by key anyway; resolve applies a method and must never double-fire.
6016
+ */
6017
+ async _jewelsRequest(path, body) {
6018
+ const rctx = getRequestContext();
6019
+ if (this._authType !== "internal" && !rctx?.callbackToken) {
6020
+ throw new MindStudioError(
6021
+ `jewels.${path.replace("/", ".")} requires an app execution context (hook token) \u2014 it cannot be called with an API key.`,
6022
+ "jewels_requires_app_context",
6023
+ 400
6024
+ );
6025
+ }
6026
+ const url = `${this._currentHttpConfig.baseUrl}/_internal/v2/jewels/${path}`;
6027
+ const res = await fetch(url, {
6028
+ method: "POST",
6029
+ headers: {
6030
+ "Content-Type": "application/json",
6031
+ Authorization: this._token
6032
+ },
6033
+ body: JSON.stringify(body)
6034
+ });
6035
+ if (!res.ok) {
6036
+ let code = "jewels_error";
6037
+ let message = `jewels.${path.replace("/", ".")} failed: ${res.status} ${res.statusText}`;
6038
+ let details;
6039
+ try {
6040
+ const errBody = await res.json();
6041
+ details = errBody;
6042
+ if (typeof errBody.errorString === "string") code = errBody.errorString;
6043
+ message = typeof errBody.errorMessage === "string" && errBody.errorMessage || typeof errBody.errorString === "string" && errBody.errorString || message;
6044
+ } catch {
6045
+ }
6046
+ throw new MindStudioError(message, code, res.status, details);
6047
+ }
6048
+ return await res.json();
6049
+ }
5961
6050
  /**
5962
6051
  * Searchable document corpora.
5963
6052
  *
@@ -6519,6 +6608,138 @@ function resolveToken(provided, config) {
6519
6608
  );
6520
6609
  }
6521
6610
 
6611
+ // src/jewel/index.ts
6612
+ function errorInfo(e) {
6613
+ if (e instanceof Error) return { message: e.message, stack: e.stack };
6614
+ return { message: String(e) };
6615
+ }
6616
+ function deepEqual(a, b) {
6617
+ if (a === b) return true;
6618
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object") {
6619
+ return false;
6620
+ }
6621
+ const aIsArray = Array.isArray(a);
6622
+ if (aIsArray !== Array.isArray(b)) return false;
6623
+ if (aIsArray) {
6624
+ const aa = a;
6625
+ const ba = b;
6626
+ return aa.length === ba.length && aa.every((v, i) => deepEqual(v, ba[i]));
6627
+ }
6628
+ const ao = a;
6629
+ const bo = b;
6630
+ const aKeys = Object.keys(ao).filter((k) => ao[k] !== void 0);
6631
+ const bKeys = Object.keys(bo).filter((k) => bo[k] !== void 0);
6632
+ if (aKeys.length !== bKeys.length) return false;
6633
+ return aKeys.every((k) => deepEqual(ao[k], bo[k]));
6634
+ }
6635
+ var VERDICTS = /* @__PURE__ */ new Set(["agree", "disagree", "skip"]);
6636
+ function normalizeVerdict(v) {
6637
+ if (!v || !VERDICTS.has(v.verdict)) {
6638
+ return {
6639
+ verdict: "skip",
6640
+ notes: `grade returned invalid verdict: ${JSON.stringify(v)}`
6641
+ };
6642
+ }
6643
+ return v.notes === void 0 ? { verdict: v.verdict } : { verdict: v.verdict, notes: v.notes };
6644
+ }
6645
+ function defineJewel(method, config) {
6646
+ const runGrade = async (proposed, actual) => {
6647
+ if (config.grade) {
6648
+ try {
6649
+ return normalizeVerdict(await config.grade({ proposed, actual }));
6650
+ } catch (e) {
6651
+ return { verdict: "skip", notes: `grade threw: ${errorInfo(e).message}` };
6652
+ }
6653
+ }
6654
+ return deepEqual(proposed, actual) ? { verdict: "agree" } : { verdict: "disagree" };
6655
+ };
6656
+ const run = async (params) => {
6657
+ const startedAt = Date.now();
6658
+ const customGrade = config.grade !== void 0;
6659
+ const done = (rest) => ({
6660
+ v: 1,
6661
+ customGrade,
6662
+ startedAt,
6663
+ durationMs: Date.now() - startedAt,
6664
+ ...rest
6665
+ });
6666
+ const traceIds = (t) => {
6667
+ if (t === void 0) return void 0;
6668
+ const ids = (Array.isArray(t) ? t : [t]).filter(
6669
+ (id) => typeof id === "string" && id.length > 0
6670
+ );
6671
+ return ids.length > 0 ? ids : void 0;
6672
+ };
6673
+ if (Object.prototype.hasOwnProperty.call(params, "grade")) {
6674
+ const ctx = params.grade;
6675
+ const verdict2 = await runGrade(ctx.proposed, ctx.actual);
6676
+ const gradeTrace2 = traceIds(verdict2.trace);
6677
+ return done({
6678
+ mode: "grade",
6679
+ proposed: ctx.proposed,
6680
+ actual: ctx.actual,
6681
+ verdict: verdict2.verdict,
6682
+ ...verdict2.notes !== void 0 ? { notes: verdict2.notes } : {},
6683
+ ...gradeTrace2 ? { gradeTrace: gradeTrace2 } : {}
6684
+ });
6685
+ }
6686
+ const isShadow = Object.prototype.hasOwnProperty.call(params, "humanInput");
6687
+ const mode = isShadow ? "shadow" : "eval";
6688
+ const actual = isShadow ? params.humanInput : void 0;
6689
+ let subject;
6690
+ if (isShadow) {
6691
+ try {
6692
+ subject = config.subject(actual);
6693
+ } catch (e) {
6694
+ return done({ mode, actual, error: { phase: "subject", ...errorInfo(e) } });
6695
+ }
6696
+ } else {
6697
+ subject = params.subject;
6698
+ }
6699
+ let proposal;
6700
+ try {
6701
+ proposal = await config.propose(subject);
6702
+ } catch (e) {
6703
+ return done({
6704
+ mode,
6705
+ subject,
6706
+ actual,
6707
+ error: { phase: "propose", ...errorInfo(e) }
6708
+ });
6709
+ }
6710
+ const trace = traceIds(proposal.trace);
6711
+ if (!isShadow) {
6712
+ return done({
6713
+ mode,
6714
+ subject,
6715
+ proposed: proposal.input,
6716
+ reasoning: proposal.reasoning,
6717
+ ...trace ? { trace } : {}
6718
+ });
6719
+ }
6720
+ const verdict = await runGrade(proposal.input, actual);
6721
+ const gradeTrace = traceIds(verdict.trace);
6722
+ return done({
6723
+ mode,
6724
+ subject,
6725
+ proposed: proposal.input,
6726
+ reasoning: proposal.reasoning,
6727
+ actual,
6728
+ verdict: verdict.verdict,
6729
+ ...verdict.notes !== void 0 ? { notes: verdict.notes } : {},
6730
+ ...trace ? { trace } : {},
6731
+ ...gradeTrace ? { gradeTrace } : {}
6732
+ });
6733
+ };
6734
+ return Object.assign(run, {
6735
+ kind: "jewel",
6736
+ method,
6737
+ subject: config.subject,
6738
+ propose: config.propose,
6739
+ grade: config.grade
6740
+ });
6741
+ }
6742
+
6522
6743
  // src/generated/snippets.ts
6523
6744
  var monacoSnippets = {
6524
6745
  "activeCampaignAddNote": { fields: [["contactId", "string"], ["note", "string"]], outputKeys: [] },
@@ -6770,6 +6991,7 @@ export {
6770
6991
  dataSources,
6771
6992
  db,
6772
6993
  index_default as default,
6994
+ defineJewel,
6773
6995
  files,
6774
6996
  getRequestContext,
6775
6997
  mindstudio,