@ljoukov/llm 4.0.8 → 4.0.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.
package/dist/index.js CHANGED
@@ -2769,6 +2769,33 @@ function ensureTrailingNewline(value) {
2769
2769
  function hasNonEmptyText(value) {
2770
2770
  return typeof value === "string" && value.length > 0;
2771
2771
  }
2772
+ function hasLogArtifactValue(value) {
2773
+ if (value === null || value === void 0) {
2774
+ return false;
2775
+ }
2776
+ if (typeof value === "string") {
2777
+ return value.length > 0;
2778
+ }
2779
+ if (Array.isArray(value)) {
2780
+ return value.length > 0;
2781
+ }
2782
+ if (typeof value === "object") {
2783
+ return Object.keys(value).length > 0;
2784
+ }
2785
+ return true;
2786
+ }
2787
+ function serialiseJsonArtifact(value) {
2788
+ if (!hasLogArtifactValue(value)) {
2789
+ return void 0;
2790
+ }
2791
+ try {
2792
+ return `${JSON.stringify(sanitiseLogValue(value), null, 2)}
2793
+ `;
2794
+ } catch {
2795
+ return `${JSON.stringify(String(value), null, 2)}
2796
+ `;
2797
+ }
2798
+ }
2772
2799
  function redactDataUrlPayload(value) {
2773
2800
  if (!value.toLowerCase().startsWith("data:")) {
2774
2801
  return value;
@@ -3049,7 +3076,9 @@ var AgentLoggingSessionImpl = class {
3049
3076
  const responsePath = path3.join(baseDir, "response.txt");
3050
3077
  const thoughtsPath = path3.join(baseDir, "thoughts.txt");
3051
3078
  const toolCallPath = path3.join(baseDir, "tool_call.txt");
3079
+ const toolCallJsonPath = path3.join(baseDir, "tool_call.json");
3052
3080
  const toolCallResponsePath = path3.join(baseDir, "tool_call_response.txt");
3081
+ const toolCallResponseJsonPath = path3.join(baseDir, "tool_call_response.json");
3053
3082
  const errorPath = path3.join(baseDir, "error.txt");
3054
3083
  const responseMetadataPath = path3.join(baseDir, "response.metadata.json");
3055
3084
  let chain = this.ensureReady.then(async () => {
@@ -3080,6 +3109,10 @@ var AgentLoggingSessionImpl = class {
3080
3109
  "utf8"
3081
3110
  );
3082
3111
  }
3112
+ const toolCallResponseJson = serialiseJsonArtifact(input.toolCallResponsePayload);
3113
+ if (toolCallResponseJson) {
3114
+ await writeFile(toolCallResponseJsonPath, toolCallResponseJson, "utf8");
3115
+ }
3083
3116
  }).catch(() => void 0);
3084
3117
  this.track(chain);
3085
3118
  let closed = false;
@@ -3118,6 +3151,10 @@ var AgentLoggingSessionImpl = class {
3118
3151
  if (hasNonEmptyText(options?.toolCallText)) {
3119
3152
  await writeFile(toolCallPath, ensureTrailingNewline(options.toolCallText), "utf8");
3120
3153
  }
3154
+ const toolCallJson = serialiseJsonArtifact(options?.toolCallPayload);
3155
+ if (toolCallJson) {
3156
+ await writeFile(toolCallJsonPath, toolCallJson, "utf8");
3157
+ }
3121
3158
  await this.writeAttachments(baseDir, options?.attachments);
3122
3159
  const payload = {
3123
3160
  capturedAt: toIsoNow(),
@@ -3147,6 +3184,10 @@ var AgentLoggingSessionImpl = class {
3147
3184
  if (hasNonEmptyText(options?.toolCallText)) {
3148
3185
  await writeFile(toolCallPath, ensureTrailingNewline(options.toolCallText), "utf8");
3149
3186
  }
3187
+ const toolCallJson = serialiseJsonArtifact(options?.toolCallPayload);
3188
+ if (toolCallJson) {
3189
+ await writeFile(toolCallJsonPath, toolCallJson, "utf8");
3190
+ }
3150
3191
  await this.writeAttachments(baseDir, options?.attachments);
3151
3192
  await writeFile(errorPath, ensureTrailingNewline(toErrorMessage(error)), "utf8");
3152
3193
  const payload = {
@@ -5124,6 +5165,10 @@ function collectLoggedAttachmentsFromGeminiParts(parts, prefix) {
5124
5165
  return collectLoggedAttachmentsFromLlmParts(convertGooglePartsToLlmParts(parts), prefix);
5125
5166
  }
5126
5167
  function extractToolCallResponseTextFromOpenAiInput(input) {
5168
+ const responses = extractToolCallResponsePayloadFromOpenAiInput(input);
5169
+ return serialiseLogArtifactText(responses);
5170
+ }
5171
+ function extractToolCallResponsePayloadFromOpenAiInput(input) {
5127
5172
  if (!Array.isArray(input)) {
5128
5173
  return void 0;
5129
5174
  }
@@ -5140,9 +5185,13 @@ function extractToolCallResponseTextFromOpenAiInput(input) {
5140
5185
  }
5141
5186
  ];
5142
5187
  });
5143
- return serialiseLogArtifactText(responses);
5188
+ return responses.length > 0 ? responses : void 0;
5144
5189
  }
5145
5190
  function extractToolCallResponseTextFromFireworksMessages(messages) {
5191
+ const responses = extractToolCallResponsePayloadFromFireworksMessages(messages);
5192
+ return serialiseLogArtifactText(responses);
5193
+ }
5194
+ function extractToolCallResponsePayloadFromFireworksMessages(messages) {
5146
5195
  if (!Array.isArray(messages)) {
5147
5196
  return void 0;
5148
5197
  }
@@ -5157,9 +5206,13 @@ function extractToolCallResponseTextFromFireworksMessages(messages) {
5157
5206
  }
5158
5207
  ];
5159
5208
  });
5160
- return serialiseLogArtifactText(responses);
5209
+ return responses.length > 0 ? responses : void 0;
5161
5210
  }
5162
5211
  function extractToolCallResponseTextFromGeminiContents(contents) {
5212
+ const responses = extractToolCallResponsePayloadFromGeminiContents(contents);
5213
+ return serialiseLogArtifactText(responses);
5214
+ }
5215
+ function extractToolCallResponsePayloadFromGeminiContents(contents) {
5163
5216
  if (!Array.isArray(contents)) {
5164
5217
  return void 0;
5165
5218
  }
@@ -5182,40 +5235,36 @@ function extractToolCallResponseTextFromGeminiContents(contents) {
5182
5235
  }
5183
5236
  }
5184
5237
  }
