veryfront 0.1.1002 → 0.1.1004

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/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.1002",
3
+ "version": "0.1.1004",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -1 +1 @@
1
- {"version":3,"file":"openai-chat-request-builder.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-chat-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC/G,OAAO,EACL,KAAK,6BAA6B,EAGnC,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,qBAAqB,GAC7B;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB,GACC;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAEJ,MAAM,MAAM,+BAA+B,GAAG;IAC5C,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,6BAA6B,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EACX;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAChB;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAChB;QACA,IAAI,EAAE,aAAa,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACL,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAUF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,2BAA2B,CA4G7B"}
1
+ {"version":3,"file":"openai-chat-request-builder.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-chat-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC/G,OAAO,EACL,KAAK,6BAA6B,EAGnC,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,qBAAqB,GAC7B;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB,GACC;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAEJ,MAAM,MAAM,+BAA+B,GAAG;IAC5C,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,6BAA6B,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EACX;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAChB;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAChB;QACA,IAAI,EAAE,aAAa,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACL,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAUF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,2BAA2B,CAmH7B"}
@@ -98,14 +98,31 @@ export function buildOpenAIChatRequest(modelId, providerName, options, stream, w
98
98
  }
99
99
  : {}),
100
100
  };
101
- const providerOpts = readProviderOptions(options.providerOptions, "openai", providerName);
102
- // Normalize max_tokens to max_completion_tokens for native OpenAI models.
103
- if (isNativeOpenAIModel(modelId) && "max_tokens" in providerOpts) {
104
- if (!("max_completion_tokens" in providerOpts)) {
105
- providerOpts.max_completion_tokens = providerOpts.max_tokens;
106
- }
107
- delete providerOpts.max_tokens;
101
+ // Env-BYOK users historically registered options under "openai-compatible";
102
+ // keep merging that bucket at the lowest precedence. max_tokens is normalized
103
+ // per bucket BEFORE merging so a higher-precedence bucket's max_tokens
104
+ // override still beats a lower bucket's max_completion_tokens.
105
+ const bucketNames = [
106
+ ...(providerName === "openai" ? ["openai-compatible"] : []),
107
+ "openai",
108
+ providerName,
109
+ ];
110
+ const providerOpts = {};
111
+ for (const bucketName of bucketNames) {
112
+ Object.assign(providerOpts, normalizeNativeMaxTokens(readProviderOptions(options.providerOptions, bucketName), modelId));
108
113
  }
109
114
  Object.assign(body, providerOpts);
110
115
  return body;
111
116
  }
117
+ /** Normalizes max_tokens to max_completion_tokens for native OpenAI models. */
118
+ function normalizeNativeMaxTokens(bucket, modelId) {
119
+ if (!isNativeOpenAIModel(modelId) || !("max_tokens" in bucket)) {
120
+ return bucket;
121
+ }
122
+ const normalized = { ...bucket };
123
+ if (!("max_completion_tokens" in normalized)) {
124
+ normalized.max_completion_tokens = normalized.max_tokens;
125
+ }
126
+ delete normalized.max_tokens;
127
+ return normalized;
128
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"openai-reasoning-models.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-reasoning-models.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9D,MAAM,MAAM,6BAA6B,GAAG,qBAAqB,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,6BAA6B,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;CAChC,CAAC;AAIF,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAG5E;AAuBD,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,EACf,YAAY,SAAW,GACtB,qBAAqB,GAAG,SAAS,CAwBnC;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,6BAA6B,GAAG,SAAS,GAChD,uBAAuB,GAAG,SAAS,CAoBrC;AAED,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,uBAAuB,GACjC,OAAO,CAET;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,SAAW,GAAG,OAAO,CAExF;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIpE"}
1
+ {"version":3,"file":"openai-reasoning-models.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-reasoning-models.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9D,MAAM,MAAM,6BAA6B,GAAG,qBAAqB,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,6BAA6B,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;CAChC,CAAC;AAIF,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAG5E;AAuBD,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,EACf,YAAY,SAAW,GACtB,qBAAqB,GAAG,SAAS,CAwBnC;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,6BAA6B,GAAG,SAAS,GAChD,uBAAuB,GAAG,SAAS,CAoBrC;AAED,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,uBAAuB,GACjC,OAAO,CAIT;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,SAAW,GAAG,OAAO,CAExF;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIpE"}
@@ -59,7 +59,9 @@ export function resolveOpenAIReasoningConfig(modelId, providerName, option) {
59
59
  }
