careervivid 1.12.7 → 1.12.9

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.
@@ -14,6 +14,7 @@ export interface AnthropicProviderOptions {
14
14
  export declare class AnthropicProvider implements LLMProvider {
15
15
  private apiKey;
16
16
  constructor(options: AnthropicProviderOptions);
17
+ private geminiSchemaToJsonSchema;
17
18
  private toAnthropicTools;
18
19
  private toAnthropicMessages;
19
20
  generate(request: LLMRequest): Promise<LLMResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"AnthropicProvider.d.ts","sourceRoot":"","sources":["../../../src/agent/providers/AnthropicProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACf,MAAM,kBAAkB,CAAC;AAK1B,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,wBAAwB;IAK7C,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,mBAAmB;IAgErB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IA+DnD,cAAc,CAClB,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACvC,OAAO,CAAC,WAAW,CAAC;CA+GxB"}
1
+ {"version":3,"file":"AnthropicProvider.d.ts","sourceRoot":"","sources":["../../../src/agent/providers/AnthropicProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACf,MAAM,kBAAkB,CAAC;AAK1B,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,wBAAwB;IAK7C,OAAO,CAAC,wBAAwB;IAwBhC,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,mBAAmB;IAgErB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IA+DnD,cAAc,CAClB,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACvC,OAAO,CAAC,WAAW,CAAC;CA+GxB"}
@@ -14,12 +14,41 @@ export class AnthropicProvider {
14
14
  constructor(options) {
15
15
  this.apiKey = options.apiKey;
16
16
  }
17
+ // ── Convert Gemini @google/genai Type enum values to JSON Schema ──────────
18
+ geminiSchemaToJsonSchema(schema) {
19
+ if (!schema || typeof schema !== "object")
20
+ return schema;
21
+ const TYPE_MAP = {
22
+ OBJECT: "object", STRING: "string", NUMBER: "number",
23
+ INTEGER: "integer", BOOLEAN: "boolean", ARRAY: "array",
24
+ object: "object", string: "string", number: "number",
25
+ integer: "integer", boolean: "boolean", array: "array",
26
+ };
27
+ const result = {};
28
+ if (schema.type)
29
+ result.type = TYPE_MAP[schema.type] ?? schema.type.toLowerCase();
30
+ if (schema.description)
31
+ result.description = schema.description;
32
+ if (schema.enum)
33
+ result.enum = schema.enum;
34
+ if (schema.required)
35
+ result.required = schema.required;
36
+ if (schema.properties && typeof schema.properties === "object") {
37
+ result.properties = {};
38
+ for (const [key, val] of Object.entries(schema.properties)) {
39
+ result.properties[key] = this.geminiSchemaToJsonSchema(val);
40
+ }
41
+ }
42
+ if (schema.items)
43
+ result.items = this.geminiSchemaToJsonSchema(schema.items);
44
+ return result;
45
+ }
17
46
  // ── Convert our Tool[] to Anthropic tool definitions ─────────────────────
18
47
  toAnthropicTools(tools) {
19
48
  return tools.map((t) => ({
20
49
  name: t.name,
21
50
  description: t.description,
22
- input_schema: t.parameters,
51
+ input_schema: this.geminiSchemaToJsonSchema(t.parameters),
23
52
  }));
24
53
  }
25
54
  // ── Convert Gemini Content[] to Anthropic messages[] ─────────────────────
@@ -27,6 +27,7 @@ export declare class OpenAIProvider implements LLMProvider {
27
27
  private baseUrl;
28
28
  private extraHeaders;
29
29
  constructor(options: OpenAIProviderOptions);
30
+ private geminiSchemaToJsonSchema;
30
31
  private toOpenAITools;
31
32
  private toOpenAIMessages;
32
33
  generate(request: LLMRequest): Promise<LLMResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"OpenAIProvider.d.ts","sourceRoot":"","sources":["../../../src/agent/providers/OpenAIProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACf,MAAM,kBAAkB,CAAC;AAG1B,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAyB;gBAEjC,OAAO,EAAE,qBAAqB;IAU1C,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,gBAAgB;IAgElB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IA2DnD,cAAc,CAClB,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACvC,OAAO,CAAC,WAAW,CAAC;CAuGxB;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,QAAQ,GAAG,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,EACzE,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB,cAAc,CAqBhB"}
1
+ {"version":3,"file":"OpenAIProvider.d.ts","sourceRoot":"","sources":["../../../src/agent/providers/OpenAIProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACf,MAAM,kBAAkB,CAAC;AAG1B,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAyB;gBAEjC,OAAO,EAAE,qBAAqB;IAY1C,OAAO,CAAC,wBAAwB;IA2ChC,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,gBAAgB;IAgElB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IA2DnD,cAAc,CAClB,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACvC,OAAO,CAAC,WAAW,CAAC;CAuGxB;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,QAAQ,GAAG,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,EACzE,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB,cAAc,CAqBhB"}
@@ -24,6 +24,48 @@ export class OpenAIProvider {
24
24
  this.baseUrl = (options.baseUrl || "https://api.openai.com/v1").replace(/\/$/, "");
25
25
  this.extraHeaders = options.extraHeaders || {};
26
26
  }
27
+ // ── Convert Gemini @google/genai Type enum values to JSON Schema ──────────
28
+ // Gemini uses uppercase strings like "OBJECT", "STRING", "ARRAY".
29
+ // OpenAI-compatible APIs (OpenRouter, OpenAI, etc.) use lowercase JSON Schema.
30
+ geminiSchemaToJsonSchema(schema) {
31
+ if (!schema || typeof schema !== "object")
32
+ return schema;
33
+ const TYPE_MAP = {
34
+ OBJECT: "object",
35
+ STRING: "string",
36
+ NUMBER: "number",
37
+ INTEGER: "integer",
38
+ BOOLEAN: "boolean",
39
+ ARRAY: "array",
40
+ // Already lowercase passthrough
41
+ object: "object",
42
+ string: "string",
43
+ number: "number",
44
+ integer: "integer",
45
+ boolean: "boolean",
46
+ array: "array",
47
+ };
48
+ const result = {};
49
+ if (schema.type) {
50
+ result.type = TYPE_MAP[schema.type] ?? schema.type.toLowerCase();
51
+ }
52
+ if (schema.description)
53
+ result.description = schema.description;
54
+ if (schema.enum)
55
+ result.enum = schema.enum;
56
+ if (schema.required)
57
+ result.required = schema.required;
58
+ if (schema.properties && typeof schema.properties === "object") {
59
+ result.properties = {};
60
+ for (const [key, val] of Object.entries(schema.properties)) {
61
+ result.properties[key] = this.geminiSchemaToJsonSchema(val);
62
+ }
63
+ }
64
+ if (schema.items) {
65
+ result.items = this.geminiSchemaToJsonSchema(schema.items);
66
+ }
67
+ return result;
68
+ }
27
69
  // ── convert our Tool[] to OpenAI function definitions ────────────────────
28
70
  toOpenAITools(tools) {
29
71
  return tools.map((t) => ({
@@ -31,7 +73,7 @@ export class OpenAIProvider {
31
73
  function: {
32
74
  name: t.name,
33
75
  description: t.description,
34
- parameters: t.parameters,
76
+ parameters: this.geminiSchemaToJsonSchema(t.parameters),
35
77
  },
36
78
  }));
37
79
  }
@@ -1 +1 @@
1
- {"version":3,"file":"configurator.d.ts","sourceRoot":"","sources":["../../../src/commands/agent/configurator.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAI3E,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKpD,CAAC;AAEF,eAAO,MAAM,SAAS;;;;;GAyBrB,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;GA+BtB,CAAC;AAEF,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAsEpD;AAED,wBAAsB,mBAAmB,CAAC,OAAO,GAAE,GAAQ,GAAG,OAAO,CAAC;IACpE,gBAAgB,EAAE,WAAW,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAqED"}
1
+ {"version":3,"file":"configurator.d.ts","sourceRoot":"","sources":["../../../src/commands/agent/configurator.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAI3E,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKpD,CAAC;AAEF,eAAO,MAAM,SAAS;;;;;GAyBrB,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;GA+BtB,CAAC;AAEF,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAsEpD;AAED,wBAAsB,mBAAmB,CAAC,OAAO,GAAE,GAAQ,GAAG,OAAO,CAAC;IACpE,gBAAgB,EAAE,WAAW,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CA4ED"}
@@ -162,7 +162,8 @@ export async function promptForAgentModel(options = {}) {
162
162
  __custom__: "custom",
163
163
  };
164
164
  selectedProvider = providerMap[picked] || "openai";
165
- const savedKey = loadConfig().llmApiKey;
165
+ const savedCfg = loadConfig();
166
+ const savedKey = savedCfg.llmApiKey;
166
167
  if (!savedKey) {
167
168
  console.log(chalk.yellow(`\n🔑 BYO API key needed for ${selectedProvider}.`));
168
169
  console.log(chalk.dim(" Run: cv agent config to save your key permanently.\n"));
@@ -173,17 +174,21 @@ export async function promptForAgentModel(options = {}) {
173
174
  });
174
175
  apiKey = keyAnswer.key.trim();
175
176
  }
176
- const modelAnswer2 = await prompt({
177
- type: "input",
178
- name: "model",
179
- message: "Model name:",
180
- initial: selectedProvider === "openai"
177
+ // Pre-fill with the saved model when provider matches, otherwise use sensible defaults
178
+ const defaultModel = savedCfg.llmProvider === selectedProvider && savedCfg.llmModel
179
+ ? savedCfg.llmModel
180
+ : selectedProvider === "openai"
181
181
  ? "gpt-4o"
182
182
  : selectedProvider === "anthropic"
183
183
  ? "claude-opus-4-5"
184
184
  : selectedProvider === "gemini"
185
185
  ? "gemini-2.5-flash"
186
- : "openai/gpt-4o",
186
+ : "google/gemma-4-31b-it:free";
187
+ const modelAnswer2 = await prompt({
188
+ type: "input",
189
+ name: "model",
190
+ message: "Model name:",
191
+ initial: defaultModel,
187
192
  });
188
193
  selectedModel = modelAnswer2.model.trim();
189
194
  thinkingBudget = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAyHpD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAwHpD"}
@@ -58,16 +58,14 @@ export function registerAgentCommand(program) {
58
58
  selectedProvider = "careervivid";
59
59
  }
60
60
  else if (options.provider && options.provider !== "careervivid") {
61
- selectedProvider = llmCfg.provider;
62
- selectedModel = llmCfg.model;
63
- thinkingBudget = 0;
64
- }
65
- else if (llmCfg.provider !== "careervivid") {
61
+ // User explicitly passed --provider on the CLI — use it directly, no picker
66
62
  selectedProvider = llmCfg.provider;
67
63
  selectedModel = llmCfg.model;
68
64
  thinkingBudget = 0;
69
65
  }
70
66
  else {
67
+ // Always show the picker. Saved config pre-fills BYO model inputs but does
68
+ // not bypass the prompt. This lets the user choose per-session.
71
69
  const result = await promptForAgentModel(options);
72
70
  selectedProvider = result.selectedProvider;
73
71
  selectedModel = result.selectedModel;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "careervivid",
3
- "version": "1.12.7",
3
+ "version": "1.12.9",
4
4
  "description": "Official CLI for CareerVivid — publish articles, diagrams, and portfolio updates from your terminal or AI agent",
5
5
  "type": "module",
6
6
  "bin": {