@runtypelabs/sdk 1.8.2 → 1.9.0

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.cjs CHANGED
@@ -6239,6 +6239,75 @@ Do NOT redo any of the above work.`
6239
6239
  (state.lastOutput || "").slice(0, 1800) || "- No final output recorded yet."
6240
6240
  ].join("\n");
6241
6241
  }
6242
+ isAssistantToolCallMessage(message) {
6243
+ return Boolean(message?.role === "assistant" && message.toolCalls && message.toolCalls.length > 0);
6244
+ }
6245
+ isToolResultMessage(message) {
6246
+ return Boolean(message?.role === "tool" && message.toolResults && message.toolResults.length > 0);
6247
+ }
6248
+ /**
6249
+ * Replay only complete adjacent tool-call/result pairs so provider validation
6250
+ * never sees an orphaned tool result after history trimming or resume.
6251
+ */
6252
+ sanitizeReplayHistoryMessages(messages) {
6253
+ const sanitized = [];
6254
+ for (let index = 0; index < messages.length; index++) {
6255
+ const message = messages[index];
6256
+ if (this.isAssistantToolCallMessage(message)) {
6257
+ const nextMessage = messages[index + 1];
6258
+ if (!this.isToolResultMessage(nextMessage)) {
6259
+ continue;
6260
+ }
6261
+ const matchedResultIds = new Set(
6262
+ nextMessage.toolResults.filter(
6263
+ (toolResult) => message.toolCalls.some((toolCall) => toolCall.toolCallId === toolResult.toolCallId)
6264
+ ).map((toolResult) => toolResult.toolCallId)
6265
+ );
6266
+ if (matchedResultIds.size === 0) {
6267
+ continue;
6268
+ }
6269
+ const matchedToolCalls = message.toolCalls.filter(
6270
+ (toolCall) => matchedResultIds.has(toolCall.toolCallId)
6271
+ );
6272
+ const matchedToolResults = nextMessage.toolResults.filter(
6273
+ (toolResult) => matchedResultIds.has(toolResult.toolCallId)
6274
+ );
6275
+ sanitized.push(
6276
+ matchedToolCalls.length === message.toolCalls.length ? message : { ...message, toolCalls: matchedToolCalls }
6277
+ );
6278
+ sanitized.push(
6279
+ matchedToolResults.length === nextMessage.toolResults.length ? nextMessage : { ...nextMessage, toolResults: matchedToolResults }
6280
+ );
6281
+ index += 1;
6282
+ continue;
6283
+ }
6284
+ if (this.isToolResultMessage(message)) {
6285
+ continue;
6286
+ }
6287
+ sanitized.push(message);
6288
+ }
6289
+ return sanitized;
6290
+ }
6291
+ /**
6292
+ * Keep replay trimming on a pair boundary. If the trim cut would start on a
6293
+ * tool-result message, slide back to include the matching assistant tool call.
6294
+ */
6295
+ trimReplayHistoryMessages(messages, maxMessages) {
6296
+ if (messages.length <= maxMessages) {
6297
+ return {
6298
+ historyMessages: messages,
6299
+ trimmedCount: 0
6300
+ };
6301
+ }
6302
+ let startIndex = messages.length - maxMessages;
6303
+ while (startIndex > 0 && messages[startIndex]?.role === "tool") {
6304
+ startIndex -= 1;
6305
+ }
6306
+ return {
6307
+ historyMessages: messages.slice(startIndex),
6308
+ trimmedCount: startIndex
6309
+ };
6310
+ }
6242
6311
  /**
6243
6312
  * Build messages for a session, injecting progress context for continuation sessions.
6244
6313
  * Optionally accepts continuation context for marathon resume scenarios.
@@ -6341,6 +6410,9 @@ Do NOT redo any of the above work.`
6341
6410
  const candidateBlock = wf.buildCandidateBlock?.(state) ?? "";
6342
6411
  const multiSessionInstruction = `This is a multi-session task (session ${sessionIndex + 1}/${maxSessions}). When you have fully completed the task, end your response with TASK_COMPLETE on its own line.`;