60
60
  }
61
61
  export function shouldRequestOpenAIReasoningSummary(providerName, reasoning) {
62
- return reasoning.source === "explicit" || supportsDefaultReasoningParams(providerName);
62
+ // Default-reasoning BYOK "openai" requests must not ask for summaries:
63
+ // unverified customer organizations get a 400 from the Responses API.
64
+ return reasoning.source === "explicit" || providerName.toLowerCase() === "veryfront-cloud";
63
65
  }
64
66
  export function isOpenAIReasoningModel(modelId, providerName = "openai") {
65
67
  return getDefaultOpenAIReasoningEffort(modelId, providerName) !== undefined;
@@ -3,6 +3,7 @@ export type OpenAIResponsesInputItem = Record<string, unknown>;
3
3
  export type OpenAIResponsesRequest = {
4
4
  model: string;
5
5
  input: OpenAIResponsesInputItem[];
6
+ store?: boolean;
6
7
  instructions?: string;
7
8
  stream?: boolean;
8
9
  max_output_tokens?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"openai-responses-request-builder.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-responses-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,+BAA+B,EAEhC,MAAM,kCAAkC,CAAC;AAO1C,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AA6IF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,sBAAsB,CA0FxB"}
1
+ {"version":3,"file":"openai-responses-request-builder.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-responses-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,+BAA+B,EAEhC,MAAM,kCAAkC,CAAC;AAO1C,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AA6IF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,sBAAsB,CAsGxB"}
@@ -162,6 +162,8 @@ export function buildOpenAIResponsesRequest(modelId, providerName, options, stre
162
162
  const body = {
163
163
  model: modelId,
164
164
  input,
165
+ // Stay stateless: encrypted reasoning content is never round-tripped via include.
166
+ store: false,
165
167
  ...(instructions !== undefined ? { instructions } : {}),
166
168
  ...(stream ? { stream: true } : {}),
167
169
  ...(options.maxOutputTokens !== undefined
@@ -208,6 +210,8 @@ export function buildOpenAIResponsesRequest(modelId, providerName, options, stre
208
210
  }
209
211
  : {}),
210
212
  };
211
- Object.assign(body, readProviderOptions(options.providerOptions, "openai", providerName));
213
+ // Env-BYOK users historically registered options under "openai-compatible";
214
+ // keep merging that bucket at the lowest precedence.
215
+ Object.assign(body, readProviderOptions(options.providerOptions, ...(providerName === "openai" ? ["openai-compatible"] : []), "openai", providerName));
212
216
  return body;
213
217
  }
@@ -34,4 +34,6 @@ export declare function inlineRuntimeMessageFileContents(messages: readonly Chat
34
34
  abortSignal?: AbortSignal;
35
35
  fetchTimeoutMs?: number;
36
36
  }): Promise<ChatUiMessage[]>;
37
+ /** Composes abort signals manually for runtimes without AbortSignal.any (Node < 20.3). */
38
+ export declare function composeAbortSignals(signals: readonly AbortSignal[]): AbortSignal;
37
39
  //# sourceMappingURL=message-file-url-refresh.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-file-url-refresh.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/message-file-url-refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAE1B,MAAM,qBAAqB,CAAC;AAK7B,mDAAmD;AACnD,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,yDAAyD;AACzD,MAAM,MAAM,sBAAsB,GAAG,CACnC,KAAK,EAAE,2BAA2B,KAC/B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjC,sDAAsD;AACtD,MAAM,MAAM,8BAA8B,GAAG;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,4DAA4D;AAC5D,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,8BAA8B,KAClC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjC,mDAAmD;AACnD,wBAAgB,+BAA+B,CAC7C,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,yBAAyB,CAe3B;AAED,0CAA0C;AAC1C,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,aAAa,EAAE,CAAC,CAqC1B;AAED,2EAA2E;AAC3E,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,gBAAgB,GAAE,yBAA6D,EAC/E,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACpB,GACL,OAAO,CAAC,aAAa,EAAE,CAAC,CA4C1B"}
