@rowan-agent/agent 0.19.2 → 0.20.1

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 (3) hide show
  1. package/dist/index.d.ts +822 -808
  2. package/dist/index.js +63 -14
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1378,7 +1378,7 @@ var LoopGuard = {
1378
1378
  // src/loop/stream-collector.ts
1379
1379
  var MAX_STREAMED_OUTPUT_CHARACTERS = 1024 * 1024;
1380
1380
  async function invokeModel(input) {
1381
- const callContext = input.callContext ?? {
1381
+ const baseContext = input.callContext ?? {
1382
1382
  signal: input.config.signal ?? new AbortController().signal,
1383
1383
  run: {
1384
1384
  id: input.config.execution.runId,
@@ -1413,8 +1413,23 @@ async function invokeModel(input) {
1413
1413
  }
1414
1414
  }
1415
1415
  };
1416
+ const position = { contentIndex: 0 };
1417
+ const callContext = {
1418
+ ...baseContext,
1419
+ tools: {
1420
+ ...baseContext.tools,
1421
+ report: (update) => {
1422
+ input.config.onToolReport?.({
1423
+ runId: input.config.execution.runId,
1424
+ update,
1425
+ contentIndex: position.contentIndex
1426
+ });
1427
+ }
1428
+ }
1429
+ };
1416
1430
  const events = input.config.stream(input.request, callContext);
1417
1431
  const result = await collectStreamResult({
1432
+ position,
1418
1433
  config: input.config,
1419
1434
  message: input.message,
1420
1435
  events,
@@ -1455,6 +1470,7 @@ async function collectStreamResult(input) {
1455
1470
  const toolNames = /* @__PURE__ */ new Map();
1456
1471
  const toolArguments = /* @__PURE__ */ new Map();
1457
1472
  for await (const event of input.events) {
1473
+ if ("partial" in event) input.position.contentIndex = event.partial.contentBlocks.length;
1458
1474
  if (event.type === "text_delta") {
1459
1475
  streamedOutputCharacters += event.text.length;
1460
1476
  } else if (event.type === "thinking_delta") {
@@ -2680,6 +2696,16 @@ function serializeSkills(skills) {
2680
2696
  function conversationMessages(messages) {
2681
2697
  return messages.flatMap((message) => {
2682
2698
  if (message.role === "user") {
2699
+ if (message.contexts && message.contexts.length > 0) {
2700
+ const turnContextText = `<turn_context>
2701
+ ${buildContextDescription(message.contexts)}
2702
+ </turn_context>`;
2703
+ const contentParts = [
2704
+ { type: "text", text: turnContextText },
2705
+ ...typeof message.content === "string" ? [{ type: "text", text: message.content }] : message.content
2706
+ ];
2707
+ return [{ role: "user", content: contentParts }];
2708
+ }
2683
2709
  return [{ role: "user", content: message.content }];
2684
2710
  }
2685
2711
  if (message.role === "assistant") {
@@ -2714,6 +2740,7 @@ function buildModelRequest(input, options) {
2714
2740
  return {
2715
2741
  model: options?.model ?? { provider: "", id: "" },
2716
2742
  ...options?.thinkingLevel === void 0 ? {} : { thinkingLevel: options.thinkingLevel },
2743
+ ...options?.providerOptions === void 0 ? {} : { providerOptions: options.providerOptions },
2717
2744
  system: systemText,
2718
2745
  messages,
2719
2746
  tools: modelTools.length > 0 ? modelTools : void 0
@@ -3721,7 +3748,8 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
3721
3748
  appendSystemPrompt: phaseContext.appendSystemPrompt
3722
3749
  }, {
3723
3750
  model: phase.model ?? config.model,
3724
- ...config.thinkingLevel === void 0 ? {} : { thinkingLevel: config.thinkingLevel }
3751
+ ...config.thinkingLevel === void 0 ? {} : { thinkingLevel: config.thinkingLevel },
3752
+ ...config.providerOptions === void 0 ? {} : { providerOptions: config.providerOptions }
3725
3753
  });
3726
3754
  if (!request.tools) {
3727
3755
  if (phaseContext.tools.length > 0) {
@@ -4061,6 +4089,7 @@ async function executeOnce(input) {
4061
4089
  execution: input.execution,
4062
4090
  model: input.model,
4063
4091
  ...input.thinkingLevel === void 0 ? {} : { thinkingLevel: input.thinkingLevel },
4092
+ ...input.providerOptions === void 0 ? {} : { providerOptions: input.providerOptions },
4064
4093
  stream: input.stream,
4065
4094
  maxAttempts: input.maxAttempts,
4066
4095
  signal: input.signal,
@@ -4224,6 +4253,9 @@ var THINKING_LEVELS = [
4224
4253
  function thinkingLevelFromUserInput(input) {
4225
4254
  return typeof input === "string" ? void 0 : input.thinkingLevel;
4226
4255
  }
4256
+ function providerOptionsFromUserInput(input) {
4257
+ return typeof input === "string" ? void 0 : input.providerOptions;
4258
+ }
4227
4259
  var METADATA_LIMIT = 64 * 1024;
4228
4260
  var IDENTITY_LIMIT = 256;
4229
4261
  function isRecord3(value) {
@@ -4278,13 +4310,16 @@ function isAssistantContent(value) {
4278
4310
  }
4279
4311
  function normalizeUserInput(input) {
4280
4312
  const normalized = typeof input === "string" ? { content: input } : input;
4281
- if (!isRecord3(normalized) || !hasOnlyKeys(normalized, ["content", "metadata", "thinkingLevel"]) || !isUserContent(normalized.content)) {
4313
+ if (!isRecord3(normalized) || !hasOnlyKeys(normalized, ["content", "metadata", "thinkingLevel", "providerOptions"]) || !isUserContent(normalized.content)) {
4282
4314
  throw new TypeError("input must contain only valid UserContent");
4283
4315
  }
4284
4316
  if (normalized.metadata !== void 0) assertMetadata(normalized.metadata, "input.metadata");
4285
4317
  if (normalized.thinkingLevel !== void 0 && !THINKING_LEVELS.includes(normalized.thinkingLevel)) {
4286
4318
  throw new TypeError("input.thinkingLevel must be a valid ThinkingLevel");
4287
4319
  }
4320
+ if (normalized.providerOptions !== void 0 && (!isRecord3(normalized.providerOptions) || !isJsonValue(normalized.providerOptions))) {
4321
+ throw new TypeError("input.providerOptions must be a JSON object");
4322
+ }
4288
4323
  assertJsonValue(normalized, "input");
4289
4324
  return normalized;
4290
4325
  }
@@ -5015,7 +5050,14 @@ function durableInterruptedAssistantContent(content) {
5015
5050
  function projectMessage(message) {
5016
5051
  switch (message.role) {
5017
5052
  case "user":
5018
- return { id: message.id, role: message.role, content: projectUserContent(message.content), createdAt: message.createdAt, ...message.metadata ? { metadata: message.metadata } : {} };
5053
+ return {
5054
+ id: message.id,
5055
+ role: message.role,
5056
+ content: projectUserContent(message.content),
5057
+ createdAt: message.createdAt,
5058
+ ...message.metadata ? { metadata: message.metadata } : {},
5059
+ ...message.contexts && message.contexts.length > 0 ? { contexts: message.contexts } : {}
5060
+ };
5019
5061
  case "assistant":
5020
5062
  return { id: message.id, role: message.role, content: projectAssistantContent(message.content), createdAt: message.createdAt, ...message.metadata ? { metadata: message.metadata } : {} };
5021
5063
  case "tool":
@@ -5200,10 +5242,7 @@ function resolveDefinitionContext(snapshot, assembled) {
5200
5242
  selectNamedResources(snapshot.resources.skills, snapshot.definition.skills, "Skill"),
5201
5243
  snapshot.definition.bundledSkills
5202
5244
  );
5203
- const contexts = [
5204
- ...selectNamedResources(snapshot.contexts, snapshot.definition.contexts, "Context"),
5205
- ...snapshot.additionalContexts
5206
- ];
5245
+ const contexts = selectNamedResources(snapshot.contexts, snapshot.definition.contexts, "Context");
5207
5246
  const phaseCandidates = [...snapshot.resources.phases?.phases.values() ?? []];
5208
5247
  const corePhases = phaseCandidates.filter((phase) => phase.core);
5209
5248
  const authoredPhases = phaseCandidates.filter((phase) => !phase.core);
@@ -7864,7 +7903,8 @@ var AgentRuntime = class _AgentRuntime {
7864
7903
  runId: run.id,
7865
7904
  expectedRevision: run.revision,
7866
7905
  executionId,
7867
- configToken: token
7906
+ configToken: token,
7907
+ ...config.additionalContexts && config.additionalContexts.length > 0 ? { additionalContexts: config.additionalContexts } : {}
7868
7908
  });
7869
7909
  executionRevision = claim.run.revision;
7870
7910
  const controller = new AbortController();
@@ -7937,6 +7977,7 @@ var AgentRuntime = class _AgentRuntime {
7937
7977
  },
7938
7978
  model,
7939
7979
  thinkingLevel: thinkingLevelFromUserInput(run.input),
7980
+ providerOptions: providerOptionsFromUserInput(run.input),
7940
7981
  stream,
7941
7982
  maxAttempts: config.maxAttempts,
7942
7983
  checkpoint: claim.run.checkpoint,
@@ -8087,7 +8128,8 @@ var AgentRuntime = class _AgentRuntime {
8087
8128
  executionId: claim.execution.executionId,
8088
8129
  transition: { from: null, to: event.update.status ?? "in_progress" },
8089
8130
  toolCall: event.update,
8090
- external: true
8131
+ external: true,
8132
+ ...event.contentIndex === void 0 ? {} : { contentIndex: event.contentIndex }
8091
8133
  });
8092
8134
  const task = toolQueue.then(async () => {
8093
8135
  const active2 = this.executions.get(run.id);
@@ -8096,7 +8138,8 @@ var AgentRuntime = class _AgentRuntime {
8096
8138
  runId: run.id,
8097
8139
  execution: claim.execution,
8098
8140
  update: event.update,
8099
- external: true
8141
+ external: true,
8142
+ ...event.contentIndex === void 0 ? {} : { contentIndex: event.contentIndex }
8100
8143
  });
8101
8144
  executionRevision = recorded.runRevision;
8102
8145
  });
@@ -10093,7 +10136,8 @@ var InMemoryStore = class _InMemoryStore {
10093
10136
  input.runId,
10094
10137
  input.expectedRevision,
10095
10138
  input.messageId ?? null,
10096
- input.configToken ?? null
10139
+ input.configToken ?? null,
10140
+ input.additionalContexts ?? null
10097
10141
  ]);
10098
10142
  const replay = this.replayOperation(operationKey, operationPayload);
10099
10143
  if (replay) return clone(replay);
@@ -10113,6 +10157,7 @@ var InMemoryStore = class _InMemoryStore {
10113
10157
  const committedMessages = [];
10114
10158
  if (!run.checkpoint && !run.initialMessageId && (!isControlRun(run) || hasUserInput(run.input))) {
10115
10159
  const userInput = normalizeUserInput(run.input);
10160
+ const turnContexts = input.additionalContexts ?? [];
10116
10161
  const message = {
10117
10162
  id: input.messageId ?? createId("msg"),
10118
10163
  agentId: run.agentId,
@@ -10120,6 +10165,7 @@ var InMemoryStore = class _InMemoryStore {
10120
10165
  role: "user",
10121
10166
  content: userInputContent(userInput),
10122
10167
  ...userInputMetadata(userInput) ? { metadata: clone(userInputMetadata(userInput)) } : {},
10168
+ ...turnContexts.length > 0 ? { contexts: clone(turnContexts) } : {},
10123
10169
  sequenceWithinRun: this.nextMessageSequence(run.id),
10124
10170
  createdAt: createTimestamp()
10125
10171
  };
@@ -10688,6 +10734,7 @@ var InMemoryStore = class _InMemoryStore {
10688
10734
  status: toStatus,
10689
10735
  state: toStatus,
10690
10736
  external: input.external ?? false,
10737
+ ...input.contentIndex === void 0 ? {} : { contentIndex: input.contentIndex },
10691
10738
  createdAt: timestamp,
10692
10739
  updatedAt: timestamp
10693
10740
  };
@@ -10713,7 +10760,8 @@ var InMemoryStore = class _InMemoryStore {
10713
10760
  kind: "tool_state_changed",
10714
10761
  transition: { from: fromStatus, to: toStatus },
10715
10762
  toolCall: acpToolCall,
10716
- ...input.external ? { external: true } : {}
10763
+ ...input.external ? { external: true } : {},
10764
+ ...stored.contentIndex === void 0 ? {} : { contentIndex: stored.contentIndex }
10717
10765
  });
10718
10766
  this.appendEvent(event);
10719
10767
  return event;
@@ -11157,7 +11205,8 @@ ${record.summary}`,
11157
11205
  kind: "tool_state_changed",
11158
11206
  transition,
11159
11207
  toolCall: acpToolCall,
11160
- ...toolCall.external ? { external: true } : {}
11208
+ ...toolCall.external ? { external: true } : {},
11209
+ ...toolCall.contentIndex === void 0 ? {} : { contentIndex: toolCall.contentIndex }
11161
11210
  });
11162
11211
  }
11163
11212
  baseEvent(run, extra) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowan-agent/agent",
3
- "version": "0.19.2",
3
+ "version": "0.20.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,7 +23,7 @@
23
23
  "build": "tsup && bun scripts/check-public-interface.ts"
24
24
  },
25
25
  "dependencies": {
26
- "@rowan-agent/models": "0.8.0",
26
+ "@rowan-agent/models": "0.9.0",
27
27
  "jiti": "2.7.0",
28
28
  "typebox": "^1.0.0",
29
29
  "yaml": "^2.7.0"