maiass 5.14.0 → 5.14.2

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/lib/commit.js CHANGED
@@ -16,6 +16,45 @@ import { logCommit } from './devlog.js';
16
16
  import colors from './colors.js';
17
17
  import chalk from 'chalk';
18
18
 
19
+ /**
20
+ * Pick the AI model used for commit message generation.
21
+ *
22
+ * Resolution order:
23
+ * 1. MAIASS_AI_COMMIT_MODEL — explicit per-commit override. Wins absolutely.
24
+ * 2. MAIASS_AI_MODEL — legacy global override. Preserves prior behaviour for
25
+ * users who configured it explicitly.
26
+ * 3. Auto-pick by diff size (post-truncation char count of the staged diff
27
+ * that will actually be sent to the model):
28
+ * < 30000 chars -> gpt-4o-mini (tier 1)
29
+ * 30000..100000 -> gpt-4-turbo (tier 2)
30
+ * > 100000 -> gpt-4o (tier 3)
31
+ *
32
+ * In practice MAIASS_AI_MAX_CHARACTERS defaults to 8000, so tier 1 is the
33
+ * common case. Tiers 2 and 3 only fire when a user has raised that cap. The
34
+ * ladder is forward-compatible with future increases.
35
+ *
36
+ * Returns { model, tier, source } where source is 'override' | 'legacy' |
37
+ * 'auto', and tier is 1/2/3 (only meaningful when source === 'auto').
38
+ */
39
+ export function pickCommitModel(diffLength, env = process.env) {
40
+ const override = env.MAIASS_AI_COMMIT_MODEL;
41
+ if (override && override.trim()) {
42
+ return { model: override.trim(), tier: null, source: 'override' };
43
+ }
44
+ const legacy = env.MAIASS_AI_MODEL;
45
+ if (legacy && legacy.trim()) {
46
+ return { model: legacy.trim(), tier: null, source: 'legacy' };
47
+ }
48
+ const len = typeof diffLength === 'number' && diffLength >= 0 ? diffLength : 0;
49
+ if (len < 30000) {
50
+ return { model: 'gpt-4o-mini', tier: 1, source: 'auto' };
51
+ }
52
+ if (len <= 100000) {
53
+ return { model: 'gpt-4-turbo', tier: 2, source: 'auto' };
54
+ }
55
+ return { model: 'gpt-4o', tier: 3, source: 'auto' };
56
+ }
57
+
19
58
  /**
20
59
  * Simple spinner for AI API calls
21
60
  */