6343
6412
  if (continuationContext && sessionIndex === 0) {
6413
+ const replayHistoryMessages = this.sanitizeReplayHistoryMessages(
6414
+ continuationContext.previousMessages
6415
+ );
6344
6416
  const defaultContinueMessage = "Continue the task. Review your prior work above and proceed with any remaining work. If everything is already complete, respond with TASK_COMPLETE.";
6345
6417
  const userMessage = continuationContext.newUserMessage || defaultContinueMessage;
6346
6418
  const userContent = [
@@ -6353,7 +6425,7 @@ Do NOT redo any of the above work.`
6353
6425
  multiSessionInstruction
6354
6426
  ].join("\n");
6355
6427
  const fullHistoryMessages = [
6356
- ...continuationContext.previousMessages,
6428
+ ...replayHistoryMessages,
6357
6429
  {
6358
6430
  role: "system",
6359
6431
  content: "IMPORTANT: You are continuing a previously completed task. The conversation above shows your prior work. Do NOT redo any of it. Build on what was already accomplished. If there is nothing new to do, respond with TASK_COMPLETE."
@@ -6365,7 +6437,7 @@ Do NOT redo any of the above work.`
6365
6437
  ];
6366
6438
  const summaryText = this.generateCompactSummary(state, compactInstructions);
6367
6439
  const breakdown = this.buildContextBudgetBreakdown({
6368
- historyMessages: continuationContext.previousMessages,
6440
+ historyMessages: replayHistoryMessages,
6369
6441
  currentTurnContent: userContent,
6370
6442
  localTools: compactionOptions?.localTools,
6371
6443
  builtinToolSchemas: compactionOptions?.builtinToolSchemas || [],
@@ -6455,16 +6527,19 @@ Do NOT redo any of the above work.`
6455
6527
  "Do not redo previous work. If the task is already complete, respond with TASK_COMPLETE."
6456
6528
  ].join("\n");
6457
6529
  const MAX_HISTORY_MESSAGES = 60;
6458
- let historyMessages = state.messages;
6530
+ let historyMessages = this.sanitizeReplayHistoryMessages(state.messages);
6459
6531
  if (historyMessages.length > MAX_HISTORY_MESSAGES) {
6460
- const trimmedCount = historyMessages.length - MAX_HISTORY_MESSAGES;
6461
- historyMessages = [
6462
- {
6463
- role: "system",
6464
- content: `[${trimmedCount} earlier messages trimmed to stay within context limits. Original task: ${(state.originalMessage || originalMessage).slice(0, 500)}]`
6465
- },
6466
- ...historyMessages.slice(-MAX_HISTORY_MESSAGES)
6467
- ];
6532
+ const trimmedHistory = this.trimReplayHistoryMessages(historyMessages, MAX_HISTORY_MESSAGES);
6533
+ historyMessages = trimmedHistory.historyMessages;
6534
+ if (trimmedHistory.trimmedCount > 0) {
6535
+ historyMessages = [
6536
+ {
6537
+ role: "system",
6538
+ content: `[${trimmedHistory.trimmedCount} earlier messages trimmed to stay within context limits. Original task: ${(state.originalMessage || originalMessage).slice(0, 500)}]`
6539
+ },
6540
+ ...historyMessages
6541
+ ];
6542
+ }
6468
6543
  }
6469
6544
  const summaryText = this.generateCompactSummary(state, compactInstructions);
6470
6545
  const breakdown = this.buildContextBudgetBreakdown({
@@ -6726,6 +6801,42 @@ var FlowBuilder = class {
6726
6801
  );
6727
6802
  return this;
6728
6803
  }
6804
+ /**
6805
+ * Add a crawl step
6806
+ */
6807
+ crawl(config) {
6808
+ this.addStep(
6809
+ "crawl",
6810
+ config.name,
6811
+ {
6812
+ url: config.url,
6813
+ limit: config.limit,
6814
+ depth: config.depth,
6815
+ source: config.source,
6816
+ formats: config.formats,
6817
+ render: config.render,
6818
+ maxAge: config.maxAge,
6819
+ modifiedSince: config.modifiedSince,
6820
+ options: config.options,
6821
+ authenticate: config.authenticate,
6822
+ cookies: config.cookies,
6823
+ setExtraHTTPHeaders: config.setExtraHTTPHeaders,
6824
+ gotoOptions: config.gotoOptions,
6825
+ waitForSelector: config.waitForSelector,
6826
+ rejectResourceTypes: config.rejectResourceTypes,
6827
+ rejectRequestPattern: config.rejectRequestPattern,
6828
+ userAgent: config.userAgent,
6829
+ jsonOptions: config.jsonOptions,
6830
+ outputVariable: config.outputVariable,
6831
+ errorHandling: config.errorHandling,
6832
+ streamOutput: config.streamOutput,
6833
+ pollIntervalMs: config.pollIntervalMs,
6834
+ completionTimeoutMs: config.completionTimeoutMs
6835
+ },
6836
+ config.enabled
6837
+ );
6838
+ return this;
6839
+ }
6729
6840
  /**
6730
6841
  * Add a fetch URL step
6731
6842
  */
@@ -7068,7 +7179,7 @@ var ClientFlowBuilder = class extends FlowBuilder {
7068
7179
  this.boundClient = client;
7069
7180
  this.createFlow({ name });
7070
7181
  }
7071
- async run(arg1, arg2, arg3, arg4) {
7182
+ async run(arg1, arg2, arg3, _arg4) {
7072
7183
  const config = this.build();
7073
7184
  let runOptions;
7074
7185
  let runCallbacks;