vellum 0.2.2 → 0.2.7

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 (32) hide show
  1. package/bun.lock +68 -100
  2. package/package.json +3 -3
  3. package/src/__tests__/config-schema.test.ts +6 -0
  4. package/src/__tests__/handlers-twilio-config.test.ts +221 -0
  5. package/src/__tests__/ipc-snapshot.test.ts +9 -0
  6. package/src/__tests__/memory-regressions.test.ts +100 -2
  7. package/src/__tests__/provider-commit-message-generator.test.ts +303 -0
  8. package/src/__tests__/session-conflict-gate.test.ts +28 -25
  9. package/src/calls/__tests__/twilio-webhook-urls.test.ts +162 -0
  10. package/src/calls/call-domain.ts +3 -3
  11. package/src/calls/twilio-config.ts +8 -8
  12. package/src/calls/twilio-provider.ts +4 -4
  13. package/src/calls/twilio-webhook-urls.ts +50 -0
  14. package/src/cli/map.ts +30 -6
  15. package/src/config/defaults.ts +1 -0
  16. package/src/config/schema.ts +4 -0
  17. package/src/config/vellum-skills/telegram-setup/SKILL.md +1 -5
  18. package/src/daemon/handlers/config.ts +44 -2
  19. package/src/daemon/ipc-contract-inventory.json +4 -0
  20. package/src/daemon/ipc-contract.ts +23 -0
  21. package/src/daemon/ride-shotgun-handler.ts +2 -1
  22. package/src/daemon/session-agent-loop.ts +37 -2
  23. package/src/daemon/session-conflict-gate.ts +18 -109
  24. package/src/memory/conflict-intent.ts +114 -0
  25. package/src/memory/job-handlers/conflict.ts +23 -1
  26. package/src/runtime/gateway-client.ts +36 -0
  27. package/src/runtime/http-server.ts +58 -2
  28. package/src/runtime/routes/channel-routes.ts +121 -79
  29. package/src/tools/browser/api-map.ts +123 -50
  30. package/src/tools/claude-code/claude-code.ts +130 -0
  31. package/src/workspace/commit-message-enrichment-service.ts +3 -3
  32. package/src/workspace/provider-commit-message-generator.ts +28 -1
@@ -9,6 +9,7 @@ const log = getLogger('commit-message-llm');
9
9
  export type CommitMessageSource = 'llm' | 'deterministic';
10
10
  export type LLMFallbackReason =
11
11
  | 'disabled'
12
+ | 'missing_provider_api_key'
12
13
  | 'provider_not_initialized'
13
14
  | 'breaker_open'
14
15
  | 'insufficient_budget'
@@ -36,6 +37,15 @@ Rules:
36
37
  - Total output must be under 300 characters
37
38
  - If you cannot determine a meaningful message, respond with exactly: FALLBACK`;
38
39
 
40
+ const PROVIDER_DEFAULT_FAST_MODELS: Record<string, string> = {
41
+ anthropic: 'claude-haiku-4-5-20251001',
42
+ openai: 'gpt-4o-mini',
43
+ gemini: 'gemini-2.0-flash',
44
+ };
45
+
46
+ // Providers that can be initialized without an API key (e.g., Ollama runs locally)
47
+ const KEYLESS_PROVIDERS = new Set(['ollama']);
48
+
39
49
  const deterministicProvider = new DefaultCommitMessageProvider();
40
50
 
41
51
  function buildDeterministicResult(
@@ -103,6 +113,15 @@ export class ProviderCommitMessageGenerator {
103
113
  return buildDeterministicResult(context, 'disabled');
104
114
  }
105
115
 
116
+ // Step 2.5: API key preflight (skip for providers that run without a key)
117
+ if (!KEYLESS_PROVIDERS.has(config.provider)) {
118
+ const providerApiKey = config.apiKeys[config.provider];
119
+ if (!providerApiKey || providerApiKey === '') {
120
+ log.debug('Provider API key missing; falling back to deterministic');
121
+ return buildDeterministicResult(context, 'missing_provider_api_key');
122
+ }
123
+ }
124
+
106
125
  // Step 3: Circuit breaker
107
126
  if (this.isBreakerOpen()) {
108
127
  log.debug(
@@ -160,6 +179,14 @@ export class ProviderCommitMessageGenerator {
160
179
  },
161
180
  ];
162
181
 
182
+ // Resolve fast model
183
+ const fastModel = llmConfig.providerFastModelOverrides[config.provider]
184
+ ?? PROVIDER_DEFAULT_FAST_MODELS[config.provider];
185
+ if (!fastModel) {
186
+ log.debug({ provider: config.provider }, 'No default fast model for provider; falling back to deterministic');
187
+ return buildDeterministicResult(context, 'provider_error');
188
+ }
189
+
163
190
  // AbortController with timeout
164
191
  const ac = new AbortController();
165
192
  const timer = setTimeout(() => ac.abort(), llmConfig.timeoutMs);
@@ -172,7 +199,7 @@ export class ProviderCommitMessageGenerator {
172
199
  SYSTEM_PROMPT,
173
200
  {
174
201
  signal: ac.signal,
175
- config: { max_tokens: llmConfig.maxTokens, temperature: llmConfig.temperature },
202
+ config: { model: fastModel, max_tokens: llmConfig.maxTokens, temperature: llmConfig.temperature },
176
203
  },
177
204
  );
178
205
  } catch (err: unknown) {