1
+ {"version":3,"file":"message-file-url-refresh.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/message-file-url-refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAE1B,MAAM,qBAAqB,CAAC;AAM7B,mDAAmD;AACnD,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,yDAAyD;AACzD,MAAM,MAAM,sBAAsB,GAAG,CACnC,KAAK,EAAE,2BAA2B,KAC/B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjC,sDAAsD;AACtD,MAAM,MAAM,8BAA8B,GAAG;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,4DAA4D;AAC5D,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,8BAA8B,KAClC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjC,mDAAmD;AACnD,wBAAgB,+BAA+B,CAC7C,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,yBAAyB,CAe3B;AAED,0CAA0C;AAC1C,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,aAAa,EAAE,CAAC,CAqC1B;AAED,2EAA2E;AAC3E,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,gBAAgB,GAAE,yBAA6D,EAC/E,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACpB,GACL,OAAO,CAAC,aAAa,EAAE,CAAC,CA0F1B;AAsLD,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAuBhF"}
@@ -1,5 +1,6 @@
1
1
  import { isTextPreviewFile, } from "../../chat/types.js";
2
2
  const MAX_INLINE_FILE_CONTENT_CHARS = 200_000;
3
+ const MAX_TOTAL_INLINE_FILE_CONTENT_CHARS = 400_000;
3
4
  const DEFAULT_RUNTIME_FILE_CONTENT_FETCH_TIMEOUT_MS = 15_000;
4
5
  /** Creates a safe runtime file content fetcher. */