@@ -291,7 +330,8 @@ async function getAICommitSuggestion(gitInfo) {
291
330
  const aiHost = process.env.MAIASS_AI_HOST || 'https://pound.maiass.net';
292
331
  const aiPath = process.env.MAIASS_AI_PATH || '/proxy';
293
332
  const aiEndpoint = aiHost + aiPath;
294
- const aiModel = process.env.MAIASS_AI_MODEL || 'gpt-3.5-turbo';
333
+ // aiModel is resolved AFTER the diff is collected and truncated — the
334
+ // auto-pick layer needs the final diff size. See pickCommitModel() below.
295
335
  const aiTemperature = parseFloat(process.env.MAIASS_AI_TEMPERATURE || '0.7');
296
336
  const commitMessageStyle = process.env.MAIASS_AI_COMMIT_MESSAGE_STYLE || 'bullet';
297
337
  const maxCharacters = parseInt(process.env.MAIASS_AI_MAX_CHARACTERS || '8000');
@@ -372,7 +412,29 @@ async function getAICommitSuggestion(gitInfo) {
372
412
  log.info(SYMBOLS.INFO, `Git diff truncated to ${maxCharacters} characters`);
373
413
  }
374
414
 
415
+ // Pick the AI model AFTER truncation — the auto-pick layer reads the final
416
+ // diff size that will actually be sent to the model. MAIASS_AI_COMMIT_MODEL
417
+ // overrides everything; MAIASS_AI_MODEL is the legacy fallback; otherwise
418
+ // we ladder based on diff length.
419
+ const modelPick = pickCommitModel(gitDiff.length);
420
+ const aiModel = modelPick.model;
421
+
375
422
  if (debugMode) {
423
+ let pickSummary;
424
+ if (modelPick.source === 'override') {
425
+ pickSummary = `[MAIASS DEBUG] AI commit model: ${aiModel} (override via MAIASS_AI_COMMIT_MODEL)`;
426
+ } else if (modelPick.source === 'legacy') {
427
+ pickSummary = `[MAIASS DEBUG] AI commit model: ${aiModel} (legacy MAIASS_AI_MODEL)`;
428
+ } else {
429
+ const ranges = {
430
+ 1: '< 30000',
431
+ 2: '30000-100000',
432
+ 3: '> 100000'
433
+ };
434
+ pickSummary = `[MAIASS DEBUG] AI commit model: ${aiModel} (tier ${modelPick.tier}, diff ${gitDiff.length} chars, threshold ${ranges[modelPick.tier]})`;
435
+ }
436
+ log.debug(SYMBOLS.INFO, pickSummary);
437
+
376
438
  log.debug(SYMBOLS.INFO, '[MAIASS DEBUG] --- AI Commit Suggestion Context ---');
377
439
  log.debug(SYMBOLS.INFO, `[MAIASS DEBUG] Model: ${aiModel}`);
378
440
  log.debug(SYMBOLS.INFO, `[MAIASS DEBUG] Temperature: ${aiTemperature}`);
@@ -81,7 +81,7 @@ function displayConfig(config, options = {}) {
81
81
  // Group by category for better display
82
82
  const categories = {
83
83
  'Core System': ['MAIASS_DEBUG', 'MAIASS_VERBOSITY', 'MAIASS_LOGGING', 'MAIASS_BRAND'],
84
- 'AI Integration': ['MAIASS_AI_MODE', 'MAIASS_AI_TOKEN', 'MAIASS_AI_MODEL', 'MAIASS_AI_TEMPERATURE', 'MAIASS_AI_HOST', 'MAIASS_AI_MAX_CHARACTERS', 'MAIASS_AI_COMMIT_MESSAGE_STYLE'],
84
+ 'AI Integration': ['MAIASS_AI_MODE', 'MAIASS_AI_TOKEN', 'MAIASS_AI_MODEL', 'MAIASS_AI_COMMIT_MODEL', 'MAIASS_AI_TEMPERATURE', 'MAIASS_AI_HOST', 'MAIASS_AI_MAX_CHARACTERS', 'MAIASS_AI_COMMIT_MESSAGE_STYLE'],
85
85
  'Git Branches': ['MAIASS_DEVELOPBRANCH', 'MAIASS_STAGINGBRANCH', 'MAIASS_MAINBRANCH'],
86
86
  'Repository Settings': ['MAIASS_REPO_TYPE', 'MAIASS_GITHUB_OWNER', 'MAIASS_GITHUB_REPO', 'MAIASS_BITBUCKET_WORKSPACE', 'MAIASS_BITBUCKET_REPO_SLUG'],
87
87
  'Pull Requests': ['MAIASS_DEVELOP_PULLREQUESTS'],
@@ -112,7 +112,7 @@ export function writeConfig(configPath, config, options = {}) {
112
112
  // Group variables by category for better organization
113
113
  const categories = {
114
114
  'Core': ['MAIASS_DEBUG', 'MAIASS_VERBOSITY', 'MAIASS_LOGGING', 'MAIASS_BRAND'],
115
- 'AI': ['MAIASS_AI_MODE', 'MAIASS_AI_TOKEN', 'MAIASS_AI_MODEL', 'MAIASS_AI_TEMPERATURE', 'MAIASS_AI_ENDPOINT', 'MAIASS_AI_MAX_CHARACTERS', 'MAIASS_AI_COMMIT_MESSAGE_STYLE'],
115
+ 'AI': ['MAIASS_AI_MODE', 'MAIASS_AI_TOKEN', 'MAIASS_AI_MODEL', 'MAIASS_AI_COMMIT_MODEL', 'MAIASS_AI_TEMPERATURE', 'MAIASS_AI_ENDPOINT', 'MAIASS_AI_MAX_CHARACTERS', 'MAIASS_AI_COMMIT_MESSAGE_STYLE'],
116
116
  'Branches': ['MAIASS_DEVELOPBRANCH', 'MAIASS_STAGINGBRANCH', 'MAIASS_MAINBRANCH'],
117
117
  'Repository': ['MAIASS_REPO_TYPE', 'MAIASS_GITHUB_OWNER', 'MAIASS_GITHUB_REPO', 'MAIASS_BITBUCKET_WORKSPACE', 'MAIASS_BITBUCKET_REPO_SLUG'],
118
118
  'Pull Requests': ['MAIASS_DEVELOP_PULLREQUESTS'],
@@ -22,6 +22,7 @@ export const MAIASS_VARIABLES = {
22
22
  'MAIASS_AI_MODE': { default: 'ask', description: 'AI interaction mode' },
23
23
  'MAIASS_AI_TOKEN': { default: '', description: 'AI API token', sensitive: true },
24
24
  'MAIASS_AI_MODEL': { default: 'gpt-3.5-turbo', description: 'AI model to use' },
25
+ 'MAIASS_AI_COMMIT_MODEL': { default: '', description: 'Override the AI model used for commit message generation. If set, skips auto-pick. Defaults to MAIASS_AI_MODEL if set, otherwise auto-picks by diff size.' },
25
26
  'MAIASS_AI_TEMPERATURE': { default: '0.7', description: 'AI temperature setting' },
26
27
  'MAIASS_AI_MAX_CHARACTERS': { default: '8000', description: 'Max characters for AI requests' },
27
28
  'MAIASS_AI_TIMEOUT': { default: '30', description: 'AI request timeout in seconds' },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "maiass",
3
3
  "type": "module",
4
- "version": "5.14.0",
4
+ "version": "5.14.2",
5
5
  "description": "AI commit messages, version bumps, and changelogs from one command. Stages, commits, merges, tags. Anonymous on first run — no email, no card.",
6
6
  "main": "maiass.mjs",
7
7
  "bin": {