commit-whisper 1.1.4 → 1.1.5

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.
Files changed (2) hide show
  1. package/dist/index.js +36 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3920,7 +3920,21 @@ function resolveModel(config) {
3920
3920
  }
3921
3921
  case "openai-compatible": {
3922
3922
  const baseURL = requireBaseUrl(config);
3923
- return createOpenAICompatible({ name: "openai-compatible", baseURL, apiKey: config.aiKey?.reveal() })(model);
3923
+ return createOpenAICompatible({
3924
+ name: "openai-compatible",
3925
+ baseURL,
3926
+ apiKey: config.aiKey?.reveal(),
3927
+ // Send the bound schema as a real `json_schema` response format. Without
3928
+ // this the SDK silently DROPS the schema (falling back to `json_object`
3929
+ // mode) and the model's unguided output fails `generateObject`'s
3930
+ // validation — exactly the "narrative unavailable" degrade we hit.
3931
+ supportsStructuredOutputs: true,
3932
+ // …but emit it NON-strict: our narration schemas use `min(1)` (⇒
3933
+ // `minLength`/`minItems`), keywords OpenAI's STRICT structured outputs
3934
+ // reject with a 400. Non-strict still hands the model the schema while
3935
+ // tolerating those keywords; `generateObject` re-validates against Zod.
3936
+ transformRequestBody: relaxStructuredOutputsStrictness
3937
+ })(model);
3924
3938
  }
3925
3939
  case "ollama": {
3926
3940
  let base = cleanBaseUrl2(config.llmBaseUrl) ?? OLLAMA_DEFAULT_BASE_URL2;
@@ -3969,6 +3983,26 @@ function cleanBaseUrl2(baseUrl) {
3969
3983
  function assertNeverProvider(provider) {
3970
3984
  throw new NarrationError(`Unsupported provider: ${String(provider)}`);
3971
3985
  }
3986
+ function isJsonSchemaResponseFormat(value) {
3987
+ if (typeof value !== "object" || value === null) {
3988
+ return false;
3989
+ }
3990
+ const candidate = value;
3991
+ return candidate.type === "json_schema" && typeof candidate.json_schema === "object" && candidate.json_schema !== null;
3992
+ }
3993
+ function relaxStructuredOutputsStrictness(body) {
3994
+ const responseFormat = body.response_format;
3995
+ if (!isJsonSchemaResponseFormat(responseFormat)) {
3996
+ return body;
3997
+ }
3998
+ return {
3999
+ ...body,
4000
+ response_format: {
4001
+ ...responseFormat,
4002
+ json_schema: { ...responseFormat.json_schema, strict: false }
4003
+ }
4004
+ };
4005
+ }
3972
4006
 
3973
4007
  // src/narrate/narrate.ts
3974
4008
  function createNarrate(deps = {}) {
@@ -6516,7 +6550,7 @@ function localName(target) {
6516
6550
  }
6517
6551
 
6518
6552
  // src/cli/version.ts
6519
- var VERSION = "1.1.4";
6553
+ var VERSION = "1.1.5";
6520
6554
 
6521
6555
  // src/cli/write-file.ts
6522
6556
  import { writeFile as fsWriteFile } from "fs/promises";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commit-whisper",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "Deterministic git history analysis with a grounded, BYOK AI narrative — terminal-native CLI.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",