kairn-cli 2.2.1 → 2.2.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/dist/cli.js CHANGED
@@ -1237,22 +1237,29 @@ function classifyError(err, provider) {
1237
1237
  }
1238
1238
  async function callLLM(config, userMessage, options) {
1239
1239
  const maxTokens = options.maxTokens ?? 8192;
1240
- const systemPrompt = options.systemPrompt;
1240
+ const { systemPrompt } = options;
1241
+ const jsonMode = options.jsonMode ?? false;
1241
1242
  const providerName = getProviderName(config.provider);
1242
1243
  if (config.provider === "anthropic") {
1243
1244
  const client2 = new Anthropic2({ apiKey: config.api_key });
1245
+ const messages = [
1246
+ { role: "user", content: userMessage }
1247
+ ];
1248
+ if (jsonMode) {
1249
+ messages.push({ role: "assistant", content: "{" });
1250
+ }
1244
1251
  try {
1245
1252
  const response = await client2.messages.create({
1246
1253
  model: config.model,
1247
1254
  max_tokens: maxTokens,
1248
1255
  system: systemPrompt,
1249
- messages: [{ role: "user", content: userMessage }]
1256
+ messages
1250
1257
  });
1251
1258
  const textBlock = response.content.find((block) => block.type === "text");
1252
1259
  if (!textBlock || textBlock.type !== "text") {
1253
1260
  throw new Error("No text response from compiler LLM");
1254
1261
  }
1255
- return textBlock.text;
1262
+ return jsonMode ? `{${textBlock.text}` : textBlock.text;
1256
1263
  } catch (err) {
1257
1264
  throw new Error(classifyError(err, providerName));
1258
1265
  }
@@ -1268,7 +1275,8 @@ async function callLLM(config, userMessage, options) {
1268
1275
  messages: [
1269
1276
  { role: "system", content: systemPrompt },
1270
1277
  { role: "user", content: userMessage }
1271
- ]
1278
+ ],
1279
+ ...jsonMode ? { response_format: { type: "json_object" } } : {}
1272
1280
  });
1273
1281
  const text = response.choices[0]?.message?.content;
1274
1282
  if (!text) {
@@ -4785,7 +4793,18 @@ function parseProposerResponse(raw) {
4785
4793
  try {
4786
4794
  parsed = JSON.parse(cleaned);
4787
4795
  } catch {
4788
- throw new Error(`Proposer returned invalid JSON: ${cleaned.slice(0, 200)}`);
4796
+ const firstBrace = cleaned.indexOf("{");
4797
+ const lastBrace = cleaned.lastIndexOf("}");
4798
+ if (firstBrace !== -1 && lastBrace > firstBrace) {
4799
+ const extracted = cleaned.slice(firstBrace, lastBrace + 1);
4800
+ try {
4801
+ parsed = JSON.parse(extracted);
4802
+ } catch {
4803
+ throw new Error(`Proposer returned invalid JSON: ${cleaned.slice(0, 200)}`);
4804
+ }
4805
+ } else {
4806
+ throw new Error(`Proposer returned invalid JSON: ${cleaned.slice(0, 200)}`);
4807
+ }
4789
4808
  }
4790
4809
  if (typeof parsed !== "object" || parsed === null) {
4791
4810
  throw new Error("Proposer response is not a JSON object");
@@ -4848,7 +4867,8 @@ async function propose(iteration, workspacePath, harnessPath, history, tasks, co
4848
4867
  const proposerConfig = { ...config, model: proposerModel };
4849
4868
  const response = await callLLM(proposerConfig, userMessage, {
4850
4869
  systemPrompt: PROPOSER_SYSTEM_PROMPT,
4851
- maxTokens: 8192
4870
+ maxTokens: 8192,
4871
+ jsonMode: true
4852
4872
  });
4853
4873
  return parseProposerResponse(response);
4854
4874
  }