5185
- return serialiseLogArtifactText(responses);
5238
+ return responses.length > 0 ? responses : void 0;
5186
5239
  }
5187
- function serialiseOpenAiStyleToolCallsForLogging(calls) {
5188
- return serialiseLogArtifactText(
5189
- calls.map((call) => {
5190
- if (call.kind === "custom") {
5191
- return {
5192
- kind: call.kind,
5193
- name: call.name,
5194
- callId: call.callId,
5195
- itemId: call.itemId,
5196
- input: call.input
5197
- };
5198
- }
5199
- const { value, error } = parseOpenAiToolArguments(call.arguments);
5240
+ function toLoggedOpenAiStyleToolCalls(calls) {
5241
+ return calls.map((call) => {
5242
+ if (call.kind === "custom") {
5200
5243
  return {
5201
5244
  kind: call.kind,
5202
5245
  name: call.name,
5203
5246
  callId: call.callId,
5204
5247
  itemId: call.itemId,
5205
- arguments: value,
5206
- ...error ? { parseError: error, rawArguments: call.arguments } : {}
5248
+ input: call.input
5207
5249
  };
5208
- })
5209
- );
5250
+ }
5251
+ const { value, error } = parseOpenAiToolArguments(call.arguments);
5252
+ return {
5253
+ kind: call.kind,
5254
+ name: call.name,
5255
+ callId: call.callId,
5256
+ itemId: call.itemId,
5257
+ arguments: value,
5258
+ ...error ? { parseError: error, rawArguments: call.arguments } : {}
5259
+ };
5260
+ });
5210
5261
  }
5211
- function serialiseGeminiToolCallsForLogging(calls) {
5212
- return serialiseLogArtifactText(
5213
- calls.map((call) => ({
5214
- name: call.name ?? "unknown",
5215
- callId: typeof call.id === "string" ? call.id : void 0,
5216
- arguments: sanitiseLogValue(call.args ?? {})
5217
- }))
5218
- );
5262
+ function toLoggedGeminiToolCalls(calls) {
5263
+ return calls.map((call) => ({
5264
+ name: call.name ?? "unknown",
5265
+ callId: typeof call.id === "string" ? call.id : void 0,
5266
+ arguments: sanitiseLogValue(call.args ?? {})
5267
+ }));
5219
5268
  }
5220
5269
  function startLlmCallLoggerFromContents(options) {
5221
5270
  const session = getCurrentAgentLoggingSession();
@@ -5295,6 +5344,13 @@ function startLlmCallLoggerFromPayload(options) {
5295
5344
  ) : extractToolCallResponseTextFromGeminiContents(
5296
5345
  options.requestPayload.contents
5297
5346
  );
5347
+ const toolCallResponsePayload = options.provider === "openai" || options.provider === "chatgpt" ? extractToolCallResponsePayloadFromOpenAiInput(
5348
+ options.requestPayload.input
5349
+ ) : options.provider === "fireworks" ? extractToolCallResponsePayloadFromFireworksMessages(
5350
+ options.requestPayload.messages
5351
+ ) : extractToolCallResponsePayloadFromGeminiContents(
5352
+ options.requestPayload.contents
5353
+ );
5298
5354
  return session.startLlmCall({
5299
5355
  provider: options.provider,
5300
5356
  modelId: options.modelId,
@@ -5304,7 +5360,8 @@ function startLlmCallLoggerFromPayload(options) {
5304
5360
  ...getCurrentToolCallContext() ? { toolContext: getCurrentToolCallContext() } : {}
5305
5361
  },
5306
5362
  attachments,
5307
- toolCallResponseText
5363
+ toolCallResponseText,
5364
+ toolCallResponsePayload
5308
5365
  });
5309
5366
  }
5310
5367
  async function runTextCall(params) {
@@ -6135,6 +6192,7 @@ async function runToolLoop(request) {
6135
6192
  let responseText = "";
6136
6193
  let reasoningSummary = "";
6137
6194
  let stepToolCallText;
6195
+ let stepToolCallPayload;
6138
6196
  const stepRequestPayload = {
6139
6197
  model: providerInfo.model,
6140
6198
  input,
@@ -6244,7 +6302,7 @@ async function runToolLoop(request) {
6244
6302
  emitEvent({ type: "usage", usage: usageTokens, costUsd: stepCostUsd, modelVersion });
6245
6303
  }
6246
6304
  const responseToolCalls = extractOpenAiToolCalls(finalResponse.output);
6247
- stepToolCallText = serialiseOpenAiStyleToolCallsForLogging(
6305
+ stepToolCallPayload = toLoggedOpenAiStyleToolCalls(
6248
6306
  responseToolCalls.map(
6249
6307
  (call) => call.kind === "custom" ? {
6250
6308
  kind: call.kind,
@@ -6261,6 +6319,7 @@ async function runToolLoop(request) {
6261
6319
  }
6262
6320
  )
6263
6321
  );
6322
+ stepToolCallText = serialiseLogArtifactText(stepToolCallPayload);
6264
6323
  const stepToolCalls = [];
6265
6324
  if (responseToolCalls.length === 0) {
6266
6325
  const steeringInput2 = steeringInternal?.drainPendingContents() ?? [];
@@ -6426,6 +6485,7 @@ async function runToolLoop(request) {
6426
6485
  stepCallLogger?.complete({
6427
6486
  responseText,
6428
6487
  toolCallText: stepToolCallText,
6488
+ toolCallPayload: stepToolCallPayload,
6429
6489
  metadata: {
6430
6490
  provider: "openai",
6431
6491
  model: request.model,
@@ -6446,6 +6506,7 @@ async function runToolLoop(request) {
6446
6506
  stepCallLogger?.fail(error, {
6447
6507
  responseText,
6448
6508
  toolCallText: stepToolCallText,
6509
+ toolCallPayload: stepToolCallPayload,
6449
6510
  metadata: {
6450
6511
  provider: "openai",
6451
6512
  model: request.model,
@@ -6480,6 +6541,7 @@ async function runToolLoop(request) {
6480
6541
  let responseText = "";
6481
6542
  let reasoningSummaryText = "";
6482
6543
  let stepToolCallText;
6544
+ let stepToolCallPayload;
6483
6545
  const markFirstModelEvent = () => {
6484
6546
  if (firstModelEventAtMs === void 0) {
6485
6547
  firstModelEventAtMs = Date.now();
@@ -6548,7 +6610,7 @@ async function runToolLoop(request) {
6548
6610
  stepCallLogger?.appendResponseDelta(responseText);
6549
6611
  }
6550
6612
  const responseToolCalls = response.toolCalls ?? [];
6551
- stepToolCallText = serialiseOpenAiStyleToolCallsForLogging(
6613
+ stepToolCallPayload = toLoggedOpenAiStyleToolCalls(
6552
6614
  responseToolCalls.map(
6553
6615
  (call) => call.kind === "custom" ? {
6554
6616
  kind: call.kind,
@@ -6565,6 +6627,7 @@ async function runToolLoop(request) {
6565
6627
  }
6566
6628
  )
6567
6629
  );
6630
+ stepToolCallText = serialiseLogArtifactText(stepToolCallPayload);
6568
6631
  if (responseToolCalls.length === 0) {
6569
6632
  const steeringInput2 = steeringInternal?.drainPendingContents() ?? [];
6570
6633
  const steeringItems2 = steeringInput2.length > 0 ? toChatGptInput(steeringInput2).input : [];
@@ -6737,6 +6800,7 @@ async function runToolLoop(request) {
6737
6800
  stepCallLogger?.complete({
6738
6801
  responseText,
6739
6802
  toolCallText: stepToolCallText,
6803
+ toolCallPayload: stepToolCallPayload,
6740
6804
  metadata: {
6741
6805
  provider: "chatgpt",
6742
6806
  model: request.model,
@@ -6755,6 +6819,7 @@ async function runToolLoop(request) {
6755
6819
  stepCallLogger?.fail(error, {
6756
6820
  responseText,
6757
6821
  toolCallText: stepToolCallText,
6822
+ toolCallPayload: stepToolCallPayload,
6758
6823
  metadata: {
6759
6824
  provider: "chatgpt",
6760
6825
  model: request.model,
@@ -6785,6 +6850,7 @@ async function runToolLoop(request) {
6785
6850
  let responseText = "";
6786
6851
  let blocked = false;
6787
6852
  let stepToolCallText;
6853
+ let stepToolCallPayload;
6788
6854
  const stepRequestPayload = {
6789
6855
  model: providerInfo.model,
6790
6856
  messages,
@@ -6849,7 +6915,7 @@ async function runToolLoop(request) {
6849
6915
  });
6850
6916
  }
6851
6917
  const responseToolCalls = extractFireworksToolCalls(message);
6852
- stepToolCallText = serialiseOpenAiStyleToolCallsForLogging(
6918
+ stepToolCallPayload = toLoggedOpenAiStyleToolCalls(
6853
6919
  responseToolCalls.map((call) => ({
6854
6920
  kind: "function",
6855
6921
  name: call.name,
@@ -6857,6 +6923,7 @@ async function runToolLoop(request) {
6857
6923
  callId: call.id
6858
6924
  }))
6859
6925
  );
6926
+ stepToolCallText = serialiseLogArtifactText(stepToolCallPayload);
6860
6927
  if (responseToolCalls.length === 0) {
6861
6928
  const steeringInput2 = steeringInternal?.drainPendingContents() ?? [];
6862
6929
  const steeringMessages = steeringInput2.length > 0 ? toFireworksMessages(steeringInput2) : [];
@@ -7009,6 +7076,7 @@ async function runToolLoop(request) {
7009
7076
  stepCallLogger?.complete({
7010
7077
  responseText,
7011
7078
  toolCallText: stepToolCallText,
7079
+ toolCallPayload: stepToolCallPayload,
7012
7080
  metadata: {
7013
7081
  provider: "fireworks",
7014
7082
  model: request.model,
@@ -7037,6 +7105,7 @@ async function runToolLoop(request) {
7037
7105
  stepCallLogger?.fail(error, {
7038
7106
  responseText,
7039
7107
  toolCallText: stepToolCallText,
7108
+ toolCallPayload: stepToolCallPayload,
7040
7109
  metadata: {
7041
7110
  provider: "fireworks",
7042
7111
  model: request.model,
@@ -7065,6 +7134,7 @@ async function runToolLoop(request) {
7065
7134
  let responseText = "";
7066
7135
  let thoughtsText = "";
7067
7136
  let stepToolCallText;
7137
+ let stepToolCallPayload;
7068
7138
  const markFirstModelEvent = () => {
7069
7139
  if (firstModelEventAtMs === void 0) {
7070
7140
  firstModelEventAtMs = Date.now();
@@ -7195,7 +7265,8 @@ async function runToolLoop(request) {
7195
7265
  responseImages: 0
7196
7266
  });
7197
7267
  totalCostUsd += stepCostUsd;
7198
- stepToolCallText = serialiseGeminiToolCallsForLogging(response.functionCalls);
7268
+ stepToolCallPayload = toLoggedGeminiToolCalls(response.functionCalls);
7269
+ stepToolCallText = serialiseLogArtifactText(stepToolCallPayload);
7199
7270
  if (response.functionCalls.length === 0) {
7200
7271
  const steeringInput2 = steeringInternal?.drainPendingContents() ?? [];
7201
7272
  finalText = responseText;
@@ -7364,6 +7435,7 @@ async function runToolLoop(request) {
7364
7435
  responseText,
7365
7436
  attachments: responseOutputAttachments,
7366
7437
  toolCallText: stepToolCallText,
7438
+ toolCallPayload: stepToolCallPayload,
7367
7439
  metadata: {
7368
7440
  provider: "gemini",
7369
7441
  model: request.model,
@@ -7386,6 +7458,7 @@ async function runToolLoop(request) {
7386
7458
  stepCallLogger?.fail(error, {
7387
7459
  responseText,
7388
7460
  toolCallText: stepToolCallText,
7461
+ toolCallPayload: stepToolCallPayload,
7389
7462
  metadata: {
7390
7463
  provider: "gemini",
7391
7464
  model: request.model,