@myagentroam/agent 0.10.7 → 0.10.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.
Files changed (52) hide show
  1. package/dist/agent-core/extensions/compaction.d.ts +1 -0
  2. package/dist/agent-core/extensions/model-request.js +1 -1
  3. package/dist/agent-core/extensions/session-messages.d.ts +1 -1
  4. package/dist/agent-core/host/contracts.d.ts +2 -0
  5. package/dist/agent-core/host/local-agent-host.d.ts +2 -0
  6. package/dist/agent-core/host/local-agent-host.js +2 -0
  7. package/dist/agent-core/model/anthropic-messages.js +15 -23
  8. package/dist/agent-core/model/catalog-file.d.ts +14 -0
  9. package/dist/agent-core/model/configuration.d.ts +7 -0
  10. package/dist/agent-core/model/configuration.js +10 -0
  11. package/dist/agent-core/model/contracts.d.ts +8 -0
  12. package/dist/agent-core/model/openai-responses.d.ts +1 -1
  13. package/dist/agent-core/model/openai-responses.js +62 -29
  14. package/dist/agent-core/model/runtime-credential.d.ts +2 -0
  15. package/dist/agent-core/model/runtime-credential.js +15 -0
  16. package/dist/agent-core/model/sse.d.ts +1 -1
  17. package/dist/agent-core/model/sse.js +22 -4
  18. package/dist/agent-core/model/tool-input.d.ts +3 -0
  19. package/dist/agent-core/model/tool-input.js +18 -0
  20. package/dist/agent-core/model/usage-observer.d.ts +31 -0
  21. package/dist/agent-core/model/usage-observer.js +82 -0
  22. package/dist/agent-core/runtime/events.d.ts +2 -0
  23. package/dist/agent-core/sdk/agent.js +9 -1
  24. package/dist/agent-core/sdk/extension-models.d.ts +1 -1
  25. package/dist/agent-core/sdk/extension-models.js +9 -1
  26. package/dist/agent-core/sdk/session.js +31 -3
  27. package/dist/agent-core/session/catalog.d.ts +1 -0
  28. package/dist/agent-core/session/catalog.js +1 -0
  29. package/dist/agent-core/session/jsonl-store.d.ts +9 -0
  30. package/dist/agent-core/session/jsonl-store.js +24 -0
  31. package/dist/agent-core/session/tool-result-resources.d.ts +26 -0
  32. package/dist/agent-core/session/tool-result-resources.js +285 -0
  33. package/dist/agent-core/session/transaction-recovery.js +1 -1
  34. package/dist/agent-core/tools/code-mode/dispatch.js +5 -0
  35. package/dist/agent-core/tools/code-mode/index.js +8 -2
  36. package/dist/agent-core/tools/code-mode/observations.d.ts +1 -0
  37. package/dist/agent-core/tools/contracts.d.ts +2 -0
  38. package/dist/agent-core/tools/execution.js +11 -2
  39. package/dist/agent-core/tools/file-change-diff.d.ts +10 -0
  40. package/dist/agent-core/tools/file-change-diff.js +139 -0
  41. package/dist/agent-core/tools/local/apply-patch.js +19 -8
  42. package/dist/agent-core/tools/result-extensions.d.ts +46 -0
  43. package/dist/agent-core/tools/result-extensions.js +134 -0
  44. package/dist/agent-core/tools/runtime-context.d.ts +1 -0
  45. package/dist/agent-core/tools/runtime.js +6 -3
  46. package/dist/index.d.ts +4 -0
  47. package/dist/index.js +1 -0
  48. package/dist/shared/auto-title.d.ts +2 -0
  49. package/dist/shared/auto-title.js +6 -0
  50. package/dist/shared/model-text.d.ts +2 -0
  51. package/dist/shared/model-text.js +6 -0
  52. package/package.json +1 -1
@@ -4,6 +4,7 @@ import { dirname, isAbsolute, parse, resolve } from 'node:path';
4
4
  import { TextDecoder } from 'node:util';
5
5
  import { MarAgentError } from '../../error.js';
6
6
  import { TOOL_EXECUTION_LIMITS } from '../execution-limits.js';
