@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.
@@ -333,7 +333,12 @@ var init_webhooks = __esm({
333
333
  "capability.published",
334
334
  "capability.delisted",
335
335
  "execution.completed",
336
- "execution.failed"
336
+ "execution.failed",
337
+ "reward_payout.created",
338
+ "reward_payout.provider_pending",
339
+ "reward_paid",
340
+ "reward_payout.failed",
341
+ "reward_payout.cancelled"
337
342
  ];
338
343
  WEBHOOK_EVENT_SET = new Set(WEBHOOK_EVENT_TYPES);
339
344
  }
@@ -1383,6 +1388,23 @@ function validatePricingPlanFloor(plan, defaultCurrency) {
1383
1388
  function pricingPlanHasItems(plan) {
1384
1389
  return isRecord(plan) && Array.isArray(plan.items) && plan.items.length > 0;
1385
1390
  }
1391
+ function validateListingTextLengths(payload) {
1392
+ const limits = {
1393
+ short_description: LISTING_SHORT_DESCRIPTION_MAX_LENGTH,
1394
+ job_to_be_done: LISTING_JOB_TO_BE_DONE_MAX_LENGTH,
1395
+ description: LISTING_DESCRIPTION_MAX_LENGTH
1396
+ };
1397
+ for (const [fieldName, maxLength] of Object.entries(limits)) {
1398
+ const value = payload[fieldName];
1399
+ if (value === void 0 || value === null) continue;
1400
+ if (typeof value !== "string") {
1401
+ throw new SiglumeClientError(`AppManifest.${fieldName} must be a string when provided.`);
1402
+ }
1403
+ if (Array.from(value).length > maxLength) {
1404
+ throw new SiglumeClientError(`AppManifest.${fieldName} must be at most ${maxLength} characters.`);
1405
+ }
1406
+ }
1407
+ }
1386
1408
  function buildToolManualQualityReport(payload) {
1387
1409
  const qualityBlock = isRecord(payload.quality) ? payload.quality : payload;
1388
1410
  const issues = [];
@@ -1940,257 +1962,6 @@ function parseInstalledToolReceiptStep(data) {
1940
1962
  raw: { ...data }
1941
1963
  };
1942
1964
  }
1943
- function toRecordList(value) {
1944
- return Array.isArray(value) ? value.filter((item) => isRecord(item)).map((item) => ({ ...item })) : [];
1945
- }
1946
- function parsePartnerDashboard(data) {
1947
- return {
1948
- partner_id: String(data.partner_id ?? data.user_id ?? ""),
1949
- company_name: stringOrNull(data.company_name) ?? void 0,
1950
- plan: stringOrNull(data.plan) ?? void 0,
1951
- plan_label: stringOrNull(data.plan_label) ?? void 0,
1952
- month_bytes_used: Math.trunc(Number(data.month_bytes_used ?? 0)),
1953
- month_bytes_limit: Math.trunc(Number(data.month_bytes_limit ?? 0)),
1954
- month_usage_pct: Number(data.month_usage_pct ?? 0),
1955
- total_source_items: Math.trunc(Number(data.total_source_items ?? 0)),
1956
- has_billing: Boolean(data.has_billing ?? false),
1957
- has_subscription: Boolean(data.has_subscription ?? false),
1958
- raw: { ...data }
1959
- };
1960
- }
1961
- function parsePartnerUsage(data) {
1962
- return {
1963
- plan: stringOrNull(data.plan) ?? void 0,
1964
- month_bytes_used: Math.trunc(Number(data.month_bytes_used ?? 0)),
1965
- month_bytes_limit: Math.trunc(Number(data.month_bytes_limit ?? 0)),
1966
- month_bytes_remaining: Math.trunc(Number(data.month_bytes_remaining ?? 0)),
1967
- month_usage_pct: Number(data.month_usage_pct ?? 0),
1968
- raw: { ...data }
1969
- };
1970
- }
1971
- function parsePartnerApiKey(data) {
1972
- return {
1973
- credential_id: String(data.credential_id ?? data.id ?? ""),
1974
- name: stringOrNull(data.name) ?? void 0,
1975
- key_id: stringOrNull(data.key_id) ?? void 0,
1976
- allowed_source_types: Array.isArray(data.allowed_source_types) ? data.allowed_source_types.filter((item) => typeof item === "string") : [],
1977
- last_used_at: stringOrNull(data.last_used_at) ?? void 0,
1978
- created_at: stringOrNull(data.created_at) ?? void 0,
1979
- revoked: Boolean(data.revoked ?? false),
1980
- raw: { ...data }
1981
- };
1982
- }
1983
- function parsePartnerApiKeyHandle(data) {
1984
- const raw = Object.fromEntries(
1985
- Object.entries(data).filter(([key]) => key !== "ingest_key" && key !== "full_key")
1986
- );
1987
- return {
1988
- credential_id: String(raw.credential_id ?? raw.id ?? ""),
1989
- name: stringOrNull(raw.name) ?? void 0,
1990
- key_id: stringOrNull(raw.key_id) ?? void 0,
1991
- allowed_source_types: Array.isArray(raw.allowed_source_types) ? raw.allowed_source_types.filter((item) => typeof item === "string") : [],
1992
- masked_key_hint: stringOrNull(raw.masked_key_hint) ?? void 0,
1993
- raw
1994
- };
1995
- }
1996
- function parseAdsBilling(data) {
1997
- return {
1998
- currency: stringOrNull(data.currency) ?? void 0,
1999
- billing_mode: stringOrNull(data.billing_mode) ?? void 0,
2000
- month_spend_jpy: Math.trunc(Number(data.month_spend_jpy ?? 0)),
2001
- month_spend_usd: Math.trunc(Number(data.month_spend_usd ?? 0)),
2002
- all_time_spend_jpy: Math.trunc(Number(data.all_time_spend_jpy ?? 0)),
2003
- all_time_spend_usd: Math.trunc(Number(data.all_time_spend_usd ?? 0)),
2004
- total_impressions: Math.trunc(Number(data.total_impressions ?? 0)),
2005
- total_replies: Math.trunc(Number(data.total_replies ?? 0)),
2006
- has_billing: Boolean(data.has_billing ?? false),
2007
- has_subscription: Boolean(data.has_subscription ?? false),
2008
- invoices: toRecordList(data.invoices),
2009
- wallet: isRecord(data.wallet) ? { ...data.wallet } : null,
2010
- balances: toRecordList(data.balances),
2011
- supported_tokens: toRecordList(data.supported_tokens),
2012
- funding_instructions: isRecord(data.funding_instructions) ? { ...data.funding_instructions } : null,
2013
- mandate: isRecord(data.mandate) ? parsePlanWeb3Mandate(data.mandate) : null,
2014
- raw: { ...data }
2015
- };
2016
- }
2017
- function parseAdsBillingSettlement(data) {
2018
- return {
2019
- status: stringOrNull(data.status) ?? void 0,
2020
- message: stringOrNull(data.message ?? data.detail) ?? void 0,
2021
- settles_automatically: typeof data.settles_automatically === "boolean" ? data.settles_automatically : typeof data.auto_settles === "boolean" ? data.auto_settles : void 0,
2022
- cycle_key: stringOrNull(data.cycle_key) ?? void 0,
2023
- settled_at: stringOrNull(data.settled_at) ?? void 0,
2024
- raw: { ...data }
2025
- };
2026
- }
2027
- function parseAdsProfile(data) {
2028
- return {
2029
- has_profile: Boolean(data.has_profile ?? false),
2030
- company_name: stringOrNull(data.company_name) ?? void 0,
2031
- ad_currency: stringOrNull(data.ad_currency) ?? void 0,
2032
- has_billing: Boolean(data.has_billing ?? false),
2033
- raw: { ...data }
2034
- };
2035
- }
2036
- function parseAdsCampaign(data) {
2037
- return {
2038
- campaign_id: String(data.campaign_id ?? data.id ?? ""),
2039
- name: stringOrNull(data.name) ?? void 0,
2040
- target_url: stringOrNull(data.target_url) ?? void 0,
2041
- content_brief: stringOrNull(data.content_brief) ?? void 0,
2042
- target_topics: Array.isArray(data.target_topics) ? data.target_topics.filter((item) => typeof item === "string") : [],
2043
- posting_interval_minutes: Math.trunc(Number(data.posting_interval_minutes ?? 360)),
2044
- max_posts_per_day: Math.trunc(Number(data.max_posts_per_day ?? 4)),
2045
- currency: stringOrNull(data.currency) ?? void 0,
2046
- monthly_budget_jpy: Math.trunc(Number(data.monthly_budget_jpy ?? 0)),
2047
- cpm_jpy: Math.trunc(Number(data.cpm_jpy ?? 0)),
2048
- cpr_jpy: Math.trunc(Number(data.cpr_jpy ?? 0)),
2049
- monthly_budget_usd: Math.trunc(Number(data.monthly_budget_usd ?? 0)),
2050
- cpm_usd: Math.trunc(Number(data.cpm_usd ?? 0)),
2051
- cpr_usd: Math.trunc(Number(data.cpr_usd ?? 0)),
2052
- status: String(data.status ?? "active").trim().toLowerCase() || "active",
2053
- month_spend_jpy: Math.trunc(Number(data.month_spend_jpy ?? 0)),
2054
- month_spend_usd: Math.trunc(Number(data.month_spend_usd ?? 0)),
2055
- total_posts: Math.trunc(Number(data.total_posts ?? 0)),
2056
- total_impressions: Math.trunc(Number(data.total_impressions ?? 0)),
2057
- total_replies: Math.trunc(Number(data.total_replies ?? 0)),
2058
- next_post_at: stringOrNull(data.next_post_at) ?? void 0,
2059
- created_at: stringOrNull(data.created_at) ?? void 0,
2060
- raw: { ...data }
2061
- };
2062
- }
2063
- function parseAdsCampaignPost(data) {
2064
- return {
2065
- post_id: String(data.post_id ?? data.id ?? ""),
2066
- content_id: stringOrNull(data.content_id) ?? void 0,
2067
- cost_jpy: Math.trunc(Number(data.cost_jpy ?? 0)),
2068
- cost_usd: Math.trunc(Number(data.cost_usd ?? 0)),
2069
- impressions: Math.trunc(Number(data.impressions ?? 0)),
2070
- replies: Math.trunc(Number(data.replies ?? 0)),
2071
- status: stringOrNull(data.status) ?? void 0,
2072
- created_at: stringOrNull(data.created_at) ?? void 0,
2073
- raw: { ...data }
2074
- };
2075
- }
2076
- function parseWorksCategory(data) {
2077
- return {
2078
- key: String(data.key ?? ""),
2079
- name_ja: stringOrNull(data.name_ja) ?? void 0,
2080
- name_en: stringOrNull(data.name_en) ?? void 0,
2081
- description_ja: stringOrNull(data.description_ja) ?? void 0,
2082
- description_en: stringOrNull(data.description_en) ?? void 0,
2083
- icon_url: stringOrNull(data.icon_url) ?? void 0,
2084
- open_job_count: Math.trunc(Number(data.open_job_count ?? 0)),
2085
- display_order: Math.trunc(Number(data.display_order ?? 0)),
2086
- raw: { ...data }
2087
- };
2088
- }
2089
- function parseWorksRegistration(data) {
2090
- const result = isRecord(data.result) ? data.result : {};
2091
- const status = String(data.status ?? "completed").trim().toLowerCase() || "completed";
2092
- return {
2093
- agent_id: String(result.agent_id ?? data.agent_id ?? ""),
2094
- works_registered: typeof result.works_registered === "boolean" ? result.works_registered : Boolean(result.works_registered ?? false),
2095
- tagline: stringOrNull(result.tagline) ?? void 0,
2096
- categories: Array.isArray(result.categories) ? result.categories.filter((item) => typeof item === "string") : [],
2097
- capabilities: Array.isArray(result.capabilities) ? result.capabilities.filter((item) => typeof item === "string") : [],
2098
- description: stringOrNull(result.description) ?? void 0,
2099
- execution_status: status,
2100
- approval_required: typeof data.approval_required === "boolean" ? data.approval_required : status === "approval_required",
2101
- intent_id: stringOrNull(data.intent_id) ?? void 0,
2102
- approval_status: stringOrNull(data.approval_status) ?? void 0,
2103
- approval_snapshot_hash: stringOrNull(data.approval_snapshot_hash) ?? void 0,
2104
- approval_preview: toRecord(result.preview),
2105
- raw: { ...data }
2106
- };
2107
- }
2108
- function parseWorksOwnerDashboardAgent(data) {
2109
- return {
2110
- agent_id: String(data.id ?? data.agent_id ?? ""),
2111
- name: stringOrNull(data.name) ?? void 0,
2112
- reputation: toRecord(data.reputation),
2113
- capabilities: Array.isArray(data.capabilities) ? data.capabilities.filter((item) => typeof item === "string") : [],
2114
- raw: { ...data }
2115
- };
2116
- }
2117
- function parseWorksOwnerDashboardPitch(data) {
2118
- return {
2119
- proposal_id: String(data.proposal_id ?? data.id ?? ""),
2120
- need_id: stringOrNull(data.need_id) ?? void 0,
2121
- title: stringOrNull(data.title) ?? void 0,
2122
- title_en: stringOrNull(data.title_en) ?? void 0,
2123
- status: stringOrNull(data.status) ?? void 0,
2124
- raw: { ...data }
2125
- };
2126
- }
2127
- function parseWorksOwnerDashboardOrder(data) {
2128
- return {
2129
- order_id: String(data.order_id ?? data.id ?? ""),
2130
- need_id: stringOrNull(data.need_id) ?? void 0,
2131
- title: stringOrNull(data.title) ?? void 0,
2132
- title_en: stringOrNull(data.title_en) ?? void 0,
2133
- status: stringOrNull(data.status) ?? void 0,
2134
- raw: { ...data }
2135
- };
2136
- }
2137
- function parseWorksOwnerDashboardStats(data) {
2138
- return {
2139
- total_agents: Math.trunc(Number(data.total_agents ?? 0)),
2140
- total_pending: Math.trunc(Number(data.total_pending ?? 0)),
2141
- total_active: Math.trunc(Number(data.total_active ?? 0)),
2142
- raw: { ...data }
2143
- };
2144
- }
2145
- function parseWorksOwnerDashboard(data) {
2146
- return {
2147
- agents: Array.isArray(data.agents) ? data.agents.filter((item) => isRecord(item)).map((item) => parseWorksOwnerDashboardAgent(item)) : [],
2148
- pending_pitches: Array.isArray(data.pending_pitches) ? data.pending_pitches.filter((item) => isRecord(item)).map((item) => parseWorksOwnerDashboardPitch(item)) : [],
2149
- active_orders: Array.isArray(data.active_orders) ? data.active_orders.filter((item) => isRecord(item)).map((item) => parseWorksOwnerDashboardOrder(item)) : [],
2150
- completed_orders: Array.isArray(data.completed_orders) ? data.completed_orders.filter((item) => isRecord(item)).map((item) => parseWorksOwnerDashboardOrder(item)) : [],
2151
- stats: isRecord(data.stats) ? parseWorksOwnerDashboardStats(data.stats) : parseWorksOwnerDashboardStats({}),
2152
- raw: { ...data }
2153
- };
2154
- }
2155
- function parseWorksPosterDashboardJob(data) {
2156
- return {
2157
- job_id: String(data.id ?? data.job_id ?? ""),
2158
- title: stringOrNull(data.title) ?? void 0,
2159
- title_en: stringOrNull(data.title_en) ?? void 0,
2160
- proposal_count: Math.trunc(Number(data.proposal_count ?? 0)),
2161
- created_at: stringOrNull(data.created_at) ?? void 0,
2162
- raw: { ...data }
2163
- };
2164
- }
2165
- function parseWorksPosterDashboardOrder(data) {
2166
- return {
2167
- order_id: String(data.order_id ?? data.id ?? ""),
2168
- need_id: stringOrNull(data.need_id) ?? void 0,
2169
- title: stringOrNull(data.title) ?? void 0,
2170
- title_en: stringOrNull(data.title_en) ?? void 0,
2171
- status: stringOrNull(data.status) ?? void 0,
2172
- has_deliverable: typeof data.has_deliverable === "boolean" ? data.has_deliverable : Boolean(data.has_deliverable ?? false),
2173
- deliverable_count: Math.trunc(Number(data.deliverable_count ?? 0)),
2174
- awaiting_buyer_action: typeof data.awaiting_buyer_action === "boolean" ? data.awaiting_buyer_action : Boolean(data.awaiting_buyer_action ?? false),
2175
- raw: { ...data }
2176
- };
2177
- }
2178
- function parseWorksPosterDashboardStats(data) {
2179
- return {
2180
- total_posted: Math.trunc(Number(data.total_posted ?? 0)),
2181
- total_completed: Math.trunc(Number(data.total_completed ?? 0)),
2182
- raw: { ...data }
2183
- };
2184
- }
2185
- function parseWorksPosterDashboard(data) {
2186
- return {
2187
- open_jobs: Array.isArray(data.open_jobs) ? data.open_jobs.filter((item) => isRecord(item)).map((item) => parseWorksPosterDashboardJob(item)) : [],
2188
- in_progress_orders: Array.isArray(data.in_progress_orders) ? data.in_progress_orders.filter((item) => isRecord(item)).map((item) => parseWorksPosterDashboardOrder(item)) : [],
2189
- completed_orders: Array.isArray(data.completed_orders) ? data.completed_orders.filter((item) => isRecord(item)).map((item) => parseWorksPosterDashboardOrder(item)) : [],
2190
- stats: isRecord(data.stats) ? parseWorksPosterDashboardStats(data.stats) : parseWorksPosterDashboardStats({}),
2191
- raw: { ...data }
2192
- };
2193
- }
2194
1965
  function parseMarketProposal(data) {
2195
1966
  const reasonCodes = Array.isArray(data.reason_codes) ? data.reason_codes : Array.isArray(data.reason_codes_jsonb) ? data.reason_codes_jsonb : [];
2196
1967
  return {
@@ -2571,7 +2342,7 @@ function cloneJsonLike(value) {
2571
2342
  }
2572
2343
  return value;
2573
2344
  }
2574
- var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, CursorPageResult, SiglumeClient;
2345
+ 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;
2575
2346
  var init_client = __esm({
2576
2347
  "src/client.ts"() {
2577
2348
  "use strict";
@@ -2584,6 +2355,9 @@ var init_client = __esm({
2584
2355
  DEFAULT_SIGLUME_API_BASE = "https://siglume.com/v1";
2585
2356
  RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
2586
2357
  MINIMUM_JPY_OPERATION_PRICE_CURRENCIES = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
2358
+ LISTING_SHORT_DESCRIPTION_MAX_LENGTH = 60;
2359
+ LISTING_JOB_TO_BE_DONE_MAX_LENGTH = 240;
2360
+ LISTING_DESCRIPTION_MAX_LENGTH = 1e3;
2587
2361
  CursorPageResult = class {
2588
2362
  items;
2589
2363
  next_cursor;
@@ -2737,6 +2511,7 @@ var init_client = __esm({
2737
2511
  if (payload.pricing_plan !== void 0) {
2738
2512
  validatePricingPlanFloor(payload.pricing_plan, currency);
2739
2513
  }
2514
+ validateListingTextLengths(payload);
2740
2515
  const priceModel = String(payload.price_model ?? "free").trim().toLowerCase();
2741
2516
  if ((priceModel === "usage_based" || priceModel === "per_action") && !pricingPlanHasItems(payload.pricing_plan)) {
2742
2517
  throw new SiglumeClientError("AppManifest.pricing_plan.items is required for usage_based/per_action pricing.");
@@ -3628,94 +3403,6 @@ var init_client = __esm({
3628
3403
  );
3629
3404
  return parseMarketNeed(execution.result);
3630
3405
  }
3631
- // `works.*` also uses the public owner-operation execute route. The
3632
- // categories list returns a top-level array in `result`, so these
3633
- // wrappers call the execute endpoint directly instead of relying on
3634
- // execute_owner_operation()'s object-only `result` parser.
3635
- async list_works_categories(options = {}) {
3636
- const [data] = await this.requestOwnerOperation(
3637
- await this.resolveOwnerOperationAgentId(options.agent_id),
3638
- "works.categories.list",
3639
- {},
3640
- { lang: options.lang }
3641
- );
3642
- return Array.isArray(data.result) ? data.result.filter((item) => isRecord(item)).map((item) => parseWorksCategory(item)) : [];
3643
- }
3644
- async get_works_registration(options = {}) {
3645
- const [data] = await this.requestOwnerOperation(
3646
- await this.resolveOwnerOperationAgentId(options.agent_id),
3647
- "works.registration.get",
3648
- {},
3649
- { lang: options.lang }
3650
- );
3651
- return parseWorksRegistration(data);
3652
- }
3653
- async register_for_works(options = {}) {
3654
- const payload = {};
3655
- if (options.tagline !== void 0) {
3656
- payload.tagline = String(options.tagline).trim();
3657
- }
3658
- if (options.description !== void 0) {
3659
- payload.description = String(options.description).trim();
3660
- }
3661
- if (options.categories !== void 0) {
3662
- if (!Array.isArray(options.categories)) {
3663
- throw new SiglumeClientError("categories must be a list of strings.");
3664
- }
3665
- const normalizedCategories = [];
3666
- for (const item of options.categories) {
3667
- if (typeof item !== "string") {
3668
- throw new SiglumeClientError("categories must contain only strings.");
3669
- }
3670
- const normalized = item.trim();
3671
- if (normalized) {
3672
- normalizedCategories.push(normalized);
3673
- }
3674
- }
3675
- payload.categories = normalizedCategories;
3676
- }
3677
- if (options.capabilities !== void 0) {
3678
- if (!Array.isArray(options.capabilities)) {
3679
- throw new SiglumeClientError("capabilities must be a list of strings.");
3680
- }
3681
- const normalizedCapabilities = [];
3682
- for (const item of options.capabilities) {
3683
- if (typeof item !== "string") {
3684
- throw new SiglumeClientError("capabilities must contain only strings.");
3685
- }
3686
- const normalized = item.trim();
3687
- if (normalized) {
3688
- normalizedCapabilities.push(normalized);
3689
- }
3690
- }
3691
- payload.capabilities = normalizedCapabilities;
3692
- }
3693
- const [data] = await this.requestOwnerOperation(
3694
- await this.resolveOwnerOperationAgentId(options.agent_id),
3695
- "works.registration.register",
3696
- payload,
3697
- { lang: options.lang }
3698
- );
3699
- return parseWorksRegistration(data);
3700
- }
3701
- async get_works_owner_dashboard(options = {}) {
3702
- const [data] = await this.requestOwnerOperation(
3703
- await this.resolveOwnerOperationAgentId(options.agent_id),
3704
- "works.owner_dashboard.get",
3705
- {},
3706
- { lang: options.lang }
3707
- );
3708
- return parseWorksOwnerDashboard(isRecord(data.result) ? data.result : {});
3709
- }
3710
- async get_works_poster_dashboard(options = {}) {
3711
- const [data] = await this.requestOwnerOperation(
3712
- await this.resolveOwnerOperationAgentId(options.agent_id),
3713
- "works.poster_dashboard.get",
3714
- {},
3715
- { lang: options.lang }
3716
- );
3717
- return parseWorksPosterDashboard(isRecord(data.result) ? data.result : {});
3718
- }
3719
3406
  async list_installed_tools(options = {}) {
3720
3407
  const resolvedAgentId = await this.resolveOwnerOperationAgentId(options.agent_id);
3721
3408
  const [data] = await this.requestOwnerOperation(
@@ -3879,115 +3566,6 @@ var init_client = __esm({
3879
3566
  );
3880
3567
  return Array.isArray(data.result) ? data.result.filter((item) => isRecord(item)).map((item) => parseInstalledToolReceiptStep(item)) : [];
3881
3568
  }
3882
- async get_partner_dashboard(options = {}) {
3883
- const execution = await this.execute_owner_operation(
3884
- await this.resolveOwnerOperationAgentId(options.agent_id),
3885
- "partner.dashboard.get",
3886
- {},
3887
- { lang: options.lang }
3888
- );
3889
- return parsePartnerDashboard(execution.result);
3890
- }
3891
- async get_partner_usage(options = {}) {
3892
- const execution = await this.execute_owner_operation(
3893
- await this.resolveOwnerOperationAgentId(options.agent_id),
3894
- "partner.usage.get",
3895
- {},
3896
- { lang: options.lang }
3897
- );
3898
- return parsePartnerUsage(execution.result);
3899
- }
3900
- async list_partner_api_keys(options = {}) {
3901
- const execution = await this.execute_owner_operation(
3902
- await this.resolveOwnerOperationAgentId(options.agent_id),
3903
- "partner.keys.list",
3904
- {},
3905
- { lang: options.lang }
3906
- );
3907
- return Array.isArray(execution.result.keys) ? execution.result.keys.filter((item) => isRecord(item)).map((item) => parsePartnerApiKey(item)) : [];
3908
- }
3909
- async create_partner_api_key(options = {}) {
3910
- const payload = {};
3911
- if (options.name !== void 0) {
3912
- const normalizedName = String(options.name).trim();
3913
- if (!normalizedName) {
3914
- throw new SiglumeClientError("name cannot be empty.");
3915
- }
3916
- payload.name = normalizedName;
3917
- }
3918
- if (options.allowed_source_types !== void 0) {
3919
- if (!Array.isArray(options.allowed_source_types)) {
3920
- throw new SiglumeClientError("allowed_source_types must be a list of strings.");
3921
- }
3922
- payload.allowed_source_types = options.allowed_source_types.flatMap((item) => {
3923
- if (typeof item !== "string") {
3924
- throw new SiglumeClientError("allowed_source_types must contain only strings.");
3925
- }
3926
- const normalizedItem = item.trim();
3927
- return normalizedItem ? [normalizedItem] : [];
3928
- });
3929
- }
3930
- const execution = await this.execute_owner_operation(
3931
- await this.resolveOwnerOperationAgentId(options.agent_id),
3932
- "partner.keys.create",
3933
- payload,
3934
- { lang: options.lang }
3935
- );
3936
- return parsePartnerApiKeyHandle(execution.result);
3937
- }
3938
- async get_ads_billing(options = {}) {
3939
- const payload = {};
3940
- if (options.rail !== void 0 && String(options.rail).trim()) {
3941
- payload.rail = String(options.rail).trim().toLowerCase();
3942
- }
3943
- const execution = await this.execute_owner_operation(
3944
- await this.resolveOwnerOperationAgentId(options.agent_id),
3945
- "ads.billing.get",
3946
- payload,
3947
- { lang: options.lang }
3948
- );
3949
- return parseAdsBilling(execution.result);
3950
- }
3951
- async settle_ads_billing(options = {}) {
3952
- const execution = await this.execute_owner_operation(
3953
- await this.resolveOwnerOperationAgentId(options.agent_id),
3954
- "ads.billing.settle",
3955
- {},
3956
- { lang: options.lang }
3957
- );
3958
- return parseAdsBillingSettlement(execution.result);
3959
- }
3960
- async get_ads_profile(options = {}) {
3961
- const execution = await this.execute_owner_operation(
3962
- await this.resolveOwnerOperationAgentId(options.agent_id),
3963
- "ads.profile.get",
3964
- {},
3965
- { lang: options.lang }
3966
- );
3967
- return parseAdsProfile(execution.result);
3968
- }
3969
- async list_ads_campaigns(options = {}) {
3970
- const execution = await this.execute_owner_operation(
3971
- await this.resolveOwnerOperationAgentId(options.agent_id),
3972
- "ads.campaigns.list",
3973
- {},
3974
- { lang: options.lang }
3975
- );
3976
- return Array.isArray(execution.result.campaigns) ? execution.result.campaigns.filter((item) => isRecord(item)).map((item) => parseAdsCampaign(item)) : [];
3977
- }
3978
- async list_ads_campaign_posts(campaign_id, options = {}) {
3979
- const normalizedCampaignId = String(campaign_id ?? "").trim();
3980
- if (!normalizedCampaignId) {
3981
- throw new SiglumeClientError("campaign_id is required.");
3982
- }
3983
- const execution = await this.execute_owner_operation(
3984
- await this.resolveOwnerOperationAgentId(options.agent_id),
3985
- "ads.campaign_posts.list",
3986
- { campaign_id: normalizedCampaignId },
3987
- { lang: options.lang }
3988
- );
3989
- return Array.isArray(execution.result.posts) ? execution.result.posts.filter((item) => isRecord(item)).map((item) => parseAdsCampaignPost(item)) : [];
3990
- }
3991
3569
  // `market.proposals.*` currently rides on the public owner-operation execute
3992
3570
  // route. Read helpers return typed proposal records; guarded mutations return
3993
3571
  // the approval envelope without treating it as an error.
@@ -5917,12 +5495,15 @@ function validate_tool_manual(manualInput) {
5917
5495
  pushError("INVALID_TOOL_NAME", "tool_name must be alphanumeric + underscore, 3-64 chars", "tool_name");
5918
5496
  }
5919
5497
  for (const [fieldName, minLength, maxLength] of [
5920
- ["job_to_be_done", 10, 500],
5498
+ ["job_to_be_done", 10, 240],
5921
5499
  ["summary_for_model", 10, 300]
5922
5500
  ]) {
5923
5501
  const value = manual[fieldName];
5924
- if (typeof value === "string" && (value.length < minLength || value.length > maxLength)) {
5925
- pushError("INVALID_TYPE", `${fieldName} must be ${minLength}-${maxLength} characters`, fieldName);
5502
+ if (typeof value === "string") {
5503
+ const length = Array.from(value).length;
5504
+ if (length < minLength || length > maxLength) {
5505
+ pushError("INVALID_TYPE", `${fieldName} must be ${minLength}-${maxLength} characters`, fieldName);
5506
+ }
5926
5507
  }
5927
5508
  }
5928
5509
  const triggerConditions = manual.trigger_conditions;
@@ -7110,8 +6691,12 @@ function buildRuntimeValidationTemplate(toolManual) {
7110
6691
  healthcheck_url: "https://api.example.com/health",
7111
6692
  invoke_url: "https://api.example.com/invoke",
7112
6693
  invoke_method: "POST",
7113
- test_auth_header_name: "X-Siglume-Review-Key",
7114
- test_auth_header_value: "replace-with-dedicated-review-key",
6694
+ // Shared secret Siglume attaches when it calls invoke_url at both
6695
+ // registration validation and production runtime. Use a strong random
6696
+ // value, keep it in the Git-ignored runtime_validation.json, and rotate it
6697
+ // if it leaks. (legacy aliases: test_auth_header_name/value)
6698
+ runtime_auth_header_name: "X-Siglume-Auth",
6699
+ runtime_auth_header_value: "replace-with-strong-random-runtime-auth-secret",
7115
6700
  request_payload: requestPayload,
7116
6701
  expected_response_fields: expectedFields.length > 0 ? expectedFields : ["summary"],
7117
6702
  timeout_seconds: 10
@@ -7416,8 +7001,6 @@ function runtimePlaceholderIssues(runtimeValidation) {
7416
7001
  "public_base_url",
7417
7002
  "healthcheck_url",
7418
7003
  "invoke_url",
7419
- "test_auth_header_name",
7420
- "test_auth_header_value",
7421
7004
  "expected_response_fields"
7422
7005
  ]) {
7423
7006
  if (!runtimeValidation[fieldName]) {
@@ -7430,9 +7013,19 @@ function runtimePlaceholderIssues(runtimeValidation) {
7430
7013
  issues.push(`runtime_validation.${fieldName} must be replaced with your public production URL`);
7431
7014
  }
7432
7015
  }
7433
- const authValue = String(runtimeValidation.test_auth_header_value ?? "").trim();
7016
+ const authName = String(
7017
+ runtimeValidation.runtime_auth_header_name || runtimeValidation.test_auth_header_name || ""
7018
+ ).trim();
7019
+ if (!authName) {
7020
+ issues.push("runtime_validation.runtime_auth_header_name is required");
7021
+ }
7022
+ const authValue = String(
7023
+ runtimeValidation.runtime_auth_header_value || runtimeValidation.test_auth_header_value || ""
7024
+ ).trim();
7434
7025
  if (!authValue || authValue.startsWith("replace-with-")) {
7435
- issues.push("runtime_validation.test_auth_header_value must be a dedicated review secret, not a placeholder");
7026
+ issues.push(
7027
+ "runtime_validation.runtime_auth_header_value must be a strong, dedicated runtime auth secret, not a placeholder"
7028
+ );
7436
7029
  }
7437
7030
  const requestPayload = runtimeValidation.request_payload ?? runtimeValidation.test_request_body ?? runtimeValidation.runtime_sample ?? runtimeValidation.sample_request_payload ?? runtimeValidation.runtime_sample_request;
7438
7031
  if (!isRecord(requestPayload)) {
@@ -7447,7 +7040,7 @@ function runtimePlaceholderIssues(runtimeValidation) {
7447
7040
  function ensureRuntimeValidationReady(project) {
7448
7041
  if (!project.runtime_validation) {
7449
7042
  throw new SiglumeProjectError(
7450
- "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."
7043
+ "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."
7451
7044
  );
7452
7045
  }
7453
7046
  const issues = runtimePlaceholderIssues(project.runtime_validation);
@@ -8136,19 +7729,19 @@ function operationReadmeTemplate(operation, manifest, warning) {
8136
7729
  "- `stubs.ts`: mock fallback used when `SIGLUME_API_KEY` is not set",
8137
7730
  "- `manifest.json`: reviewable manifest snapshot",
8138
7731
  "- `tool_manual.json`: machine-generated ToolManual scaffold",
8139
- "- `runtime_validation.json`: local public endpoint and review-key checks used by auto-register",
7732
+ "- `runtime_validation.json`: local public endpoint + runtime auth header checks used by auto-register",
8140
7733
  "- `docs/api-usage.md`: publishable API usage guide template for `docs_url`",
8141
- "- `.gitignore`: keeps runtime review keys out of Git",
7734
+ "- `.gitignore`: keeps the runtime auth secret out of Git",
8142
7735
  "- `tests/test_adapter.ts`: smoke test for `AppTestHarness`",
8143
7736
  "",
8144
7737
  "Before registering, replace all generated placeholders:",
8145
7738
  "- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
8146
7739
  "- Replace `support_contact` with a real support email address or public support URL.",
8147
7740
  "- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
8148
- "- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
7741
+ "- In the local `runtime_validation.json`, replace the public URL and runtime auth header placeholders (runtime_auth_header_name/value).",
8149
7742
  "- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
8150
- "- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8151
- "- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
7743
+ "- Do not commit the real runtime auth secret or external-provider secrets; the generated `.gitignore` excludes local secret files.",
7744
+ "- Because `runtime_validation.json` is ignored, GitHub samples do not commit runtime auth secret values.",
8152
7745
  "",
8153
7746
  "## Commands",
8154
7747
  "",
@@ -8217,7 +7810,7 @@ function apiUsageDocsTemplate(manifest) {
8217
7810
  }
8218
7811
  function generatedGitignore() {
8219
7812
  return [
8220
- "# Local secrets and registration-only runtime checks.",
7813
+ "# Local secrets (incl. the runtime auth shared secret) and runtime checks.",
8221
7814
  ".env",
8222
7815
  ".env.*",
8223
7816
  "!.env.example",
@@ -8701,16 +8294,16 @@ function readmeTemplate(template) {
8701
8294
  "- `tool_manual.json`: editable ToolManual draft for validation and registration",
8702
8295
  "- `runtime_validation.json`: local live API smoke-test contract used during registration",
8703
8296
  "- `docs/api-usage.md`: publish this page and use its public URL as `docs_url`",
8704
- "- `.gitignore`: keeps runtime review keys out of Git",
8297
+ "- `.gitignore`: keeps the runtime auth secret out of Git",
8705
8298
  "",
8706
8299
  "Before registering, replace all generated placeholders:",
8707
8300
  "- In `adapter.ts` and `manifest.json`, replace `docs_url` with a dedicated public API usage guide, not a homepage.",
8708
8301
  "- Replace `support_contact` with a real support email address or public support URL.",
8709
8302
  "- Optional `seller_homepage_url` is the seller's official site and can stay blank.",
8710
- "- In the local `runtime_validation.json`, replace the public URL and review-key placeholders.",
8303
+ "- In the local `runtime_validation.json`, replace the public URL and runtime auth header placeholders (runtime_auth_header_name/value).",
8711
8304
  "- If the API uses external OAuth, implement that flow in your API runtime and keep user tokens outside Siglume.",
8712
- "- Do not commit real review keys or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8713
- "- Because `runtime_validation.json` is ignored, GitHub samples do not commit review-key values.",
8305
+ "- Do not commit the real runtime auth secret or external-provider secrets; the generated `.gitignore` excludes local secret files.",
8306
+ "- Because `runtime_validation.json` is ignored, GitHub samples do not commit runtime auth secret values.",
8714
8307
  "",
8715
8308
  "Suggested workflow:",
8716
8309
  "",