5
6
  export function createRuntimeFileContentFetcher(options = {}) {
@@ -51,16 +52,21 @@ export async function resolveRuntimeMessageFileUrls(messages, resolveFileUrl) {
51
52
  /** Fetches text attachment bodies and adds them as adjacent text parts. */
52
53
  export async function inlineRuntimeMessageFileContents(messages, fetchFileContent = createRuntimeFileContentFetcher(), options = {}) {
53
54
  const contentByUrl = new Map();
54
- return Promise.all(messages.map(async (message) => {
55
- if (!message.parts.some((part) => shouldInlineFileContent(part))) {
56
- return message;
57
- }
58
- const parts = [];
59
- for (const part of message.parts) {
60
- parts.push(part);
61
- const file = getInlineableFilePart(part);
55
+ const newestUserMessageIndex = findNewestUserMessageIndex(messages);
56
+ const inlineTextByPart = new Map();
57
+ let remainingBudget = MAX_TOTAL_INLINE_FILE_CONTENT_CHARS;
58
+ // Allocate the aggregate inline budget newest-first so the most recent
59
+ // attachments win, then skip fetching entirely once the budget is spent.
60
+ for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex--) {
61
+ const message = messages[messageIndex];
62
+ for (let partIndex = 0; partIndex < message.parts.length; partIndex++) {
63
+ const file = getInlineableFilePart(message.parts[partIndex]);
62
64
  if (!file)
63
65
  continue;
66
+ if (remainingBudget <= 0) {
67
+ inlineTextByPart.set(`${messageIndex}:${partIndex}`, "[attachment content omitted: inline budget exceeded]");
68
+ continue;
69
+ }
64
70
  let contentPromise = contentByUrl.get(file.url);
65
71
  if (!contentPromise) {
66
72
  contentPromise = fetchFileContent({
@@ -76,16 +82,53 @@ export async function inlineRuntimeMessageFileContents(messages, fetchFileConten
76
82
  }).then(normalizeInlineFileContent);
77
83
  contentByUrl.set(file.url, contentPromise);
78
84
  }
79
- const content = await contentPromise;
80
- if (!content)
85
+ let inlineContent;
86
+ try {
87
+ inlineContent = await contentPromise;
88
+ }
89
+ catch (error) {
90
+ // Attachments on the newest user message must stay hard failures, and
91
+ // caller aborts always propagate; stale history attachments degrade.
92
+ if (messageIndex === newestUserMessageIndex || options.abortSignal?.aborted) {
93
+ throw error;
94
+ }
95
+ inlineTextByPart.set(`${messageIndex}:${partIndex}`, `[attachment unavailable: ${file.filename ?? file.uploadId ?? "file"}]`);
81
96
  continue;
82
- parts.push({
83
- type: "text",
84
- text: buildInlineFileContentText(file, content),
85
- });
97
+ }
98
+ if (!inlineContent)
99
+ continue;
100
+ let content = inlineContent.content;
101
+ let truncated = inlineContent.truncated;
102
+ if (content.length > remainingBudget) {
103
+ content = content.slice(0, remainingBudget);
104
+ truncated = true;
105
+ }
106
+ remainingBudget -= content.length;
107
+ inlineTextByPart.set(`${messageIndex}:${partIndex}`, buildInlineFileContentText(file, truncated ? `${content}\n\n[Attachment content truncated]` : content));
108
+ }
109
+ }
110
+ return messages.map((message, messageIndex) => {
111
+ if (!message.parts.some((part) => shouldInlineFileContent(part))) {
112
+ return message;
113
+ }
114
+ const parts = [];
115
+ for (let partIndex = 0; partIndex < message.parts.length; partIndex++) {
116
+ parts.push(message.parts[partIndex]);
117
+ const text = inlineTextByPart.get(`${messageIndex}:${partIndex}`);
118
+ if (text) {
119
+ parts.push({ type: "text", text });
120
+ }
86
121
  }
87
122
  return { ...message, parts };
88
- }));
123
+ });
124
+ }
125
+ function findNewestUserMessageIndex(messages) {
126
+ for (let index = messages.length - 1; index >= 0; index--) {
127
+ if (messages[index]?.role === "user") {
128
+ return index;
129
+ }
130
+ }
131
+ return -1;
89
132
  }
90
133
  function isRecord(value) {
91
134
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -207,6 +250,37 @@ function appendRuntimeTextContentUntilInlineLimit(content, decoded) {
207
250
  }
208
251
  return { content: `${content}${decoded}`, reachedLimit: false };
209
252
  }
253
+ /** Composes abort signals manually for runtimes without AbortSignal.any (Node < 20.3). */
254
+ export function composeAbortSignals(signals) {
255
+ const controller = new AbortController();
256
+ const removeListeners = [];
257
+ const detachAll = () => {
258
+ for (const removeListener of removeListeners) {
259
+ removeListener();
260
+ }
261
+ removeListeners.length = 0;
262
+ };
263
+ for (const signal of signals) {
264
+ if (signal.aborted) {
265
+ detachAll();
266
+ controller.abort(signal.reason);
267
+ return controller.signal;
268
+ }
269
+ const onAbort = () => controller.abort(signal.reason);
270
+ signal.addEventListener("abort", onAbort, { once: true });
271
+ removeListeners.push(() => signal.removeEventListener("abort", onAbort));
272
+ }
273
+ // Detach listeners from the still-pending source signals once any of them
274
+ // fires, so long-lived caller signals don't accumulate stale listeners.
275
+ controller.signal.addEventListener("abort", detachAll, { once: true });
276
+ return controller.signal;
277
+ }
278
+ function anyAbortSignal(signals) {
279
+ if (typeof AbortSignal.any === "function") {
280
+ return AbortSignal.any([...signals]);
281
+ }
282
+ return composeAbortSignals(signals);
283
+ }
210
284
  function createRuntimeFileContentFetchSignal(abortSignal, timeoutMs) {
211
285
  const timeoutSignal = AbortSignal.timeout(Math.max(0, timeoutMs));
212
286
  if (!abortSignal) {
@@ -217,7 +291,7 @@ function createRuntimeFileContentFetchSignal(abortSignal, timeoutMs) {
217
291
  };
218
292
  }
219
293
  return {
220
- signal: AbortSignal.any([abortSignal, timeoutSignal]),
294
+ signal: anyAbortSignal([abortSignal, timeoutSignal]),
221
295
  wasAbortedByCaller: () => abortSignal.aborted,
222
296
  didTimeout: () => timeoutSignal.aborted,
223
297
  };
@@ -277,9 +351,9 @@ function normalizeInlineFileContent(content) {
277
351
  if (!content || content.trim().length === 0)
278
352
  return undefined;
279
353
  if (content.length <= MAX_INLINE_FILE_CONTENT_CHARS) {
280
- return content;
354
+ return { content, truncated: false };
281
355
  }
282
- return `${content.slice(0, MAX_INLINE_FILE_CONTENT_CHARS)}\n\n[Attachment content truncated]`;
356
+ return { content: content.slice(0, MAX_INLINE_FILE_CONTENT_CHARS), truncated: true };
283
357
  }
284
358
  function escapeXmlAttr(value) {
285
359
  return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -1 +1 @@
1
- {"version":3,"file":"transpiler.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/transpiler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA6IvD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAwGlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
1
+ {"version":3,"file":"transpiler.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/transpiler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA4MvD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAgIlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -27,7 +27,50 @@ import * as evalMod from "../eval/index.js";
27
27
  import * as metricsMod from "../metrics/index.js";
28
28
  import * as schemasMod from "../schemas/index.js";
29
29
  import * as chatUploadsMod from "../chat/upload-handler.js";
30
+ // Keyed by entry file + entry source hash; each entry additionally records the
31
+ // bundled dependency contents it was built from and is only served while those
32
+ // still match (see findCachedModuleWithFreshDeps).
30
33
  const transpileCache = new Map();
34
+ const textEncoder = new TextEncoder();
35
+ async function hashSource(source) {
36
+ const digest = await dntShim.crypto.subtle.digest("SHA-256", textEncoder.encode(source));
37
+ return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
38
+ }
39
+ /**
40
+ * Returns the first cached module whose recorded bundled-dependency contents
41
+ * still match what the current adapter serves. esbuild inlines relative
42
+ * imports into the bundle, so an unchanged entry file does not guarantee an
43
+ * unchanged module: a dependency edited by a new release (or differing between
44
+ * two projects that share the same entry source) must invalidate the entry.
45
+ */
46
+ async function findCachedModuleWithFreshDeps(entries, context) {
47
+ const hashByPath = new Map();
48
+ for (const entry of entries) {
49
+ let depsMatch = true;
50
+ for (const dep of entry.deps) {
51
+ let hash = hashByPath.get(dep.path);
52
+ if (!hashByPath.has(dep.path)) {
53
+ try {
54
+ const content = context.fsAdapter
55
+ ? await context.fsAdapter.readFile(dep.path)
56
+ : await createFileSystem().readTextFile(dep.path);
57
+ hash = await hashSource(content);
58
+ }
59
+ catch {
60
+ hash = undefined;
61
+ }
62
+ hashByPath.set(dep.path, hash);
63
+ }
64
+ if (hash === undefined || hash !== dep.hash) {
65
+ depsMatch = false;
66
+ break;
67
+ }
68
+ }
69
+ if (depsMatch)
70
+ return entry.module;
71
+ }
72
+ return undefined;
73
+ }
31
74
  // Setup veryfront modules as globals for compiled binary support
32
75
  let veryfrontGlobalsInitialized = false;
33
76
  /**
@@ -57,7 +100,7 @@ async function ensureVeryfrontGlobals() {
57
100
  /**
58
101
  * Create an esbuild plugin for resolving files via fsAdapter
59
102
  */
60
- function createFsAdapterPlugin(fsAdapter) {
103
+ function createFsAdapterPlugin(fsAdapter, onDependencyLoaded) {
61
104
  const existsCache = new Map();
62
105
  async function checkExists(filePath) {
63
106
  const cached = existsCache.get(filePath);
@@ -108,6 +151,7 @@ function createFsAdapterPlugin(fsAdapter) {
108
151
  build.onLoad({ filter: /.*/, namespace: "fsadapter" }, wrapWithCurrentContext(async (args) => {
109
152
  try {
110
153
  const content = await fsAdapter.readFile(args.path);
154
+ onDependencyLoaded?.(args.path, content);
111
155
  return {
112
156
  contents: content,
113
157
  loader: getEsbuildLoader(args.path),
@@ -131,9 +175,6 @@ function createFsAdapterPlugin(fsAdapter) {
131
175
  * Import and transpile a module for discovery
132
176
  */
133
177
  export async function importModule(file, context) {
134
- const cached = transpileCache.get(file);
135
- if (cached)
136
- return cached;
137
178
  // Ensure veryfront modules are available as globals for compiled binaries
138
179
  await ensureVeryfrontGlobals();
139
180
  const filePath = file.replace("file://", "");
@@ -149,6 +190,20 @@ export async function importModule(file, context) {
149
190
  cause: error,
150
191
  });
151
192
  }
193
+ // The cache key must include the source content: a shared hosted runtime
194
+ // process serves many projects and releases, and the same relative path
195
+ // (e.g. "tools/foo.ts") recurs across them. A path-only key keeps serving
196
+ // the stale module after a deploy and can hand one project's module to
197
+ // another project's discovery. The entry hash alone is still not enough —
198
+ // bundled relative imports are inlined into the module — so cached entries
199
+ // are only served after their recorded dependency contents re-verify.
200
+ const cacheKey = `${file} ${await hashSource(source)}`;
201
+ const cachedEntries = transpileCache.get(cacheKey);
202
+ if (cachedEntries) {
203
+ const cached = await findCachedModuleWithFreshDeps(cachedEntries, context);
204
+ if (cached)
205
+ return cached;
206
+ }
152
207
  const loader = getEsbuildLoader(filePath);
153
208
  await ensureDefaultBundlerContracts();
154
209
  const { build } = await import("../extensions/bundler/index.js");
@@ -160,8 +215,16 @@ export async function importModule(file, context) {
160
215
  const relativeImports = isDeno && !isDenoCompiled && !hasFsAdapter
161
216
  ? [...source.matchAll(/from\s+["'](\.\.[^"']+)["']/g)].map((m) => m[1]).filter(Boolean)
162
217
  : [];
163
- // Use fsAdapter plugin whenever a VFS adapter is available (regardless of runtime)
164
- const plugins = hasFsAdapter ? [createFsAdapterPlugin(context.fsAdapter)] : [];
218
+ // Use fsAdapter plugin whenever a VFS adapter is available (regardless of
219
+ // runtime), recording every bundled dependency for cache re-validation.
220
+ const bundledDeps = [];
221
+ const plugins = hasFsAdapter
222
+ ? [
223
+ createFsAdapterPlugin(context.fsAdapter, (path, content) => {
224
+ bundledDeps.push({ path, content });
225
+ }),
226
+ ]
227
+ : [];
165
228
  const result = await build({
166
229
  bundle: true,
167
230
  write: false,
@@ -218,7 +281,10 @@ export async function importModule(file, context) {
218
281
  const moduleUrl = pathHelper.toFileUrl(tempFile);
219
282
  moduleUrl.searchParams.set("v", String(Date.now()));
220
283
  const module = await import(moduleUrl.href);
221
- transpileCache.set(file, module);
284
+ const deps = await Promise.all(bundledDeps.map(async ({ path, content }) => ({ path, hash: await hashSource(content) })));
285
+ const entries = transpileCache.get(cacheKey) ?? [];
286
+ entries.push({ deps, module });
287
+ transpileCache.set(cacheKey, entries);
222
288
  return module;
223
289
  }
224
290
  finally {
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.1002";
2
+ export declare const VERSION = "0.1.1004";
3
3
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
3
  /** Shared version value. */
4
- export const VERSION = "0.1.1002";
4
+ export const VERSION = "0.1.1004";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.1002",
3
+ "version": "0.1.1004",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",