@mcarvin/smart-diff 1.1.0 → 2.0.0
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/README.md +101 -21
- package/dist/index.cjs +255 -109
- package/dist/index.cjs.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.cjs.map +1 -1
- package/dist/index.min.mjs +1 -1
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.min.umd.js +1 -1
- package/dist/index.min.umd.js.map +1 -1
- package/dist/index.mjs +252 -106
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +258 -113
- package/dist/index.umd.js.map +1 -1
- package/dist/typings/ai/aiTypes.d.ts +5 -3
- package/dist/typings/ai/llmProviders.d.ts +12 -0
- package/dist/typings/index.d.ts +7 -5
- package/package.json +33 -7
- package/dist/typings/ai/openAIConfig.d.ts +0 -21
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateText } from 'ai';
|
|
1
2
|
import { resolve, relative } from 'node:path';
|
|
2
3
|
import { simpleGit } from 'simple-git';
|
|
3
4
|
|
|
@@ -33,9 +34,55 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
33
34
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
34
35
|
};
|
|
35
36
|
|
|
37
|
+
const DEFAULT_LLM_MAX_DIFF_CHARS = 120000;
|
|
38
|
+
const DEFAULT_GIT_DIFF_SYSTEM_PROMPT = `You are a senior software engineer helping developers understand code and configuration changes from the git context they supplied.
|
|
39
|
+
You receive: commit subject lines (when available), changed file paths, and unified git patch(es)—either one range diff or concatenated per-commit patches, depending on how the diff was produced. Patches may be truncated mid-section with an explicit marker—do not infer changes beyond visible lines.
|
|
40
|
+
Explain what changed in terms of behavior, APIs, data, configuration, security, and operational risk. Tie claims to the patch when possible.
|
|
41
|
+
Produce a concise, developer-focused summary in Markdown.
|
|
42
|
+
Use sections that fit the change (for example: Highlights, Breaking or risky changes, API / contract changes, Data & schema, Configuration & infra, Security & auth, Tests & quality). Omit empty sections.
|
|
43
|
+
Group related changes; do not list every individual file. When multiple commits appear in the context, briefly separate notable themes by commit when helpful.
|
|
44
|
+
If the user message includes a Team line, use that exact team name in the summary title (for example: "## <Team> – Change summary" or similar).`;
|
|
45
|
+
const LLM_GATEWAY_REQUIRED_MESSAGE = "No LLM provider configured. Set LLM_PROVIDER (openai | openai-compatible | anthropic | google | bedrock | mistral | cohere | groq | xai | deepseek), " +
|
|
46
|
+
"or a provider API key (OPENAI_API_KEY, LLM_API_KEY, ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, MISTRAL_API_KEY, COHERE_API_KEY, GROQ_API_KEY, XAI_API_KEY, DEEPSEEK_API_KEY), " +
|
|
47
|
+
"or LLM_BASE_URL / OPENAI_BASE_URL for an OpenAI-compatible gateway, " +
|
|
48
|
+
"or JSON in OPENAI_DEFAULT_HEADERS / LLM_DEFAULT_HEADERS. " +
|
|
49
|
+
"Alternatively pass llmModelProvider or openAiClientProvider to generateSummary or summarizeGitDiff.";
|
|
50
|
+
|
|
51
|
+
const DEFAULT_MODEL_BY_PROVIDER = {
|
|
52
|
+
openai: "gpt-4o-mini",
|
|
53
|
+
"openai-compatible": "gpt-4o-mini",
|
|
54
|
+
anthropic: "claude-3-5-haiku-latest",
|
|
55
|
+
google: "gemini-2.0-flash",
|
|
56
|
+
bedrock: "anthropic.claude-3-5-haiku-20241022-v1:0",
|
|
57
|
+
mistral: "mistral-small-latest",
|
|
58
|
+
cohere: "command-r-08-2024",
|
|
59
|
+
groq: "llama-3.1-8b-instant",
|
|
60
|
+
xai: "grok-2-latest",
|
|
61
|
+
deepseek: "deepseek-chat",
|
|
62
|
+
};
|
|
63
|
+
const VALID_PROVIDERS = new Set([
|
|
64
|
+
"openai",
|
|
65
|
+
"openai-compatible",
|
|
66
|
+
"anthropic",
|
|
67
|
+
"google",
|
|
68
|
+
"bedrock",
|
|
69
|
+
"mistral",
|
|
70
|
+
"cohere",
|
|
71
|
+
"groq",
|
|
72
|
+
"xai",
|
|
73
|
+
"deepseek",
|
|
74
|
+
]);
|
|
75
|
+
function readEnv(name) {
|
|
76
|
+
var _a;
|
|
77
|
+
const value = (_a = process.env[name]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
78
|
+
return value && value.length > 0 ? value : undefined;
|
|
79
|
+
}
|
|
80
|
+
function isValidProviderId(value) {
|
|
81
|
+
return VALID_PROVIDERS.has(value);
|
|
82
|
+
}
|
|
36
83
|
function resolveLlmBaseUrl() {
|
|
37
|
-
var _a
|
|
38
|
-
return (
|
|
84
|
+
var _a;
|
|
85
|
+
return (_a = readEnv("LLM_BASE_URL")) !== null && _a !== void 0 ? _a : readEnv("OPENAI_BASE_URL");
|
|
39
86
|
}
|
|
40
87
|
function parseHeaderJsonObject(raw) {
|
|
41
88
|
const trimmed = raw === null || raw === void 0 ? void 0 : raw.trim();
|
|
@@ -66,87 +113,187 @@ function parseLlmDefaultHeadersFromEnv() {
|
|
|
66
113
|
const merged = Object.assign(Object.assign({}, base), override);
|
|
67
114
|
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
68
115
|
}
|
|
69
|
-
function
|
|
70
|
-
return Object.keys(headers).find((k) => k.toLowerCase() === "authorization");
|
|
71
|
-
}
|
|
72
|
-
function stripBearerPrefix(value) {
|
|
116
|
+
function resolveOpenAiApiKey() {
|
|
73
117
|
var _a;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
return
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
return
|
|
102
|
-
if (
|
|
103
|
-
return
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return
|
|
108
|
-
}
|
|
109
|
-
function
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
return (_a = readEnv("LLM_API_KEY")) !== null && _a !== void 0 ? _a : readEnv("OPENAI_API_KEY");
|
|
119
|
+
}
|
|
120
|
+
function detectLlmProvider() {
|
|
121
|
+
var _a, _b;
|
|
122
|
+
const explicit = (_a = readEnv("LLM_PROVIDER")) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
123
|
+
if (explicit && isValidProviderId(explicit)) {
|
|
124
|
+
return explicit;
|
|
125
|
+
}
|
|
126
|
+
if (resolveLlmBaseUrl()) {
|
|
127
|
+
return "openai-compatible";
|
|
128
|
+
}
|
|
129
|
+
if (resolveOpenAiApiKey()) {
|
|
130
|
+
return "openai";
|
|
131
|
+
}
|
|
132
|
+
if (readEnv("ANTHROPIC_API_KEY"))
|
|
133
|
+
return "anthropic";
|
|
134
|
+
if ((_b = readEnv("GOOGLE_GENERATIVE_AI_API_KEY")) !== null && _b !== void 0 ? _b : readEnv("GOOGLE_API_KEY"))
|
|
135
|
+
return "google";
|
|
136
|
+
if (readEnv("MISTRAL_API_KEY"))
|
|
137
|
+
return "mistral";
|
|
138
|
+
if (readEnv("COHERE_API_KEY"))
|
|
139
|
+
return "cohere";
|
|
140
|
+
if (readEnv("GROQ_API_KEY"))
|
|
141
|
+
return "groq";
|
|
142
|
+
if (readEnv("XAI_API_KEY"))
|
|
143
|
+
return "xai";
|
|
144
|
+
if (readEnv("DEEPSEEK_API_KEY"))
|
|
145
|
+
return "deepseek";
|
|
146
|
+
if (parseLlmDefaultHeadersFromEnv())
|
|
147
|
+
return "openai";
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
function isLlmProviderConfigured() {
|
|
151
|
+
return detectLlmProvider() !== undefined;
|
|
152
|
+
}
|
|
153
|
+
function defaultModelForProvider(provider) {
|
|
154
|
+
return DEFAULT_MODEL_BY_PROVIDER[provider];
|
|
155
|
+
}
|
|
156
|
+
function createOpenAiModel(modelId) {
|
|
157
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
const { createOpenAI } = yield import('@ai-sdk/openai');
|
|
159
|
+
const apiKey = resolveOpenAiApiKey();
|
|
160
|
+
const headers = parseLlmDefaultHeadersFromEnv();
|
|
161
|
+
const provider = createOpenAI(Object.assign(Object.assign({}, (apiKey ? { apiKey } : {})), (headers ? { headers } : {})));
|
|
162
|
+
return provider(modelId);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function createOpenAiCompatibleModel(modelId) {
|
|
166
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
167
|
+
var _a;
|
|
168
|
+
const { createOpenAICompatible } = yield import('@ai-sdk/openai-compatible');
|
|
169
|
+
const baseURL = resolveLlmBaseUrl();
|
|
170
|
+
if (!baseURL) {
|
|
171
|
+
throw new Error("openai-compatible provider requires LLM_BASE_URL or OPENAI_BASE_URL to be set.");
|
|
120
172
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
defaultHeaders =
|
|
128
|
-
Object.keys(mergedHeaders).length > 0 ? mergedHeaders : undefined;
|
|
129
|
-
}
|
|
130
|
-
return Object.assign(Object.assign({ apiKey: apiKey.length > 0 ? apiKey : "unused" }, (baseURL ? { baseURL } : {})), (defaultHeaders ? { defaultHeaders } : {}));
|
|
173
|
+
const apiKey = resolveOpenAiApiKey();
|
|
174
|
+
const headers = parseLlmDefaultHeadersFromEnv();
|
|
175
|
+
const provider = createOpenAICompatible(Object.assign(Object.assign({ name: (_a = readEnv("LLM_PROVIDER_NAME")) !== null && _a !== void 0 ? _a : "openai-compatible", baseURL }, (apiKey ? { apiKey } : {})), (headers ? { headers } : {})));
|
|
176
|
+
return provider(modelId);
|
|
177
|
+
});
|
|
131
178
|
}
|
|
132
|
-
function
|
|
179
|
+
function wrapMissingPeer(failure) {
|
|
180
|
+
const err = new Error(`Failed to load optional provider package "${failure.pkg}" for LLM_PROVIDER="${failure.provider}". ` +
|
|
181
|
+
`Install it with \`npm install ${failure.pkg}\`.`);
|
|
182
|
+
err.cause = failure.cause;
|
|
183
|
+
return err;
|
|
184
|
+
}
|
|
185
|
+
function importOptional(provider, pkg, loader) {
|
|
133
186
|
return __awaiter(this, void 0, void 0, function* () {
|
|
134
|
-
|
|
135
|
-
|
|
187
|
+
try {
|
|
188
|
+
return yield loader();
|
|
189
|
+
}
|
|
190
|
+
catch (cause) {
|
|
191
|
+
throw wrapMissingPeer({ provider, pkg, cause });
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function createAnthropicModel(modelId) {
|
|
196
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
197
|
+
const mod = yield importOptional("anthropic", "@ai-sdk/anthropic", () => import('@ai-sdk/anthropic'));
|
|
198
|
+
const apiKey = readEnv("ANTHROPIC_API_KEY");
|
|
199
|
+
const provider = mod.createAnthropic(apiKey ? { apiKey } : undefined);
|
|
200
|
+
return provider(modelId);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function createGoogleModel(modelId) {
|
|
204
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
205
|
+
var _a;
|
|
206
|
+
const mod = yield importOptional("google", "@ai-sdk/google", () => import('@ai-sdk/google'));
|
|
207
|
+
const apiKey = (_a = readEnv("GOOGLE_GENERATIVE_AI_API_KEY")) !== null && _a !== void 0 ? _a : readEnv("GOOGLE_API_KEY");
|
|
208
|
+
const provider = mod.createGoogleGenerativeAI(apiKey ? { apiKey } : undefined);
|
|
209
|
+
return provider(modelId);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function createBedrockModel(modelId) {
|
|
213
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
214
|
+
const mod = yield importOptional("bedrock", "@ai-sdk/amazon-bedrock", () => import('@ai-sdk/amazon-bedrock'));
|
|
215
|
+
const provider = mod.createAmazonBedrock();
|
|
216
|
+
return provider(modelId);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
function createMistralModel(modelId) {
|
|
220
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
221
|
+
const mod = yield importOptional("mistral", "@ai-sdk/mistral", () => import('@ai-sdk/mistral'));
|
|
222
|
+
const apiKey = readEnv("MISTRAL_API_KEY");
|
|
223
|
+
const provider = mod.createMistral(apiKey ? { apiKey } : undefined);
|
|
224
|
+
return provider(modelId);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
function createCohereModel(modelId) {
|
|
228
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
229
|
+
const mod = yield importOptional("cohere", "@ai-sdk/cohere", () => import('@ai-sdk/cohere'));
|
|
230
|
+
const apiKey = readEnv("COHERE_API_KEY");
|
|
231
|
+
const provider = mod.createCohere(apiKey ? { apiKey } : undefined);
|
|
232
|
+
return provider(modelId);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function createGroqModel(modelId) {
|
|
236
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
237
|
+
const mod = yield importOptional("groq", "@ai-sdk/groq", () => import('@ai-sdk/groq'));
|
|
238
|
+
const apiKey = readEnv("GROQ_API_KEY");
|
|
239
|
+
const provider = mod.createGroq(apiKey ? { apiKey } : undefined);
|
|
240
|
+
return provider(modelId);
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
function createXaiModel(modelId) {
|
|
244
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
245
|
+
const mod = yield importOptional("xai", "@ai-sdk/xai", () => import('@ai-sdk/xai'));
|
|
246
|
+
const apiKey = readEnv("XAI_API_KEY");
|
|
247
|
+
const provider = mod.createXai(apiKey ? { apiKey } : undefined);
|
|
248
|
+
return provider(modelId);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
function createDeepseekModel(modelId) {
|
|
252
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
253
|
+
const mod = yield importOptional("deepseek", "@ai-sdk/deepseek", () => import('@ai-sdk/deepseek'));
|
|
254
|
+
const apiKey = readEnv("DEEPSEEK_API_KEY");
|
|
255
|
+
const provider = mod.createDeepSeek(apiKey ? { apiKey } : undefined);
|
|
256
|
+
return provider(modelId);
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
function resolveLanguageModel() {
|
|
260
|
+
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
261
|
+
var _a, _b, _c;
|
|
262
|
+
const provider = (_a = options.provider) !== null && _a !== void 0 ? _a : detectLlmProvider();
|
|
263
|
+
if (!provider) {
|
|
264
|
+
throw new Error("No LLM provider could be resolved. Set LLM_PROVIDER or a provider API key " +
|
|
265
|
+
"(OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, MISTRAL_API_KEY, " +
|
|
266
|
+
"COHERE_API_KEY, GROQ_API_KEY, XAI_API_KEY, DEEPSEEK_API_KEY), or LLM_BASE_URL for an OpenAI-compatible gateway.");
|
|
267
|
+
}
|
|
268
|
+
const modelId = (_c = (_b = options.model) !== null && _b !== void 0 ? _b : readEnv("LLM_MODEL")) !== null && _c !== void 0 ? _c : defaultModelForProvider(provider);
|
|
269
|
+
switch (provider) {
|
|
270
|
+
case "openai":
|
|
271
|
+
return createOpenAiModel(modelId);
|
|
272
|
+
case "openai-compatible":
|
|
273
|
+
return createOpenAiCompatibleModel(modelId);
|
|
274
|
+
case "anthropic":
|
|
275
|
+
return createAnthropicModel(modelId);
|
|
276
|
+
case "google":
|
|
277
|
+
return createGoogleModel(modelId);
|
|
278
|
+
case "bedrock":
|
|
279
|
+
return createBedrockModel(modelId);
|
|
280
|
+
case "mistral":
|
|
281
|
+
return createMistralModel(modelId);
|
|
282
|
+
case "cohere":
|
|
283
|
+
return createCohereModel(modelId);
|
|
284
|
+
case "groq":
|
|
285
|
+
return createGroqModel(modelId);
|
|
286
|
+
case "xai":
|
|
287
|
+
return createXaiModel(modelId);
|
|
288
|
+
case "deepseek":
|
|
289
|
+
return createDeepseekModel(modelId);
|
|
290
|
+
default: {
|
|
291
|
+
const _exhaustive = provider;
|
|
292
|
+
throw new Error(`Unhandled LLM provider: ${String(_exhaustive)}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
136
295
|
});
|
|
137
296
|
}
|
|
138
|
-
|
|
139
|
-
const DEFAULT_LLM_MAX_DIFF_CHARS = 120000;
|
|
140
|
-
const DEFAULT_GIT_DIFF_SYSTEM_PROMPT = `You are a senior software engineer helping developers understand code and configuration changes from the git context they supplied.
|
|
141
|
-
You receive: commit subject lines (when available), changed file paths, and unified git patch(es)—either one range diff or concatenated per-commit patches, depending on how the diff was produced. Patches may be truncated mid-section with an explicit marker—do not infer changes beyond visible lines.
|
|
142
|
-
Explain what changed in terms of behavior, APIs, data, configuration, security, and operational risk. Tie claims to the patch when possible.
|
|
143
|
-
Produce a concise, developer-focused summary in Markdown.
|
|
144
|
-
Use sections that fit the change (for example: Highlights, Breaking or risky changes, API / contract changes, Data & schema, Configuration & infra, Security & auth, Tests & quality). Omit empty sections.
|
|
145
|
-
Group related changes; do not list every individual file. When multiple commits appear in the context, briefly separate notable themes by commit when helpful.
|
|
146
|
-
If the user message includes a Team line, use that exact team name in the summary title (for example: "## <Team> – Change summary" or similar).`;
|
|
147
|
-
const LLM_GATEWAY_REQUIRED_MESSAGE = "No LLM gateway configured. Set OPENAI_API_KEY or LLM_API_KEY, and/or LLM_BASE_URL or OPENAI_BASE_URL, " +
|
|
148
|
-
"and/or JSON in OPENAI_DEFAULT_HEADERS or LLM_DEFAULT_HEADERS. " +
|
|
149
|
-
"Alternatively pass openAiClientProvider to generateSummary or summarizeGitDiff.";
|
|
150
297
|
|
|
151
298
|
function resolveLlmMaxDiffChars(cliOverride) {
|
|
152
299
|
var _a;
|
|
@@ -174,18 +321,26 @@ function truncateUnifiedDiffForLlm(diffText, maxChars) {
|
|
|
174
321
|
function markdownDiffTruncationNotice(originalChars, maxChars) {
|
|
175
322
|
return `> **Truncated diff:** The unified diff was ${originalChars} characters; only the first ${maxChars} were sent to the model. The summary may not reflect the full change set. Narrow the ref range, adjust path filters, or raise \`maxDiffChars\` / \`LLM_MAX_DIFF_CHARS\`—often together with switching to a model whose context window can fit a larger prompt.\n\n`;
|
|
176
323
|
}
|
|
324
|
+
function resolveMaxOutputTokens() {
|
|
325
|
+
var _a;
|
|
326
|
+
const raw = (_a = process.env.LLM_MAX_TOKENS) !== null && _a !== void 0 ? _a : process.env.OPENAI_MAX_TOKENS;
|
|
327
|
+
const parsed = raw !== undefined ? Number.parseInt(raw, 10) : 4000;
|
|
328
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 4000;
|
|
329
|
+
}
|
|
177
330
|
function generateSummary(input) {
|
|
178
331
|
return __awaiter(this, void 0, void 0, function* () {
|
|
179
|
-
var _a
|
|
180
|
-
const { diffText, fileNames, commits, flags,
|
|
181
|
-
if (!
|
|
332
|
+
var _a;
|
|
333
|
+
const { diffText, fileNames, commits, flags, llmModelProvider, diffSummary, } = input;
|
|
334
|
+
if (!llmModelProvider && !isLlmProviderConfigured()) {
|
|
182
335
|
throw new Error(LLM_GATEWAY_REQUIRED_MESSAGE);
|
|
183
336
|
}
|
|
184
337
|
const maxDiffChars = resolveLlmMaxDiffChars(flags.maxDiffChars);
|
|
185
338
|
const diffTruncated = diffText.length > maxDiffChars;
|
|
186
339
|
const diffForLlm = truncateUnifiedDiffForLlm(diffText, maxDiffChars);
|
|
187
|
-
const userContent =
|
|
188
|
-
const
|
|
340
|
+
const userContent = buildUserContent(flags, commits, fileNames, diffForLlm, diffSummary);
|
|
341
|
+
const systemPrompt = (_a = flags.systemPrompt) !== null && _a !== void 0 ? _a : DEFAULT_GIT_DIFF_SYSTEM_PROMPT;
|
|
342
|
+
const maxOutputTokens = resolveMaxOutputTokens();
|
|
343
|
+
const summary = yield callLlm(userContent, systemPrompt, maxOutputTokens, llmModelProvider, flags);
|
|
189
344
|
if (!diffTruncated) {
|
|
190
345
|
return summary;
|
|
191
346
|
}
|
|
@@ -212,7 +367,7 @@ function formatRegexFilterLines(flags) {
|
|
|
212
367
|
return (`${incLine}${excLine}` +
|
|
213
368
|
"Git context shape: concatenated per-commit unified patches for commits that pass the message filters.\n");
|
|
214
369
|
}
|
|
215
|
-
function
|
|
370
|
+
function buildUserContent(flags, commits, fileNames, diffText, diffSummary) {
|
|
216
371
|
var _a, _b;
|
|
217
372
|
const from = flags.from;
|
|
218
373
|
const to = (_a = flags.to) !== null && _a !== void 0 ? _a : "HEAD";
|
|
@@ -242,31 +397,21 @@ function buildOpenAiUserContent(flags, commits, fileNames, diffText, diffSummary
|
|
|
242
397
|
"=== Git context (unified diff(s); patches may be truncated with an explicit marker) ===\n" +
|
|
243
398
|
diffText);
|
|
244
399
|
}
|
|
245
|
-
function
|
|
400
|
+
function callLlm(userContent, systemPrompt, maxOutputTokens, llmModelProvider, flags) {
|
|
246
401
|
return __awaiter(this, void 0, void 0, function* () {
|
|
247
|
-
var _a, _b
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
const response = yield client.chat.completions.create({
|
|
402
|
+
var _a, _b;
|
|
403
|
+
const model = llmModelProvider
|
|
404
|
+
? yield llmModelProvider()
|
|
405
|
+
: yield resolveLanguageModel(Object.assign(Object.assign({}, (flags.provider ? { provider: flags.provider } : {})), (flags.model ? { model: flags.model } : {})));
|
|
406
|
+
const result = yield generateText({
|
|
253
407
|
model,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
role: "system",
|
|
257
|
-
content: systemPrompt,
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
role: "user",
|
|
261
|
-
content: userContent,
|
|
262
|
-
},
|
|
263
|
-
],
|
|
408
|
+
system: systemPrompt,
|
|
409
|
+
prompt: userContent,
|
|
264
410
|
temperature: 0.2,
|
|
265
|
-
|
|
411
|
+
maxOutputTokens,
|
|
266
412
|
});
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
return text.length > 0 ? text : "No summary generated by OpenAI.";
|
|
413
|
+
const text = (_b = (_a = result.text) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "";
|
|
414
|
+
return text.length > 0 ? text : "No summary generated by the model.";
|
|
270
415
|
});
|
|
271
416
|
}
|
|
272
417
|
|
|
@@ -710,6 +855,7 @@ function summarizeGitDiff(options) {
|
|
|
710
855
|
to,
|
|
711
856
|
team: options.teamName,
|
|
712
857
|
model: options.model,
|
|
858
|
+
provider: options.provider,
|
|
713
859
|
maxDiffChars: options.maxDiffChars,
|
|
714
860
|
systemPrompt: options.systemPrompt,
|
|
715
861
|
commitMessageIncludeRegexes: options.commitMessageIncludeRegexes,
|
|
@@ -720,11 +866,11 @@ function summarizeGitDiff(options) {
|
|
|
720
866
|
fileNames,
|
|
721
867
|
commits: filteredCommits,
|
|
722
868
|
flags: summarizeFlags,
|
|
723
|
-
|
|
869
|
+
llmModelProvider: options.llmModelProvider,
|
|
724
870
|
diffSummary,
|
|
725
871
|
});
|
|
726
872
|
});
|
|
727
873
|
}
|
|
728
874
|
|
|
729
|
-
export { DEFAULT_GIT_DIFF_SYSTEM_PROMPT, LLM_GATEWAY_REQUIRED_MESSAGE, buildDiffPathspecs, createGitClient,
|
|
875
|
+
export { DEFAULT_GIT_DIFF_SYSTEM_PROMPT, LLM_GATEWAY_REQUIRED_MESSAGE, buildDiffPathspecs, createGitClient, defaultModelForProvider, detectLlmProvider, filterCommitsByMessageRegexes, generateSummary, getChangedFiles, getCommits, getDiff, getDiffSummary, getRepoRoot, isLlmProviderConfigured, parseLlmDefaultHeadersFromEnv, resolveLanguageModel, resolveLlmBaseUrl, resolveLlmMaxDiffChars, summarizeGitDiff, truncateUnifiedDiffForLlm };
|
|
730
876
|
//# sourceMappingURL=index.mjs.map
|