7
+ import { captureFileChange, reserveFileChangePaths } from '../result-extensions.js';
7
8
  export const applyPatchToolDefinition = {
8
9
  name: 'apply_patch',
9
10
  allowedCallers: ['direct', 'programmatic'],
@@ -70,6 +71,9 @@ export class ApplyPatchTool {
70
71
  }
71
72
  async execute(patch) {
72
73
  const changes = parsePatch(patch);
74
+ reserveFileChangePaths(changes.flatMap((change) => change.kind === 'update' && change.targetPath
75
+ ? [change.path, change.targetPath]
76
+ : [change.path]));
73
77
  const resolvedChanges = await this.#resolveChanges(changes);
74
78
  const results = [];
75
79
  let totalBytes = 0;
@@ -149,7 +153,7 @@ export class ApplyPatchTool {
149
153
  const targetStat = await optionalLstat(resolvedChange.target);
150
154
  if (targetStat && !targetStat.isFile())
151
155
  invalid('Patch targets must be regular files.');
152
- const content = Buffer.from(`${change.lines.join('\n')}\n`);
156
+ const content = Buffer.from(change.lines.length ? `${change.lines.join('\n')}\n` : '');
153
157
  const totalBytes = enforceContentLimits(content, currentTotalBytes);
154
158
  return {
155
159
  mutations: [
@@ -158,7 +162,8 @@ export class ApplyPatchTool {
158
162
  target: resolvedChange.target,
159
163
  content,
160
164
  ...(targetStat ? { mode: targetStat.mode & 0o7777 } : {}),
161
- expectedExisting: targetStat !== undefined
165
+ expectedExisting: targetStat !== undefined,
166
+ ...(targetStat ? { original: await readBoundedFile(resolvedChange.target) } : {})
162
167
  }
163
168
  ],
164
169
  result: {
@@ -178,7 +183,9 @@ export class ApplyPatchTool {
178
183
  if (resolvedChange.kind === 'delete') {
179
184
  const { change } = resolvedChange;
180
185
  return {
181
- mutations: [{ path: change.path, target: resolvedChange.source, expectedExisting: true }],
186
+ mutations: [
187
+ { path: change.path, target: resolvedChange.source, expectedExisting: true, original }
188
+ ],
182
189
  result: {
183
190
  path: change.path,
184
191
  operation: 'deleted',
@@ -204,13 +211,14 @@ export class ApplyPatchTool {
204
211
  invalid('Patch targets must be regular files.');
205
212
  return {
206
213
  mutations: [
207
- { path: change.path, target: resolvedChange.source, expectedExisting: true },
214
+ { path: change.path, target: resolvedChange.source, expectedExisting: true, original },
208
215
  {
209
216
  path: moveChange.targetPath,
210
217
  target: resolvedChange.target,
211
218
  content,
212
219
  mode: (targetStat ?? sourceStat).mode & 0o7777,
213
- expectedExisting: targetStat !== undefined
220
+ expectedExisting: targetStat !== undefined,
221
+ ...(targetStat ? { original: await readBoundedFile(resolvedChange.target) } : {})
214
222
  }
215
223
  ],
216
224
  result: {
@@ -230,7 +238,8 @@ export class ApplyPatchTool {
230
238
  target: resolvedChange.source,
231
239
  content,
232
240
  mode: sourceStat.mode & 0o7777,
233
- expectedExisting: true
241
+ expectedExisting: true,
242
+ original
234
243
  }
235
244
  ],
236
245
  result: {
@@ -267,6 +276,8 @@ export class ApplyPatchTool {
267
276
  const backup = `${mutation.target}.mar-patch-${randomUUID()}.bak`;
268
277
  await this.#fileOperations.rename(mutation.target, backup);
269
278
  backups.push({ target: mutation.target, backup });
279
+ if (mutation.original && !(await readBoundedFile(backup)).equals(mutation.original))
280
+ throw new MarAgentError('MAR_AGENT_PATCH_CONFLICT', 'A patch target changed after preflight.');
270
281
  }
271
282
  for (const item of staged) {
272
283
  await this.#fileOperations.rename(item.temporary, item.target);
@@ -291,6 +302,8 @@ export class ApplyPatchTool {
291
302
  throw error;
292
303
  }
293
304
  await Promise.all(backups.map((item) => this.#fileOperations.rm(item.backup, { force: true })));
305
+ for (const mutation of mutations)
306
+ await captureFileChange(mutation.path, mutation.original, mutation.content);
294
307
  }
295
308
  }
296
309
  function parsePatch(patch) {
@@ -331,8 +344,6 @@ function parsePatch(patch) {
331
344
  invalid('Added file lines must start with +.');
332
345
  content.push(line.slice(1));
333
346
  }
334
- if (!content.length)
335
- invalid('Added files must contain at least one patch line.');
336
347
  changes.push({ kind: 'add', path, lines: content });
337
348
  }
338
349
  else if (header.startsWith('*** Delete File: ')) {
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ import type { ToolExecutionResult } from './contracts.js';
3
+ export declare const fileChangesExtensionSchema: z.ZodObject<{
4
+ type: z.ZodLiteral<"file_changes">;
5
+ version: z.ZodLiteral<1>;
6
+ entries: z.ZodArray<z.ZodObject<{
7
+ changeId: z.ZodString;
8
+ path: z.ZodString;
9
+ change: z.ZodEnum<{
10
+ added: "added";
11
+ modified: "modified";
12
+ deleted: "deleted";
13
+ }>;
14
+ additions: z.ZodNullable<z.ZodNumber>;
15
+ deletions: z.ZodNullable<z.ZodNumber>;
16
+ diff: z.ZodDiscriminatedUnion<[z.ZodObject<{
17
+ status: z.ZodLiteral<"available">;
18
+ resourceRef: z.ZodString;
19
+ format: z.ZodLiteral<"unified-diff">;
20
+ byteSize: z.ZodNumber;
21
+ sha256: z.ZodString;
22
+ }, z.core.$strip>, z.ZodObject<{
23
+ status: z.ZodLiteral<"unavailable">;
24
+ reason: z.ZodEnum<{
25
+ "unsupported-content": "unsupported-content";
26
+ "limit-exceeded": "limit-exceeded";
27
+ "capture-failed": "capture-failed";
28
+ "storage-failed": "storage-failed";
29
+ }>;
30
+ }, z.core.$strip>], "status">;
31
+ }, z.core.$strip>>;
32
+ }, z.core.$strip>;
33
+ export type ToolResultExtension = z.infer<typeof fileChangesExtensionSchema>;
34
+ export type FileChangeEvidence = ToolResultExtension['entries'][number];
35
+ export type AvailableToolResultResource = Extract<FileChangeEvidence['diff'], {
36
+ status: 'available';
37
+ }>;
38
+ export type ToolResultResourceWriter = (text: string) => Promise<AvailableToolResultResource>;
39
+ export declare function parseToolResultExtensions(value: unknown): ToolResultExtension[] | undefined;
40
+ export declare function failedToolResultExtensions(error: unknown): ToolResultExtension[] | undefined;
41
+ /** Reserve a complete invocation's descriptors before any leaf commits, including wrapped calls. */
42
+ export declare function reserveFileChangePaths(paths: readonly string[]): void;
43
+ /** Only the SDK's real file commit calls this producer; arbitrary result fields are ignored. */
44
+ export declare function captureFileChange(path: string, before?: Buffer, after?: Buffer): Promise<void>;
45
+ /** Own a physical invocation, including all real leaf effects retained across wrappers. */
46
+ export declare function withToolResultExtensions(write: ToolResultResourceWriter | undefined, run: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>;
@@ -0,0 +1,134 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { MarAgentError } from '../error.js';
4
+ import { z } from 'zod';
5
+ import { createFileDiff, FileDiffLimitError } from './file-change-diff.js';
6
+ const diffSchema = z.discriminatedUnion('status', [
7
+ z.object({
8
+ status: z.literal('available'),
9
+ resourceRef: z.string().uuid(),
10
+ format: z.literal('unified-diff'),
11
+ byteSize: z
12
+ .number()
13
+ .int()
14
+ .nonnegative()
15
+ .max(16 * 1024 * 1024),
16
+ sha256: z.string().regex(/^[a-f0-9]{64}$/u)
17
+ }),
18
+ z.object({
19
+ status: z.literal('unavailable'),
20
+ reason: z.enum(['unsupported-content', 'limit-exceeded', 'capture-failed', 'storage-failed'])
21
+ })
22
+ ]);
23
+ export const fileChangesExtensionSchema = z.object({
24
+ type: z.literal('file_changes'),
25
+ version: z.literal(1),
26
+ entries: z
27
+ .array(z.object({
28
+ changeId: z.string().uuid(),
29
+ path: z.string().min(1).max(8192),
30
+ change: z.enum(['added', 'modified', 'deleted']),
31
+ additions: z.number().int().nonnegative().nullable(),
32
+ deletions: z.number().int().nonnegative().nullable(),
33
+ diff: diffSchema
34
+ }))
35
+ .max(200)
36
+ });
37
+ export function parseToolResultExtensions(value) {
38
+ if (!Array.isArray(value) || value.length > 16)
39
+ return undefined;
40
+ const extensions = [];
41
+ const ids = new Set();
42
+ for (const input of value) {
43
+ const parsed = fileChangesExtensionSchema.safeParse(input);
44
+ if (!parsed.success || extensions.some((entry) => entry.type === parsed.data.type))
45
+ continue;
46
+ if (new Set(parsed.data.entries.map((entry) => entry.changeId)).size !==
47
+ parsed.data.entries.length ||
48
+ parsed.data.entries.some((entry) => ids.has(entry.changeId)))
49
+ continue;
50
+ parsed.data.entries.forEach((entry) => ids.add(entry.changeId));
51
+ extensions.push(parsed.data);
52
+ }
53
+ return extensions.length && Buffer.byteLength(JSON.stringify(extensions)) <= 1024 * 1024
54
+ ? extensions
55
+ : undefined;
56
+ }
57
+ const capture = new AsyncLocalStorage();
58
+ const failures = new WeakMap();
59
+ export function failedToolResultExtensions(error) {
60
+ return error !== null && typeof error === 'object' ? failures.get(error) : undefined;
61
+ }
62
+ /** Reserve a complete invocation's descriptors before any leaf commits, including wrapped calls. */
63
+ export function reserveFileChangePaths(paths) {
64
+ const context = capture.getStore();
65
+ const entries = (context?.reservedEntries ?? 0) + paths.length;
66
+ const bytes = (context?.descriptorBytes ?? 256) +
67
+ paths.reduce((sum, path) => sum + Buffer.byteLength(JSON.stringify(path)) + 512, 0);
68
+ if (entries > 200 || bytes > 1024 * 1024 || paths.some((path) => path.length > 8192))
69
+ throw new MarAgentError('MAR_AGENT_TOOL_OUTPUT_LIMIT', 'Patch paths exceed the file evidence descriptor limit.');
70
+ if (context) {
71
+ context.reservedEntries = entries;
72
+ context.descriptorBytes = bytes;
73
+ }
74
+ }
75
+ /** Only the SDK's real file commit calls this producer; arbitrary result fields are ignored. */
76
+ export async function captureFileChange(path, before, after) {
77
+ const context = capture.getStore();
78
+ if (!context)
79
+ return;
80
+ const entry = {
81
+ changeId: randomUUID(),
82
+ path,
83
+ change: before === undefined ? 'added' : after === undefined ? 'deleted' : 'modified',
84
+ additions: null,
85
+ deletions: null,
86
+ diff: { status: 'unavailable', reason: 'capture-failed' }
87
+ };
88
+ context.entries.push(entry);
89
+ try {
90
+ const diff = createFileDiff(path, before, after);
91
+ if (!diff) {
92
+ entry.diff = { status: 'unavailable', reason: 'unsupported-content' };
93
+ return;
94
+ }
95
+ entry.additions = diff.additions;
96
+ entry.deletions = diff.deletions;
97
+ context.bytes += Buffer.byteLength(diff.text);
98
+ if (context.bytes > 32 * 1024 * 1024)
99
+ entry.diff = { status: 'unavailable', reason: 'limit-exceeded' };
100
+ else if (context.write)
101
+ entry.diff = await context.write(diff.text);
102
+ else
103
+ entry.diff = { status: 'unavailable', reason: 'storage-failed' };
104
+ }
105
+ catch (error) {
106
+ entry.diff = {
107
+ status: 'unavailable',
108
+ reason: error instanceof FileDiffLimitError ? 'limit-exceeded' : 'storage-failed'
109
+ };
110
+ }
111
+ }
112
+ /** Own a physical invocation, including all real leaf effects retained across wrappers. */
113
+ export async function withToolResultExtensions(write, run) {
114
+ const context = {
115
+ entries: [],
116
+ bytes: 0,
117
+ reservedEntries: 0,
118
+ descriptorBytes: 256,
119
+ ...(write ? { write } : {})
120
+ };
121
+ return capture.run(context, async () => {
122
+ const extensions = () => parseToolResultExtensions([{ type: 'file_changes', version: 1, entries: context.entries }]);
123
+ try {
124
+ const { resultExtensions: _ignored, ...result } = await run();
125
+ const resultExtensions = context.entries.length ? extensions() : undefined;
126
+ return resultExtensions ? { ...result, resultExtensions } : result;
127
+ }
128
+ catch (error) {
129
+ if (context.entries.length && error !== null && typeof error === 'object')
130
+ failures.set(error, extensions());
131
+ throw error;
132
+ }
133
+ });
134
+ }
@@ -46,6 +46,7 @@ export interface ToolRuntimeContext {
46
46
  executionId: string;
47
47
  modelId?: string;
48
48
  signal: AbortSignal;
49
+ writeToolResultResource?: import('./result-extensions.js').ToolResultResourceWriter;
49
50
  codeMode?: import('./contracts.js').ToolExecutionContext['codeMode'];
50
51
  skills: ReadonlyMap<string, AgentSkill>;
51
52
  recentImages?: readonly ToolRuntimeImage[];
@@ -3,10 +3,13 @@ import { randomUUID } from 'node:crypto';
3
3
  import { AGENT_TOOL_HANDLERS, BUILTIN_TOOL_DEFINITIONS } from './registry.js';
4
4
  import { normalizeToolInput } from './input.js';
5
5
  import { validateToolResult } from './output-projection.js';
6
+ import { withToolResultExtensions } from './result-extensions.js';
6
7
  export async function executeRegisteredTool(name, arguments_, callId, context, caller = 'direct') {
7
- if (context.invokeTool)
8
- return validateToolResult(await context.invokeTool({ name, arguments: arguments_, callId }, context, caller));
9
- return validateToolResult(await executeCapturedTool(AGENT_TOOL_HANDLERS.has(name) ? 'builtin' : name.startsWith('mcp__') ? 'mcp' : 'host', { name, arguments: arguments_, callId }, context));
8
+ return withToolResultExtensions(context.writeToolResultResource, async () => {
9
+ if (context.invokeTool)
10
+ return validateToolResult(await context.invokeTool({ name, arguments: arguments_, callId }, context, caller));
11
+ return validateToolResult(await executeCapturedTool(AGENT_TOOL_HANDLERS.has(name) ? 'builtin' : name.startsWith('mcp__') ? 'mcp' : 'host', { name, arguments: arguments_, callId }, context));
12
+ });
10
13
  }
11
14
  /** Invoke an already captured source; names never reselect a different backend. */
12
15
  export async function executeCapturedTool(kind, call, context) {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  export { MarAgentError } from './agent-core/error.js';
2
2
  export { MAR_AGENT_HOST_API_VERSION, negotiateHost, type HostDescription, type MarAgentHostCapability } from './agent-core/host/contracts.js';
3
+ export type { ToolResultExtension, FileChangeEvidence } from './agent-core/tools/result-extensions.js';
4
+ export { parseToolResultExtensions } from './agent-core/tools/result-extensions.js';
5
+ export type { ToolResultResourceInput, ToolResultResourcePage } from './agent-core/session/tool-result-resources.js';
3
6
  export type { HostExecutionExtensions, HostSessionResourceSnapshot, HostSkill, MarAgentHost } from './agent-core/host/contracts.js';
4
7
  export { LocalAgentHost, selectExecutionShell, type LocalAgentExecutionExtensions, type LocalAgentExecutionMcpBinding, type LocalAgentMcpBinding } from './agent-core/host/local-agent-host.js';
5
8
  export type { LocalProcessExecutor, LocalProcessSpawnRequest } from './agent-core/host/local-process-executor.js';
@@ -41,3 +44,4 @@ export type { ApplyPatchFileResult, ApplyPatchResult, ApplyPatchPartialResult, C
41
44
  export { MCP_DEFINITION_LIMITS, assertMcpToolCatalog, assertMcpToolDefinition } from './agent-core/tools/mcp/catalog.js';
42
45
  export type { WorkspacePathMount } from './agent-core/tools/shared/path-resolver.js';
43
46
  export type { CodeModeEngine, CodeModeEngineFactory, CreateCodeModeEngine } from './agent-core/tools/code-mode/engine.js';
47
+ export type { ModelRequestUsage, ModelUsageObservation, ModelUsageObserver } from './agent-core/model/usage-observer.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { MarAgentError } from './agent-core/error.js';
2
2
  export { MAR_AGENT_HOST_API_VERSION, negotiateHost } from './agent-core/host/contracts.js';
3
+ export { parseToolResultExtensions } from './agent-core/tools/result-extensions.js';
3
4
  export { LocalAgentHost, selectExecutionShell } from './agent-core/host/local-agent-host.js';
4
5
  export { SecretValue, marAgentReasoningEffortSchema, parseModelCatalog, resolveModelDefaultReasoningEffort } from './agent-core/model/configuration.js';
5
6
  export { testMarAgentModelTransport } from './agent-core/model/transport-test.js';
@@ -1,5 +1,7 @@
1
1
  import { type MarAgentModelConfiguration } from '../agent-core/model/configuration.js';
2
2
  export interface GenerateSessionTitleInput {
3
+ readonly onModelUsage?: (usage: import('../agent-core/model/usage-observer.js').ModelRequestUsage) => Promise<void> | void;
4
+ readonly onModelUsageFailure?: () => void;
3
5
  readonly models: readonly MarAgentModelConfiguration[];
4
6
  readonly currentModelId: string;
5
7
  readonly prompt: string;
@@ -1,3 +1,4 @@
1
+ import { randomUUID } from 'node:crypto';
1
2
  import { MarAgentError } from '../agent-core/error.js';
2
3
  import { AnthropicMessagesAdapter } from '../agent-core/model/anthropic-messages.js';
3
4
  import { resolveModelDefaultReasoningEffort } from '../agent-core/model/configuration.js';
@@ -38,6 +39,11 @@ export async function generateSessionTitle(input) {
38
39
  try {
39
40
  for await (const event of adapter.start({
40
41
  retryState: { attempts: 0, maxAttempts: 1 },
42
+ usageRequestId: randomUUID(),
43
+ ...(input.onModelUsage === undefined ? {} : { onModelUsage: input.onModelUsage }),
44
+ ...(input.onModelUsageFailure === undefined
45
+ ? {}
46
+ : { onModelUsageFailure: input.onModelUsageFailure }),
41
47
  system: defaultLanguage
42
48
  ? `${sessionTitlePrompt}\n- If the user message does not establish a language, use ${JSON.stringify(defaultLanguage)} as the default language.`
43
49
  : sessionTitlePrompt,
@@ -2,6 +2,8 @@ import { type MarAgentModelConfiguration, type MarAgentReasoningEffort } from '.
2
2
  import type { ModelAttemptDiagnostic, ModelUsage } from '../agent-core/model/contracts.js';
3
3
  import type { CoreCompactMessage } from '../agent-core/extensions/compaction.js';
4
4
  export interface GenerateModelTextInput {
5
+ readonly onModelUsage?: (usage: import('../agent-core/model/usage-observer.js').ModelRequestUsage) => Promise<void> | void;
6
+ readonly onModelUsageFailure?: () => void;
5
7
  readonly model: MarAgentModelConfiguration;
6
8
  readonly system: string;
7
9
  readonly messages: readonly CoreCompactMessage[];
@@ -1,3 +1,4 @@
1
+ import { randomUUID } from 'node:crypto';
1
2
  import { MarAgentError } from '../agent-core/error.js';
2
3
  import { AnthropicMessagesAdapter } from '../agent-core/model/anthropic-messages.js';
3
4
  import { OpenAiResponsesAdapter } from '../agent-core/model/openai-responses.js';
@@ -16,6 +17,11 @@ export async function generateModelText(input) {
16
17
  try {
17
18
  for await (const event of adapter.start({
18
19
  retryState: { attempts: 0, maxAttempts: 1 },
20
+ usageRequestId: randomUUID(),
21
+ ...(input.onModelUsage === undefined ? {} : { onModelUsage: input.onModelUsage }),
22
+ ...(input.onModelUsageFailure === undefined
23
+ ? {}
24
+ : { onModelUsageFailure: input.onModelUsageFailure }),
19
25
  system: input.system,
20
26
  messages: input.messages,
21
27
  tools: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/agent",
3
- "version": "0.10.7",
3
+ "version": "0.10.9",
4
4
  "description": "Embeddable MAR coding agent SDK and CLI.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",