@siglume/api-sdk 1.2.2 → 2.0.1

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.
@@ -354,7 +354,12 @@ var init_webhooks = __esm({
354
354
  "capability.published",
355
355
  "capability.delisted",
356
356
  "execution.completed",
357
- "execution.failed"
357
+ "execution.failed",
358
+ "reward_payout.created",
359
+ "reward_payout.provider_pending",
360
+ "reward_paid",
361
+ "reward_payout.failed",
362
+ "reward_payout.cancelled"
358
363
  ];
359
364
  WEBHOOK_EVENT_SET = new Set(WEBHOOK_EVENT_TYPES);
360
365
  }
@@ -1404,6 +1409,23 @@ function validatePricingPlanFloor(plan, defaultCurrency) {
1404
1409
  function pricingPlanHasItems(plan) {
1405
1410
  return isRecord(plan) && Array.isArray(plan.items) && plan.items.length > 0;
1406
1411
  }
1412
+ function validateListingTextLengths(payload) {
1413
+ const limits = {
1414
+ short_description: LISTING_SHORT_DESCRIPTION_MAX_LENGTH,
1415
+ job_to_be_done: LISTING_JOB_TO_BE_DONE_MAX_LENGTH,
1416
+ description: LISTING_DESCRIPTION_MAX_LENGTH
1417
+ };
1418
+ for (const [fieldName, maxLength] of Object.entries(limits)) {
1419
+ const value = payload[fieldName];
1420
+ if (value === void 0 || value === null) continue;
1421
+ if (typeof value !== "string") {
1422
+ throw new SiglumeClientError(`AppManifest.${fieldName} must be a string when provided.`);
1423
+ }
1424
+ if (Array.from(value).length > maxLength) {
1425
+ throw new SiglumeClientError(`AppManifest.${fieldName} must be at most ${maxLength} characters.`);
1426
+ }
1427
+ }
1428
+ }
1407
1429
  function buildToolManualQualityReport(payload) {
1408
1430
  const qualityBlock = isRecord(payload.quality) ? payload.quality : payload;
1409
1431
  const issues = [];
@@ -1961,257 +1983,6 @@ function parseInstalledToolReceiptStep(data) {
1961
1983
  raw: { ...data }
1962
1984
  };
1963
1985
  }
1964
- function toRecordList(value) {
1965
- return Array.isArray(value) ? value.filter((item) => isRecord(item)).map((item) => ({ ...item })) : [];
1966
- }
1967
- function parsePartnerDashboard(data) {
1968
- return {
1969
- partner_id: String(data.partner_id ?? data.user_id ?? ""),
1970
- company_name: stringOrNull(data.company_name) ?? void 0,
1971
- plan: stringOrNull(data.plan) ?? void 0,
1972
- plan_label: stringOrNull(data.plan_label) ?? void 0,
1973
- month_bytes_used: Math.trunc(Number(data.month_bytes_used ?? 0)),
1974
- month_bytes_limit: Math.trunc(Number(data.month_bytes_limit ?? 0)),
1975
- month_usage_pct: Number(data.month_usage_pct ?? 0),
1976
- total_source_items: Math.trunc(Number(data.total_source_items ?? 0)),
1977
- has_billing: Boolean(data.has_billing ?? false),
1978
- has_subscription: Boolean(data.has_subscription ?? false),
1979
- raw: { ...data }
1980
- };
1981
- }
1982
- function parsePartnerUsage(data) {
1983
- return {
1984
- plan: stringOrNull(data.plan) ?? void 0,
1985
- month_bytes_used: Math.trunc(Number(data.month_bytes_used ?? 0)),
1986
- month_bytes_limit: Math.trunc(Number(data.month_bytes_limit ?? 0)),
1987
- month_bytes_remaining: Math.trunc(Number(data.month_bytes_remaining ?? 0)),
1988
- month_usage_pct: Number(data.month_usage_pct ?? 0),
1989
- raw: { ...data }
1990
- };
1991
- }
1992
- function parsePartnerApiKey(data) {
1993
- return {
1994
- credential_id: String(data.credential_id ?? data.id ?? ""),
1995
- name: stringOrNull(data.name) ?? void 0,
1996
- key_id: stringOrNull(data.key_id) ?? void 0,
1997
- allowed_source_types: Array.isArray(data.allowed_source_types) ? data.allowed_source_types.filter((item) => typeof item === "string") : [],
1998
- last_used_at: stringOrNull(data.last_used_at) ?? void 0,
1999
- created_at: stringOrNull(data.created_at) ?? void 0,
2000
- revoked: Boolean(data.revoked ?? false),
2001
- raw: { ...data }
2002
- };
2003
- }
2004
- function parsePartnerApiKeyHandle(data) {
2005
- const raw = Object.fromEntries(
2006
- Object.entries(data).filter(([key]) => key !== "ingest_key" && key !== "full_key")
2007
- );
2008
- return {
2009
- credential_id: String(raw.credential_id ?? raw.id ?? ""),
2010
- name: stringOrNull(raw.name) ?? void 0,
2011
- key_id: stringOrNull(raw.key_id) ?? void 0,
2012
- allowed_source_types: Array.isArray(raw.allowed_source_types) ? raw.allowed_source_types.filter((item) => typeof item === "string") : [],
2013
- masked_key_hint: stringOrNull(raw.masked_key_hint) ?? void 0,
2014
- raw
2015
- };
2016
- }
2017
- function parseAdsBilling(data) {
2018
- return {
2019
- currency: stringOrNull(data.currency) ?? void 0,
2020
- billing_mode: stringOrNull(data.billing_mode) ?? void 0,
2021
- month_spend_jpy: Math.trunc(Number(data.month_spend_jpy ?? 0)),
2022
- month_spend_usd: Math.trunc(Number(data.month_spend_usd ?? 0)),
2023
- all_time_spend_jpy: Math.trunc(Number(data.all_time_spend_jpy ?? 0)),
2024
- all_time_spend_usd: Math.trunc(Number(data.all_time_spend_usd ?? 0)),
2025
- total_impressions: Math.trunc(Number(data.total_impressions ?? 0)),
2026
- total_replies: Math.trunc(Number(data.total_replies ?? 0)),
2027
- has_billing: Boolean(data.has_billing ?? false),
2028
- has_subscription: Boolean(data.has_subscription ?? false),
2029
- invoices: toRecordList(data.invoices),
2030
- wallet: isRecord(data.wallet) ? { ...data.wallet } : null,
2031
- balances: toRecordList(data.balances),
2032
- supported_tokens: toRecordList(data.supported_tokens),
2033
- funding_instructions: isRecord(data.funding_instructions) ? { ...data.funding_instructions } : null,
2034
- mandate: isRecord(data.mandate) ? parsePlanWeb3Mandate(data.mandate) : null,
2035
- raw: { ...data }
2036
- };
2037
- }
2038
- function parseAdsBillingSettlement(data) {
2039
- return {
2040
- status: stringOrNull(data.status) ?? void 0,
2041
- message: stringOrNull(data.message ?? data.detail) ?? void 0,
2042
- settles_automatically: typeof data.settles_automatically === "boolean" ? data.settles_automatically : typeof data.auto_settles === "boolean" ? data.auto_settles : void 0,
2043
- cycle_key: stringOrNull(data.cycle_key) ?? void 0,
2044
- settled_at: stringOrNull(data.settled_at) ?? void 0,
2045
- raw: { ...data }
2046
- };
2047
- }
2048
- function parseAdsProfile(data) {
2049
- return {
2050
- has_profile: Boolean(data.has_profile ?? false),
2051
- company_name: stringOrNull(data.company_name) ?? void 0,
2052
- ad_currency: stringOrNull(data.ad_currency) ?? void 0,
2053
- has_billing: Boolean(data.has_billing ?? false),
2054
- raw: { ...data }
2055
- };
2056
- }
2057
- function parseAdsCampaign(data) {
2058
- return {
2059
- campaign_id: String(data.campaign_id ?? data.id ?? ""),
2060
- name: stringOrNull(data.name) ?? void 0,
2061
- target_url: stringOrNull(data.target_url) ?? void 0,
2062
- content_brief: stringOrNull(data.content_brief) ?? void 0,
2063
- target_topics: Array.isArray(data.target_topics) ? data.target_topics.filter((item) => typeof item === "string") : [],
2064
- posting_interval_minutes: Math.trunc(Number(data.posting_interval_minutes ?? 360)),
2065
- max_posts_per_day: Math.trunc(Number(data.max_posts_per_day ?? 4)),
2066
- currency: stringOrNull(data.currency) ?? void 0,
2067
- monthly_budget_jpy: Math.trunc(Number(data.monthly_budget_jpy ?? 0)),
2068
- cpm_jpy: Math.trunc(Number(data.cpm_jpy ?? 0)),
2069
- cpr_jpy: Math.trunc(Number(data.cpr_jpy ?? 0)),
2070
- monthly_budget_usd: Math.trunc(Number(data.monthly_budget_usd ?? 0)),
2071
- cpm_usd: Math.trunc(Number(data.cpm_usd ?? 0)),
2072
- cpr_usd: Math.trunc(Number(data.cpr_usd ?? 0)),
2073
- status: String(data.status ?? "active").trim().toLowerCase() || "active",
2074
- month_spend_jpy: Math.trunc(Number(data.month_spend_jpy ?? 0)),
2075
- month_spend_usd: Math.trunc(Number(data.month_spend_usd ?? 0)),
2076
- total_posts: Math.trunc(Number(data.total_posts ?? 0)),
2077
- total_impressions: Math.trunc(Number(data.total_impressions ?? 0)),
2078
- total_replies: Math.trunc(Number(data.total_replies ?? 0)),
2079
- next_post_at: stringOrNull(data.next_post_at) ?? void 0,
2080
- created_at: stringOrNull(data.created_at) ?? void 0,
2081
- raw: { ...data }
2082
- };
2083
- }
2084
- function parseAdsCampaignPost(data) {
2085
- return {
2086
- post_id: String(data.post_id ?? data.id ?? ""),
2087
- content_id: stringOrNull(data.content_id) ?? void 0,
2088
- cost_jpy: Math.trunc(Number(data.cost_jpy ?? 0)),
2089
- cost_usd: Math.trunc(Number(data.cost_usd ?? 0)),
2090
- impressions: Math.trunc(Number(data.impressions ?? 0)),
2091
- replies: Math.trunc(Number(data.replies ?? 0)),
2092
- status: stringOrNull(data.status) ?? void 0,
2093
- created_at: stringOrNull(data.created_at) ?? void 0,
2094
- raw: { ...data }
2095
- };
2096
- }
2097
- function parseWorksCategory(data) {
2098
- return {
2099
- key: String(data.key ?? ""),
2100
- name_ja: stringOrNull(data.name_ja) ?? void 0,
2101
- name_en: stringOrNull(data.name_en) ?? void 0,
2102
- description_ja: stringOrNull(data.description_ja) ?? void 0,
2103
- description_en: stringOrNull(data.description_en) ?? void 0,
2104
- icon_url: stringOrNull(data.icon_url) ?? void 0,
2105
- open_job_count: Math.trunc(Number(data.open_job_count ?? 0)),
2106
- display_order: Math.trunc(Number(data.display_order ?? 0)),
2107
- raw: { ...data }
2108
- };
2109
- }
2110
- function parseWorksRegistration(data) {
2111
- const result = isRecord(data.result) ? data.result : {};
2112
- const status = String(data.status ?? "completed").trim().toLowerCase() || "completed";
2113
- return {
2114
- agent_id: String(result.agent_id ?? data.agent_id ?? ""),
2115
- works_registered: typeof result.works_registered === "boolean" ? result.works_registered : Boolean(result.works_registered ?? false),
2116
- tagline: stringOrNull(result.tagline) ?? void 0,
2117
- categories: Array.isArray(result.categories) ? result.categories.filter((item) => typeof item === "string") : [],
2118
- capabilities: Array.isArray(result.capabilities) ? result.capabilities.filter((item) => typeof item === "string") : [],
2119
- description: stringOrNull(result.description) ?? void 0,
2120
- execution_status: status,
2121
- approval_required: typeof data.approval_required === "boolean" ? data.approval_required : status === "approval_required",
2122
- intent_id: stringOrNull(data.intent_id) ?? void 0,
2123
- approval_status: stringOrNull(data.approval_status) ?? void 0,
2124
- approval_snapshot_hash: stringOrNull(data.approval_snapshot_hash) ?? void 0,
2125
- approval_preview: toRecord(result.preview),
2126
- raw: { ...data }
2127
- };
2128
- }
2129
- function parseWorksOwnerDashboardAgent(data) {
2130
- return {
2131
- agent_id: String(data.id ?? data.agent_id ?? ""),
2132
- name: stringOrNull(data.name) ?? void 0,
2133
- reputation: toRecord(data.reputation),
2134
- capabilities: Array.isArray(data.capabilities) ? data.capabilities.filter((item) => typeof item === "string") : [],
2135
- raw: { ...data }
2136
- };
2137
- }
2138
- function parseWorksOwnerDashboardPitch(data) {
2139
- return {
2140
- proposal_id: String(data.proposal_id ?? data.id ?? ""),
2141
- need_id: stringOrNull(data.need_id) ?? void 0,
2142
- title: stringOrNull(data.title) ?? void 0,
2143
- title_en: stringOrNull(data.title_en) ?? void 0,
2144
- status: stringOrNull(data.status) ?? void 0,
2145
- raw: { ...data }
2146
- };
2147
- }
2148
- function parseWorksOwnerDashboardOrder(data) {
2149
- return {
2150
- order_id: String(data.order_id ?? data.id ?? ""),
2151
- need_id: stringOrNull(data.need_id) ?? void 0,
2152
- title: stringOrNull(data.title) ?? void 0,
2153
- title_en: stringOrNull(data.title_en) ?? void 0,
2154
- status: stringOrNull(data.status) ?? void 0,
2155
- raw: { ...data }
2156
- };
2157
- }
2158
- function parseWorksOwnerDashboardStats(data) {
2159
- return {
2160
- total_agents: Math.trunc(Number(data.total_agents ?? 0)),
2161
- total_pending: Math.trunc(Number(data.total_pending ?? 0)),
2162
- total_active: Math.trunc(Number(data.total_active ?? 0)),
2163
- raw: { ...data }
2164
- };
2165
- }
2166
- function parseWorksOwnerDashboard(data) {
2167
- return {
2168
- agents: Array.isArray(data.agents) ? data.agents.filter((item) => isRecord(item)).map((item) => parseWorksOwnerDashboardAgent(item)) : [],
2169
- pending_pitches: Array.isArray(data.pending_pitches) ? data.pending_pitches.filter((item) => isRecord(item)).map((item) => parseWorksOwnerDashboardPitch(item)) : [],
2170
- active_orders: Array.isArray(data.active_orders) ? data.active_orders.filter((item) => isRecord(item)).map((item) => parseWorksOwnerDashboardOrder(item)) : [],
2171
- completed_orders: Array.isArray(data.completed_orders) ? data.completed_orders.filter((item) => isRecord(item)).map((item) => parseWorksOwnerDashboardOrder(item)) : [],
2172
- stats: isRecord(data.stats) ? parseWorksOwnerDashboardStats(data.stats) : parseWorksOwnerDashboardStats({}),
2173
- raw: { ...data }
2174
- };
2175
- }
2176
- function parseWorksPosterDashboardJob(data) {
2177
- return {
2178
- job_id: String(data.id ?? data.job_id ?? ""),
2179
- title: stringOrNull(data.title) ?? void 0,
2180
- title_en: stringOrNull(data.title_en) ?? void 0,
2181
- proposal_count: Math.trunc(Number(data.proposal_count ?? 0)),
2182
- created_at: stringOrNull(data.created_at) ?? void 0,
2183
- raw: { ...data }
2184
- };
2185
- }
2186
- function parseWorksPosterDashboardOrder(data) {
2187
- return {
2188
- order_id: String(data.order_id ?? data.id ?? ""),
2189
- need_id: stringOrNull(data.need_id) ?? void 0,
2190
- title: stringOrNull(data.title) ?? void 0,
2191
- title_en: stringOrNull(data.title_en) ?? void 0,
2192
- status: stringOrNull(data.status) ?? void 0,
2193
- has_deliverable: typeof data.has_deliverable === "boolean" ? data.has_deliverable : Boolean(data.has_deliverable ?? false),
2194
- deliverable_count: Math.trunc(Number(data.deliverable_count ?? 0)),
2195
- awaiting_buyer_action: typeof data.awaiting_buyer_action === "boolean" ? data.awaiting_buyer_action : Boolean(data.awaiting_buyer_action ?? false),
2196
- raw: { ...data }
2197
- };
2198
- }
2199
- function parseWorksPosterDashboardStats(data) {
2200
- return {
2201
- total_posted: Math.trunc(Number(data.total_posted ?? 0)),
2202
- total_completed: Math.trunc(Number(data.total_completed ?? 0)),
2203
- raw: { ...data }
2204
- };
2205
- }
2206
- function parseWorksPosterDashboard(data) {
2207
- return {
2208
- open_jobs: Array.isArray(data.open_jobs) ? data.open_jobs.filter((item) => isRecord(item)).map((item) => parseWorksPosterDashboardJob(item)) : [],
2209
- in_progress_orders: Array.isArray(data.in_progress_orders) ? data.in_progress_orders.filter((item) => isRecord(item)).map((item) => parseWorksPosterDashboardOrder(item)) : [],
2210
- completed_orders: Array.isArray(data.completed_orders) ? data.completed_orders.filter((item) => isRecord(item)).map((item) => parseWorksPosterDashboardOrder(item)) : [],
2211
- stats: isRecord(data.stats) ? parseWorksPosterDashboardStats(data.stats) : parseWorksPosterDashboardStats({}),
2212
- raw: { ...data }
2213
- };
2214
- }
2215
1986
  function parseMarketProposal(data) {
2216
1987
  const reasonCodes = Array.isArray(data.reason_codes) ? data.reason_codes : Array.isArray(data.reason_codes_jsonb) ? data.reason_codes_jsonb : [];
2217
1988
  return {
@@ -2592,7 +2363,7 @@ function cloneJsonLike(value) {
2592
2363
  }
2593
2364
  return value;
2594
2365
  }
2595
- var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, CursorPageResult, SiglumeClient;
2366
+ var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, LISTING_SHORT_DESCRIPTION_MAX_LENGTH, LISTING_JOB_TO_BE_DONE_MAX_LENGTH, LISTING_DESCRIPTION_MAX_LENGTH, CursorPageResult, SiglumeClient;
2596
2367
  var init_client = __esm({
2597
2368
  "src/client.ts"() {
2598
2369
  "use strict";
@@ -2605,6 +2376,9 @@ var init_client = __esm({
2605
2376
  DEFAULT_SIGLUME_API_BASE = "https://siglume.com/v1";
2606
2377
  RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
2607
2378
  MINIMUM_JPY_OPERATION_PRICE_CURRENCIES = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
2379
+ LISTING_SHORT_DESCRIPTION_MAX_LENGTH = 60;
2380
+ LISTING_JOB_TO_BE_DONE_MAX_LENGTH = 240;
2381
+ LISTING_DESCRIPTION_MAX_LENGTH = 1e3;
2608
2382
  CursorPageResult = class {
2609
2383
  items;
2610
2384
  next_cursor;
@@ -2758,6 +2532,7 @@ var init_client = __esm({
2758
2532
  if (payload.pricing_plan !== void 0) {
2759
2533
  validatePricingPlanFloor(payload.pricing_plan, currency);
2760
2534
  }
2535
+ validateListingTextLengths(payload);
2761
2536
  const priceModel = String(payload.price_model ?? "free").trim().toLowerCase();
2762
2537
  if ((priceModel === "usage_based" || priceModel === "per_action") && !pricingPlanHasItems(payload.pricing_plan)) {
2763
2538
  throw new SiglumeClientError("AppManifest.pricing_plan.items is required for usage_based/per_action pricing.");
@@ -3649,94 +3424,6 @@ var init_client = __esm({
3649
3424
  );
3650
3425
  return parseMarketNeed(execution.result);
3651
3426
  }
3652
- // `works.*` also uses the public owner-operation execute route. The
3653
- // categories list returns a top-level array in `result`, so these
3654
- // wrappers call the execute endpoint directly instead of relying on
3655
- // execute_owner_operation()'s object-only `result` parser.
3656
- async list_works_categories(options = {}) {
3657
- const [data] = await this.requestOwnerOperation(
3658
- await this.resolveOwnerOperationAgentId(options.agent_id),
3659
- "works.categories.list",
3660
- {},
3661
- { lang: options.lang }
3662
- );
3663
- return Array.isArray(data.result) ? data.result.filter((item) => isRecord(item)).map((item) => parseWorksCategory(item)) : [];
3664
- }
3665
- async get_works_registration(options = {}) {
3666
- const [data] = await this.requestOwnerOperation(
3667
- await this.resolveOwnerOperationAgentId(options.agent_id),
3668
- "works.registration.get",
3669
- {},
3670
- { lang: options.lang }
3671
- );
3672
- return parseWorksRegistration(data);
3673
- }
3674
- async register_for_works(options = {}) {
3675
- const payload = {};
3676
- if (options.tagline !== void 0) {
3677
- payload.tagline = String(options.tagline).trim();
3678
- }
3679
- if (options.description !== void 0) {
3680
- payload.description = String(options.description).trim();
3681
- }
3682
- if (options.categories !== void 0) {
3683
- if (!Array.isArray(options.categories)) {
3684
- throw new SiglumeClientError("categories must be a list of strings.");
3685
- }
3686
- const normalizedCategories = [];
3687
- for (const item of options.categories) {
3688
- if (typeof item !== "string") {
3689
- throw new SiglumeClientError("categories must contain only strings.");
3690
- }
3691
- const normalized = item.trim();
3692
- if (normalized) {
3693
- normalizedCategories.push(normalized);
3694
- }
3695
- }
3696
- payload.categories = normalizedCategories;
3697
- }
3698
- if (options.capabilities !== void 0) {
3699
- if (!Array.isArray(options.capabilities)) {
3700
- throw new SiglumeClientError("capabilities must be a list of strings.");
3701
- }
3702
- const normalizedCapabilities = [];
3703
- for (const item of options.capabilities) {
3704
- if (typeof item !== "string") {
3705
- throw new SiglumeClientError("capabilities must contain only strings.");
3706
- }
3707
- const normalized = item.trim();
3708
- if (normalized) {
3709
- normalizedCapabilities.push(normalized);
3710
- }
3711
- }
3712
- payload.capabilities = normalizedCapabilities;
3713
- }
3714
- const [data] = await this.requestOwnerOperation(
3715
- await this.resolveOwnerOperationAgentId(options.agent_id),
3716
- "works.registration.register",
3717
- payload,
3718
- { lang: options.lang }
3719
- );
3720
- return parseWorksRegistration(data);
3721
- }
3722
- async get_works_owner_dashboard(options = {}) {
3723
- const [data] = await this.requestOwnerOperation(
3724
- await this.resolveOwnerOperationAgentId(options.agent_id),
3725
- "works.owner_dashboard.get",
3726
- {},
3727
- { lang: options.lang }
3728
- );
3729
- return parseWorksOwnerDashboard(isRecord(data.result) ? data.result : {});
3730
- }
3731
- async get_works_poster_dashboard(options = {}) {
3732
- const [data] = await this.requestOwnerOperation(
3733
- await this.resolveOwnerOperationAgentId(options.agent_id),
3734
- "works.poster_dashboard.get",
3735
- {},
3736
- { lang: options.lang }
3737
- );
3738
- return parseWorksPosterDashboard(isRecord(data.result) ? data.result : {});
3739
- }
3740
3427
  async list_installed_tools(options = {}) {
3741
3428
  const resolvedAgentId = await this.resolveOwnerOperationAgentId(options.agent_id);
3742
3429
  const [data] = await this.requestOwnerOperation(
@@ -3900,115 +3587,6 @@ var init_client = __esm({
3900
3587
  );
3901
3588
  return Array.isArray(data.result) ? data.result.filter((item) => isRecord(item)).map((item) => parseInstalledToolReceiptStep(item)) : [];
3902
3589
  }
3903
- async get_partner_dashboard(options = {}) {
3904
- const execution = await this.execute_owner_operation(
3905
- await this.resolveOwnerOperationAgentId(options.agent_id),
3906
- "partner.dashboard.get",
3907
- {},
3908
- { lang: options.lang }
3909
- );
3910
- return parsePartnerDashboard(execution.result);
3911
- }
3912
- async get_partner_usage(options = {}) {
3913
- const execution = await this.execute_owner_operation(
3914
- await this.resolveOwnerOperationAgentId(options.agent_id),
3915
- "partner.usage.get",
3916
- {},
3917
- { lang: options.lang }
3918
- );
3919
- return parsePartnerUsage(execution.result);
3920
- }
3921
- async list_partner_api_keys(options = {}) {
3922
- const execution = await this.execute_owner_operation(
3923
- await this.resolveOwnerOperationAgentId(options.agent_id),
3924
- "partner.keys.list",
3925
- {},
3926
- { lang: options.lang }
3927
- );
3928
- return Array.isArray(execution.result.keys) ? execution.result.keys.filter((item) => isRecord(item)).map((item) => parsePartnerApiKey(item)) : [];
3929
- }
3930
- async create_partner_api_key(options = {}) {
3931
- const payload = {};
3932
- if (options.name !== void 0) {
3933
- const normalizedName = String(options.name).trim();
3934
- if (!normalizedName) {
3935
- throw new SiglumeClientError("name cannot be empty.");
3936
- }
3937
- payload.name = normalizedName;
3938
- }
3939
- if (options.allowed_source_types !== void 0) {
3940
- if (!Array.isArray(options.allowed_source_types)) {
3941
- throw new SiglumeClientError("allowed_source_types must be a list of strings.");
3942
- }
3943
- payload.allowed_source_types = options.allowed_source_types.flatMap((item) => {
3944
- if (typeof item !== "string") {
3945
- throw new SiglumeClientError("allowed_source_types must contain only strings.");
3946
- }
3947
- const normalizedItem = item.trim();
3948
- return normalizedItem ? [normalizedItem] : [];
3949
- });
3950
- }
3951
- const execution = await this.execute_owner_operation(
3952
- await this.resolveOwnerOperationAgentId(options.agent_id),
3953
- "partner.keys.create",
3954
- payload,
3955
- { lang: options.lang }
3956
- );
3957
- return parsePartnerApiKeyHandle(execution.result);
3958
- }
3959
- async get_ads_billing(options = {}) {
3960
- const payload = {};
3961
- if (options.rail !== void 0 && String(options.rail).trim()) {
3962
- payload.rail = String(options.rail).trim().toLowerCase();
3963
- }
3964
- const execution = await this.execute_owner_operation(
3965
- await this.resolveOwnerOperationAgentId(options.agent_id),
3966
- "ads.billing.get",
3967
- payload,
3968
- { lang: options.lang }
3969
- );
3970
- return parseAdsBilling(execution.result);
3971
- }
3972
- async settle_ads_billing(options = {}) {
3973
- const execution = await this.execute_owner_operation(
3974
- await this.resolveOwnerOperationAgentId(options.agent_id),
3975
- "ads.billing.settle",
3976
- {},
3977
- { lang: options.lang }
3978
- );
3979
- return parseAdsBillingSettlement(execution.result);
3980
- }
3981
- async get_ads_profile(options = {}) {
3982
- const execution = await this.execute_owner_operation(
3983
- await this.resolveOwnerOperationAgentId(options.agent_id),
3984
- "ads.profile.get",
3985
- {},
3986
- { lang: options.lang }
3987
- );
3988
- return parseAdsProfile(execution.result);
3989
- }
3990
- async list_ads_campaigns(options = {}) {
3991
- const execution = await this.execute_owner_operation(
3992
- await this.resolveOwnerOperationAgentId(options.agent_id),
3993
- "ads.campaigns.list",
3994
- {},
3995
- { lang: options.lang }
3996
- );
3997
- return Array.isArray(execution.result.campaigns) ? execution.result.campaigns.filter((item) => isRecord(item)).map((item) => parseAdsCampaign(item)) : [];
3998
- }
3999
- async list_ads_campaign_posts(campaign_id, options = {}) {
4000
- const normalizedCampaignId = String(campaign_id ?? "").trim();
4001
- if (!normalizedCampaignId) {
4002
- throw new SiglumeClientError("campaign_id is required.");
4003
- }
4004
- const execution = await this.execute_owner_operation(
4005
- await this.resolveOwnerOperationAgentId(options.agent_id),
4006
- "ads.campaign_posts.list",
4007
- { campaign_id: normalizedCampaignId },
4008
- { lang: options.lang }
4009
- );
4010
- return Array.isArray(execution.result.posts) ? execution.result.posts.filter((item) => isRecord(item)).map((item) => parseAdsCampaignPost(item)) : [];
4011
- }
4012
3590
  // `market.proposals.*` currently rides on the public owner-operation execute
4013
3591
  // route. Read helpers return typed proposal records; guarded mutations return
4014
3592
  // the approval envelope without treating it as an error.
@@ -5938,12 +5516,15 @@ function validate_tool_manual(manualInput) {
5938
5516
  pushError("INVALID_TOOL_NAME", "tool_name must be alphanumeric + underscore, 3-64 chars", "tool_name");
5939
5517
  }
5940
5518
  for (const [fieldName, minLength, maxLength] of [
5941
- ["job_to_be_done", 10, 500],
5519
+ ["job_to_be_done", 10, 240],
5942
5520
  ["summary_for_model", 10, 300]
5943
5521
  ]) {
5944
5522
  const value = manual[fieldName];
5945
- if (typeof value === "string" && (value.length < minLength || value.length > maxLength)) {
5946
- pushError("INVALID_TYPE", `${fieldName} must be ${minLength}-${maxLength} characters`, fieldName);
5523
+ if (typeof value === "string") {
5524
+ const length = Array.from(value).length;
5525
+ if (length < minLength || length > maxLength) {
5526
+ pushError("INVALID_TYPE", `${fieldName} must be ${minLength}-${maxLength} characters`, fieldName);
5527
+ }
5947
5528
  }
5948
5529
  }
5949
5530
  const triggerConditions = manual.trigger_conditions;
@@ -7131,8 +6712,12 @@ function buildRuntimeValidationTemplate(toolManual) {
7131
6712
  healthcheck_url: "https://api.example.com/health",
7132
6713
  invoke_url: "https://api.example.com/invoke",
7133
6714
  invoke_method: "POST",
7134
- test_auth_header_name: "X-Siglume-Review-Key",
7135
- test_auth_header_value: "replace-with-dedicated-review-key",
6715
+ // Shared secret Siglume attaches when it calls invoke_url at both
6716
+ // registration validation and production runtime. Use a strong random
6717
+ // value, keep it in the Git-ignored runtime_validation.json, and rotate it
6718
+ // if it leaks. (legacy aliases: test_auth_header_name/value)
6719
+ runtime_auth_header_name: "X-Siglume-Auth",
6720
+ runtime_auth_header_value: "replace-with-strong-random-runtime-auth-secret",
7136
6721
  request_payload: requestPayload,
7137
6722
  expected_response_fields: expectedFields.length > 0 ? expectedFields : ["summary"],
7138
6723
  timeout_seconds: 10
@@ -7437,8 +7022,6 @@ function runtimePlaceholderIssues(runtimeValidation) {
7437
7022
  "public_base_url",
7438
7023
  "healthcheck_url",
7439
7024
  "invoke_url",
7440
- "test_auth_header_name",
7441
- "test_auth_header_value",
7442
7025
  "expected_response_fields"
7443
7026
  ]) {
7444
7027
  if (!runtimeValidation[fieldName]) {
@@ -7451,9 +7034,19 @@ function runtimePlaceholderIssues(runtimeValidation) {
7451
7034
  issues.push(`runtime_validation.${fieldName} must be replaced with your public production URL`);
7452
7035
  }
7453
7036
  }
7454
- const authValue = String(runtimeValidation.test_auth_header_value ?? "").trim();
7037
+ const authName = String(
7038
+ runtimeValidation.runtime_auth_header_name || runtimeValidation.test_auth_header_name || ""
7039
+ ).trim();
7040
+ if (!authName) {
7041
+ issues.push("runtime_validation.runtime_auth_header_name is required");
7042
+ }
7043
+ const authValue = String(
7044
+ runtimeValidation.runtime_auth_header_value || runtimeValidation.test_auth_header_value || ""
7045
+ ).trim();
7455
7046
  if (!authValue || authValue.startsWith("replace-with-")) {
7456
- issues.push("runtime_validation.test_auth_header_value must be a dedicated review secret, not a placeholder");
7047
+ issues.push(
7048
+ "runtime_validation.runtime_auth_header_value must be a strong, dedicated runtime auth secret, not a placeholder"
7049
+ );
7457
7050
  }
7458
7051
  const requestPayload = runtimeValidation.request_payload ?? runtimeValidation.test_request_body ?? runtimeValidation.runtime_sample ?? runtimeValidation.sample_request_payload ?? runtimeValidation.runtime_sample_request;
7459
7052
  if (!isRecord(requestPayload)) {
@@ -7468,7 +7061,7 @@ function runtimePlaceholderIssues(runtimeValidation) {
7468
7061
  function ensureRuntimeValidationReady(project) {
7469
7062
  if (!project.runtime_validation) {
7470
7063
  throw new SiglumeProjectError(
7471
- "runtime_validation.json is required for `siglume register`. Create it with public_base_url, healthcheck_url, invoke_url, dedicated review auth header, request_payload, and expected_response_fields."
7064
+ "runtime_validation.json is required for `siglume register`. Create it with public_base_url, healthcheck_url, invoke_url, runtime auth header (runtime_auth_header_name/value), request_payload, and expected_response_fields."
7472
7065
  );
7473
7066
  }
7474
7067
  const issues = runtimePlaceholderIssues(project.runtime_validation);
@@ -8157,19 +7750,19 @@ function operationReadmeTemplate(operation, manifest, warning) {
8157
7750
  "- `stubs.ts`: mock fallback used when `SIGLUME_API_KEY` is not set",
8158
7751
  "- `manifest.json`: reviewable manifest snapshot",
8159
7752
  "- `tool_manual.json`: machine-generated ToolManual scaffold",
8160
- "- `runtime_validation.json`: local public endpoint and review-key checks used by auto-register",
7753
+ "- `runtime_validation.json`: local public endpoint + runtime auth header checks used by auto-register",
8161
7754
  "- `docs/api-usage.md`: publishable API usage guide template for `docs_url`",
8162
- "- `.gitignore`: keeps runtime review keys out of Git",
7755
+ "- `.gitignore`: keeps the runtime auth secret out of Git",
8163
7756
  "- `tests/test_adapter.ts`: smoke test for `AppTestHarness`",
8164
7757
  "",
8165
7758
  "Before registering, replace all generated placeholders:",
8166
7759
  "- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
8167
7760
  "- Replace `support_contact` with a real support email address or public support URL.",
8168
7761
  "- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
8169
- "- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
7762
+ "- In the local `runtime_validation.json`, replace the public URL and runtime auth header placeholders (runtime_auth_header_name/value).",
8170
7763
  "- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
8171
- "- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8172
- "- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
7764
+ "- Do not commit the real runtime auth secret or external-provider secrets; the generated `.gitignore` excludes local secret files.",
7765
+ "- Because `runtime_validation.json` is ignored, GitHub samples do not commit runtime auth secret values.",
8173
7766
  "",
8174
7767
  "## Commands",
8175
7768
  "",
@@ -8238,7 +7831,7 @@ function apiUsageDocsTemplate(manifest) {
8238
7831
  }
8239
7832
  function generatedGitignore() {
8240
7833
  return [
8241
- "# Local secrets and registration-only runtime checks.",
7834
+ "# Local secrets (incl. the runtime auth shared secret) and runtime checks.",
8242
7835
  ".env",
8243
7836
  ".env.*",
8244
7837
  "!.env.example",
@@ -8722,16 +8315,16 @@ function readmeTemplate(template) {
8722
8315
  "- `tool_manual.json`: editable ToolManual draft for validation and registration",
8723
8316
  "- `runtime_validation.json`: local live API smoke-test contract used during registration",
8724
8317
  "- `docs/api-usage.md`: publish this page and use its public URL as `docs_url`",
8725
- "- `.gitignore`: keeps runtime review keys out of Git",
8318
+ "- `.gitignore`: keeps the runtime auth secret out of Git",
8726
8319
  "",
8727
8320
  "Before registering, replace all generated placeholders:",
8728
8321
  "- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
8729
8322
  "- Replace `support_contact` with a real support email address or public support URL.",
8730
8323
  "- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
8731
- "- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
8324
+ "- In the local `runtime_validation.json`, replace the public URL and runtime auth header placeholders (runtime_auth_header_name/value).",
8732
8325
  "- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
8733
- "- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8734
- "- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
8326
+ "- Do not commit the real runtime auth secret or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8327
+ "- Because `runtime_validation.json` is ignored, GitHub samples do not commit runtime auth secret values.",
8735
8328
  "",
8736
8329
  "Suggested workflow:",
8737
8330
  "",