@standardagents/builder 0.27.8 → 0.27.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -859,30 +859,40 @@ function resolveDefinedProviderConfig(definition, env2) {
859
859
  missing.push(slot.defaultEnv);
860
860
  }
861
861
  }
862
- for (const [slotName, source] of Object.entries(definition.config ?? {})) {
863
- if (source.type === "const") {
864
- values[slotName] = source.value;
865
- continue;
866
- }
867
- envKeys.push(source.name);
868
- variables.push({
869
- name: source.name,
870
- type: normalizeEnvType(source.valueType),
871
- required: source.required !== false && source.default === void 0,
872
- description: source.description ?? ""
873
- });
874
- const envValue = env2[source.name];
875
- if (envValue !== void 0 && envValue !== null && envValue !== "") {
876
- values[slotName] = coerceProviderConfigValue(envValue, source.valueType);
877
- continue;
878
- }
879
- if (source.default !== void 0) {
880
- values[slotName] = source.default;
881
- continue;
862
+ const isConfigSource = (value) => !!value && typeof value === "object" && !Array.isArray(value) && (value.type === "env" || value.type === "const");
863
+ const resolveConfigValue = (value) => {
864
+ if (value === null || value === void 0) return void 0;
865
+ if (isConfigSource(value)) {
866
+ const source = value;
867
+ if (source.type === "const") return source.value;
868
+ envKeys.push(source.name);
869
+ variables.push({
870
+ name: source.name,
871
+ type: normalizeEnvType(source.valueType),
872
+ required: source.required !== false && source.default === void 0,
873
+ description: source.description ?? ""
874
+ });
875
+ const envValue = env2[source.name];
876
+ if (envValue !== void 0 && envValue !== null && envValue !== "") {
877
+ return coerceProviderConfigValue(envValue, source.valueType);
878
+ }
879
+ if (source.default !== void 0) return source.default;
880
+ if (source.required !== false) missing.push(source.name);
881
+ return void 0;
882
882
  }
883
- if (source.required !== false) {
884
- missing.push(source.name);
883
+ if (typeof value === "object" && !Array.isArray(value)) {
884
+ const out = {};
885
+ for (const [key, entry] of Object.entries(value)) {
886
+ const resolved = resolveConfigValue(entry);
887
+ if (resolved !== void 0) out[key] = resolved;
888
+ }
889
+ return Object.keys(out).length > 0 ? out : void 0;
885
890
  }
891
+ return value;
892
+ };
893
+ for (const [slotName, source] of Object.entries(definition.config ?? {})) {
894
+ const resolved = resolveConfigValue(source);
895
+ if (resolved !== void 0) values[slotName] = resolved;
886
896
  }
887
897
  return {
888
898
  providerConfig: values,
@@ -42323,7 +42333,12 @@ function transformUserMessage(msg) {
42323
42333
  const content = transformMessageContent2(msg.content);
42324
42334
  return {
42325
42335
  role: "user",
42326
- content: typeof content === "string" ? content : content
42336
+ // Always emit STRUCTURED content parts, never a bare string. Both are
42337
+ // valid on api.openai.com, but the canonical Responses shape (an array of
42338
+ // typed `input_text`/`input_image` parts) is what the assistant path
42339
+ // already emits and what the stricter ChatGPT Codex backend requires — a
42340
+ // plain string there earns a bodyless 400.
42341
+ content: typeof content === "string" ? [{ type: "input_text", text: content }] : content
42327
42342
  };
42328
42343
  }
42329
42344
  function transformAssistantMessage2(msg) {
@@ -43199,10 +43214,12 @@ var init_dist6 = __esm({
43199
43214
  async getClient() {
43200
43215
  if (!this.client) {
43201
43216
  const { default: OpenAI } = await import('openai');
43217
+ const defaultHeaders = this.config.defaultHeaders;
43202
43218
  this.client = new OpenAI({
43203
43219
  apiKey: this.config.apiKey,
43204
43220
  baseURL: this.config.baseUrl,
43205
- timeout: this.config.timeout
43221
+ timeout: this.config.timeout,
43222
+ ...defaultHeaders ? { defaultHeaders } : {}
43206
43223
  });
43207
43224
  }
43208
43225
  return this.client;
@@ -43607,6 +43624,17 @@ var init_dist6 = __esm({
43607
43624
  // ============================================================================
43608
43625
  // Error Handling
43609
43626
  // ============================================================================
43627
+ /**
43628
+ * True when a 403 is an edge/CDN block page (HTML challenge such as
43629
+ * Cloudflare's "Unable to load site") rather than a real API auth error.
43630
+ * Real API 403s carry a JSON error body; edge blocks carry HTML.
43631
+ */
43632
+ static isEdgeBlock(error) {
43633
+ const parts = [error?.message];
43634
+ if (typeof error?.error === "string") parts.push(error.error);
43635
+ const body = parts.filter(Boolean).join(" ");
43636
+ return /<html|<!doctype|unable to load site|ray id|cloudflare|attention required/i.test(body);
43637
+ }
43610
43638
  toProviderError(error) {
43611
43639
  if (error instanceof ProviderError) {
43612
43640
  return error;
@@ -43618,6 +43646,9 @@ var init_dist6 = __esm({
43618
43646
  if (status === 429) {
43619
43647
  return new ProviderError(error.message, "rate_limit", status, retryAfter);
43620
43648
  }
43649
+ if (status === 403 && _OpenAIProvider.isEdgeBlock(anyError)) {
43650
+ return new ProviderError(error.message, "server_error", status);
43651
+ }
43621
43652
  if (status === 401 || status === 403) {
43622
43653
  return new ProviderError(error.message, "auth_error", status);
43623
43654
  }
@@ -66246,7 +66277,7 @@ var config_get_default = defineController2(async ({ config, env: env2, req }) =>
66246
66277
  });
66247
66278
 
66248
66279
  // src/version.ts
66249
- var BUILDER_VERSION = "0.27.8".length > 0 ? "0.27.8" : "dev";
66280
+ var BUILDER_VERSION = "0.27.10".length > 0 ? "0.27.10" : "dev";
66250
66281
 
66251
66282
  // src/api/diagnostics.get.ts
66252
66283
  init_LLMRequest();