@myagentroam/agent 0.11.21 → 0.11.22
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/agent-core/error.d.ts +1 -1
- package/dist/agent-core/error.js +20 -14
- package/dist/agent-core/extensions/compaction.d.ts +6 -0
- package/dist/agent-core/extensions/compaction.js +16 -2
- package/dist/agent-core/extensions/model-request.d.ts +5 -9
- package/dist/agent-core/extensions/model-request.js +14 -3
- package/dist/agent-core/extensions/prompt-input.js +3 -1
- package/dist/agent-core/host/contracts.d.ts +8 -0
- package/dist/agent-core/host/local-agent-host.d.ts +2 -0
- package/dist/agent-core/host/local-agent-host.js +3 -0
- package/dist/agent-core/model/anthropic-messages.js +15 -26
- package/dist/agent-core/model/catalog-file.d.ts +2 -0
- package/dist/agent-core/model/configuration.d.ts +3 -1
- package/dist/agent-core/model/configuration.js +1 -0
- package/dist/agent-core/model/contracts.d.ts +5 -8
- package/dist/agent-core/model/image.d.ts +17 -0
- package/dist/agent-core/model/image.js +53 -0
- package/dist/agent-core/model/openai-responses.d.ts +7 -2
- package/dist/agent-core/model/openai-responses.js +81 -27
- package/dist/agent-core/runtime/compaction/retained-context.js +2 -9
- package/dist/agent-core/runtime/context/gc-runtime.d.ts +3 -1
- package/dist/agent-core/runtime/context/gc-runtime.js +17 -6
- package/dist/agent-core/runtime/context/gc-tokens.js +13 -0
- package/dist/agent-core/runtime/context/gc.d.ts +2 -1
- package/dist/agent-core/runtime/context/gc.js +75 -12
- package/dist/agent-core/runtime/context/projection.js +4 -0
- package/dist/agent-core/runtime/context/request-budget.d.ts +2 -4
- package/dist/agent-core/runtime/context/restore.d.ts +2 -0
- package/dist/agent-core/runtime/context/restore.js +19 -3
- package/dist/agent-core/runtime/contracts.d.ts +2 -3
- package/dist/agent-core/runtime/execution.d.ts +1 -1
- package/dist/agent-core/runtime/execution.js +10 -4
- package/dist/agent-core/runtime/resource-publication.d.ts +8 -0
- package/dist/agent-core/runtime/resource-publication.js +60 -0
- package/dist/agent-core/sdk/agent.js +16 -0
- package/dist/agent-core/sdk/model-runtime.js +2 -0
- package/dist/agent-core/sdk/resource-input.d.ts +31 -0
- package/dist/agent-core/sdk/resource-input.js +342 -0
- package/dist/agent-core/sdk/session.js +144 -39
- package/dist/agent-core/session/catalog.d.ts +4 -0
- package/dist/agent-core/session/catalog.js +4 -0
- package/dist/agent-core/session/context-gc-checkpoint.d.ts +6 -4
- package/dist/agent-core/session/context-gc-checkpoint.js +41 -16
- package/dist/agent-core/session/inline-media.d.ts +45 -0
- package/dist/agent-core/session/inline-media.js +163 -0
- package/dist/agent-core/session/store/contracts.d.ts +11 -0
- package/dist/agent-core/session/store/history.d.ts +1 -1
- package/dist/agent-core/session/store/history.js +26 -2
- package/dist/agent-core/session/store/images.d.ts +4 -6
- package/dist/agent-core/session/store/images.js +18 -111
- package/dist/agent-core/session/store/jsonl-store.d.ts +9 -0
- package/dist/agent-core/session/store/jsonl-store.js +100 -28
- package/dist/agent-core/session/store/resources.d.ts +26 -0
- package/dist/agent-core/session/store/resources.js +196 -0
- package/dist/agent-core/session/store/types.d.ts +7 -6
- package/dist/agent-core/session/transaction-recovery.js +1 -1
- package/dist/agent-core/tools/code-mode/cells.js +3 -4
- package/dist/agent-core/tools/code-mode/index.js +32 -8
- package/dist/agent-core/tools/code-mode/observations.d.ts +5 -16
- package/dist/agent-core/tools/code-mode/quickjs-engine.js +23 -26
- package/dist/agent-core/tools/contracts.d.ts +15 -5
- package/dist/agent-core/tools/execution-limits.d.ts +3 -1
- package/dist/agent-core/tools/execution-limits.js +3 -1
- package/dist/agent-core/tools/execution.d.ts +2 -1
- package/dist/agent-core/tools/execution.js +31 -4
- package/dist/agent-core/tools/input-diagnostics/source-preview.d.ts +10 -0
- package/dist/agent-core/tools/input-diagnostics/source-preview.js +64 -0
- package/dist/agent-core/tools/local/apply-patch-parser.js +2 -53
- package/dist/agent-core/tools/local/apply-patch.js +1 -1
- package/dist/agent-core/tools/local/image-processing.d.ts +24 -0
- package/dist/agent-core/tools/local/image-processing.js +135 -0
- package/dist/agent-core/tools/local/read.js +1 -1
- package/dist/agent-core/tools/local/view-image.d.ts +4 -0
- package/dist/agent-core/tools/local/view-image.js +154 -25
- package/dist/agent-core/tools/output-projection.d.ts +2 -4
- package/dist/agent-core/tools/output-projection.js +81 -10
- package/dist/agent-core/tools/runtime-context.d.ts +1 -0
- package/dist/agent-core/tools/runtime.js +20 -1
- package/dist/cli/main.js +2 -1
- package/dist/index.d.ts +1 -1
- package/package.json +2 -1
|
@@ -9,7 +9,7 @@ export declare class MarAgentError extends Error {
|
|
|
9
9
|
cause?: unknown;
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
|
-
export declare function describeMarAgentError(error: unknown, fallbackCode: string, fallbackMessage?: string): {
|
|
12
|
+
export declare function describeMarAgentError(error: unknown, fallbackCode: string, fallbackMessage?: string, includeCauses?: boolean): {
|
|
13
13
|
code: string;
|
|
14
14
|
message: string;
|
|
15
15
|
};
|
package/dist/agent-core/error.js
CHANGED
|
@@ -13,7 +13,7 @@ export class MarAgentError extends Error {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
const MAX_ERROR_MESSAGE_CHARACTERS = 1_000;
|
|
16
|
-
export function describeMarAgentError(error, fallbackCode, fallbackMessage = 'MAR Agent operation failed.') {
|
|
16
|
+
export function describeMarAgentError(error, fallbackCode, fallbackMessage = 'MAR Agent operation failed.', includeCauses = true) {
|
|
17
17
|
const code = diagnosticCode(error) ?? fallbackCode;
|
|
18
18
|
const messages = [];
|
|
19
19
|
const seen = new Set();
|
|
@@ -22,8 +22,13 @@ export function describeMarAgentError(error, fallbackCode, fallbackMessage = 'MA
|
|
|
22
22
|
seen.add(current);
|
|
23
23
|
const currentCode = diagnosticCode(current);
|
|
24
24
|
const message = diagnosticMessage(current, currentCode);
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const summary = message && currentCode !== undefined && currentCode !== code
|
|
26
|
+
? `${currentCode}: ${message}`
|
|
27
|
+
: message;
|
|
28
|
+
if (summary && !messages.includes(summary))
|
|
29
|
+
messages.push(summary);
|
|
30
|
+
if (!includeCauses)
|
|
31
|
+
break;
|
|
27
32
|
current = diagnosticCause(current);
|
|
28
33
|
}
|
|
29
34
|
return {
|
|
@@ -40,23 +45,24 @@ function diagnosticCode(value) {
|
|
|
40
45
|
return typeof code === 'string' && code.trim().length > 0 ? code.trim().slice(0, 80) : undefined;
|
|
41
46
|
}
|
|
42
47
|
function diagnosticMessage(value, code) {
|
|
43
|
-
const message = value instanceof
|
|
44
|
-
? value.
|
|
45
|
-
: value
|
|
46
|
-
typeof value === 'object' &&
|
|
47
|
-
'message' in value &&
|
|
48
|
-
typeof value.message === 'string'
|
|
48
|
+
const message = value instanceof MarAgentError
|
|
49
|
+
? value.publicMessage
|
|
50
|
+
: value instanceof Error
|
|
49
51
|
? value.message
|
|
50
|
-
:
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
: value !== null &&
|
|
53
|
+
typeof value === 'object' &&
|
|
54
|
+
'message' in value &&
|
|
55
|
+
typeof value.message === 'string'
|
|
56
|
+
? value.message
|
|
57
|
+
: typeof value === 'string'
|
|
58
|
+
? value
|
|
59
|
+
: undefined;
|
|
53
60
|
const normalized = message?.trim();
|
|
54
61
|
if (!normalized)
|
|
55
62
|
return undefined;
|
|
56
|
-
|
|
63
|
+
return code !== undefined && normalized.startsWith(`${code}: `)
|
|
57
64
|
? normalized.slice(code.length + 2)
|
|
58
65
|
: normalized;
|
|
59
|
-
return code === undefined ? withoutDuplicatedCode : `${code}: ${withoutDuplicatedCode}`;
|
|
60
66
|
}
|
|
61
67
|
function diagnosticCause(value) {
|
|
62
68
|
if (value === null || typeof value !== 'object' || !('cause' in value))
|
|
@@ -10,6 +10,12 @@ export interface CoreCompactDiagnostic {
|
|
|
10
10
|
readonly elapsedMs: number;
|
|
11
11
|
readonly reason?: 'INPUT_BUDGET_EXHAUSTED' | 'MODEL_INCOMPLETE' | 'MODEL_FAILED';
|
|
12
12
|
readonly errorCode?: string;
|
|
13
|
+
readonly trigger?: 'manual' | 'automatic';
|
|
14
|
+
readonly causeCode?: string;
|
|
15
|
+
readonly errorReason?: string;
|
|
16
|
+
readonly httpStatus?: number;
|
|
17
|
+
readonly retryable?: boolean;
|
|
18
|
+
readonly transport?: 'HTTP' | 'WEBSOCKET';
|
|
13
19
|
}
|
|
14
20
|
export interface CoreCompactMessage {
|
|
15
21
|
readonly role: 'user' | 'assistant' | 'tool' | 'tool_call';
|
|
@@ -35,6 +35,7 @@ export function compactExtensionDiagnostic(value) {
|
|
|
35
35
|
value.length > 0 &&
|
|
36
36
|
value.length <= limit &&
|
|
37
37
|
!/[\r\n]/u.test(value);
|
|
38
|
+
const code = (value) => typeof value === 'string' && /^[A-Za-z][A-Za-z0-9_.-]{0,127}$/u.test(value);
|
|
38
39
|
if (!label(input.modelId, 128) ||
|
|
39
40
|
!label(input.reasoningEffort, 32) ||
|
|
40
41
|
typeof input.state !== 'string' ||
|
|
@@ -61,8 +62,21 @@ export function compactExtensionDiagnostic(value) {
|
|
|
61
62
|
['INPUT_BUDGET_EXHAUSTED', 'MODEL_INCOMPLETE', 'MODEL_FAILED'].includes(input.reason)
|
|
62
63
|
? { reason: input.reason }
|
|
63
64
|
: {}),
|
|
64
|
-
...(
|
|
65
|
-
|
|
65
|
+
...(code(input.errorCode) ? { errorCode: input.errorCode } : {}),
|
|
66
|
+
...(input.trigger === 'manual' || input.trigger === 'automatic'
|
|
67
|
+
? { trigger: input.trigger }
|
|
68
|
+
: {}),
|
|
69
|
+
...(code(input.causeCode) ? { causeCode: input.causeCode } : {}),
|
|
70
|
+
...(code(input.errorReason) ? { errorReason: input.errorReason } : {}),
|
|
71
|
+
...(typeof input.httpStatus === 'number' &&
|
|
72
|
+
Number.isInteger(input.httpStatus) &&
|
|
73
|
+
input.httpStatus >= 100 &&
|
|
74
|
+
input.httpStatus <= 599
|
|
75
|
+
? { httpStatus: input.httpStatus }
|
|
76
|
+
: {}),
|
|
77
|
+
...(typeof input.retryable === 'boolean' ? { retryable: input.retryable } : {}),
|
|
78
|
+
...(input.transport === 'HTTP' || input.transport === 'WEBSOCKET'
|
|
79
|
+
? { transport: input.transport }
|
|
66
80
|
: {})
|
|
67
81
|
};
|
|
68
82
|
}
|
|
@@ -13,10 +13,7 @@ export type CoreModelMessage = {
|
|
|
13
13
|
readonly callId?: string;
|
|
14
14
|
readonly name?: string;
|
|
15
15
|
readonly arguments?: unknown;
|
|
16
|
-
readonly images?: readonly
|
|
17
|
-
readonly mimeType: string;
|
|
18
|
-
readonly dataBase64: string;
|
|
19
|
-
}[];
|
|
16
|
+
readonly images?: readonly import('../model/image.js').ModelImage[];
|
|
20
17
|
};
|
|
21
18
|
export interface CoreModelRequest {
|
|
22
19
|
readonly modelId: string;
|
|
@@ -26,10 +23,7 @@ export interface CoreModelRequest {
|
|
|
26
23
|
readonly tools: readonly ClientToolDefinition[];
|
|
27
24
|
readonly toolChoice?: 'auto' | 'none';
|
|
28
25
|
readonly reasoningEffort?: MarAgentReasoningEffort;
|
|
29
|
-
readonly images?: readonly
|
|
30
|
-
readonly mimeType: string;
|
|
31
|
-
readonly dataBase64: string;
|
|
32
|
-
}[];
|
|
26
|
+
readonly images?: readonly import('../model/image.js').ModelImage[];
|
|
33
27
|
}
|
|
34
28
|
export interface CoreRequestSnapshot {
|
|
35
29
|
readonly id: string;
|
|
@@ -54,7 +48,9 @@ export declare class ExtensionRequestBridge {
|
|
|
54
48
|
#private;
|
|
55
49
|
readonly modelId: string;
|
|
56
50
|
readonly original: ModelRequest;
|
|
51
|
+
private readonly committedPrefix;
|
|
52
|
+
rewroteCommittedInput: boolean;
|
|
57
53
|
readonly view: CoreModelRequest;
|
|
58
|
-
constructor(modelId: string, original: ModelRequest, sourceMessages?: readonly CoreModelMessage[]);
|
|
54
|
+
constructor(modelId: string, original: ModelRequest, sourceMessages?: readonly CoreModelMessage[], committedPrefix?: number);
|
|
59
55
|
lower(view: CoreModelRequest): ModelRequest;
|
|
60
56
|
}
|
|
@@ -59,11 +59,14 @@ function freezeSnapshot(value) {
|
|
|
59
59
|
export class ExtensionRequestBridge {
|
|
60
60
|
modelId;
|
|
61
61
|
original;
|
|
62
|
+
committedPrefix;
|
|
62
63
|
#messages = new Map();
|
|
64
|
+
rewroteCommittedInput = false;
|
|
63
65
|
view;
|
|
64
|
-
constructor(modelId, original, sourceMessages) {
|
|
66
|
+
constructor(modelId, original, sourceMessages, committedPrefix = 0) {
|
|
65
67
|
this.modelId = modelId;
|
|
66
68
|
this.original = original;
|
|
69
|
+
this.committedPrefix = committedPrefix;
|
|
67
70
|
const messages = original.messages.map((original, index) => {
|
|
68
71
|
const sourceRef = sourceMessages?.[index]?.sourceRef ?? randomUUID();
|
|
69
72
|
const view = original.role === 'provider'
|
|
@@ -82,7 +85,7 @@ export class ExtensionRequestBridge {
|
|
|
82
85
|
: {}),
|
|
83
86
|
...(original.images !== undefined ? { images: structuredClone(original.images) } : {})
|
|
84
87
|
};
|
|
85
|
-
this.#messages.set(sourceRef, { original, view: structuredClone(view) });
|
|
88
|
+
this.#messages.set(sourceRef, { original, view: structuredClone(view), index });
|
|
86
89
|
return view;
|
|
87
90
|
});
|
|
88
91
|
this.view = {
|
|
@@ -113,7 +116,11 @@ export class ExtensionRequestBridge {
|
|
|
113
116
|
Array.isArray(tool.inputSchema)))
|
|
114
117
|
throw new MarAgentError('MAR_AGENT_EXTENSION_MODEL_REQUEST_INVALID', 'Model request view is invalid.');
|
|
115
118
|
const seen = new Set();
|
|
116
|
-
|
|
119
|
+
if (view.messages.length < this.committedPrefix ||
|
|
120
|
+
view.system !== this.original.system ||
|
|
121
|
+
!isDeepStrictEqual(view.systemBlocks, this.original.systemBlocks))
|
|
122
|
+
this.rewroteCommittedInput = true;
|
|
123
|
+
const messages = view.messages.map((message, index) => {
|
|
117
124
|
if (!message || typeof message !== 'object')
|
|
118
125
|
throw new MarAgentError('MAR_AGENT_EXTENSION_MODEL_REQUEST_INVALID', 'Message view is invalid.');
|
|
119
126
|
const source = message.sourceRef ? this.#messages.get(message.sourceRef) : undefined;
|
|
@@ -122,8 +129,12 @@ export class ExtensionRequestBridge {
|
|
|
122
129
|
throw new MarAgentError('MAR_AGENT_EXTENSION_MODEL_REQUEST_INVALID', 'Message source reference is invalid.');
|
|
123
130
|
seen.add(message.sourceRef);
|
|
124
131
|
}
|
|
132
|
+
if (index < this.committedPrefix && source?.index !== index)
|
|
133
|
+
this.rewroteCommittedInput = true;
|
|
125
134
|
if (source && isDeepStrictEqual(message, source.view))
|
|
126
135
|
return source.original;
|
|
136
|
+
if (index < this.committedPrefix)
|
|
137
|
+
this.rewroteCommittedInput = true;
|
|
127
138
|
if (message.role === 'opaque' ||
|
|
128
139
|
typeof message.content !== 'string' ||
|
|
129
140
|
!['user', 'assistant', 'tool', 'tool_call'].includes(message.role))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MarAgentError } from '../error.js';
|
|
2
|
+
import { isModelImageUrl } from '../model/image.js';
|
|
2
3
|
export function captureCorePromptInput(input) {
|
|
3
4
|
if (!input ||
|
|
4
5
|
typeof input.text !== 'string' ||
|
|
@@ -14,7 +15,8 @@ export function captureCorePromptInput(input) {
|
|
|
14
15
|
!Array.from(input.images).every((image) => image &&
|
|
15
16
|
typeof image.name === 'string' &&
|
|
16
17
|
typeof image.mimeType === 'string' &&
|
|
17
|
-
typeof image.dataBase64 === 'string'
|
|
18
|
+
typeof image.dataBase64 === 'string' &&
|
|
19
|
+
(image.url === undefined || isModelImageUrl(image.url))))))
|
|
18
20
|
throw new MarAgentError('MAR_AGENT_SESSION_INPUT_INVALID', 'Prompt content is invalid.');
|
|
19
21
|
return structuredClone({
|
|
20
22
|
text: input.text,
|
|
@@ -55,6 +55,14 @@ export interface HostSessionResourceSnapshot {
|
|
|
55
55
|
export interface MarAgentHost {
|
|
56
56
|
/** Independent model consumption facts, including child and auxiliary calls. */
|
|
57
57
|
modelUsage?: import('../model/usage-observer.js').ModelUsageObserver | undefined;
|
|
58
|
+
publishModelResource?: (image: import('../session/store/resources.js').SessionResource, context: {
|
|
59
|
+
sessionId: string;
|
|
60
|
+
executionId: string;
|
|
61
|
+
homeDirectory: string;
|
|
62
|
+
}) => Promise<{
|
|
63
|
+
url: string;
|
|
64
|
+
urlExpiresAt: number;
|
|
65
|
+
} | undefined>;
|
|
58
66
|
readonly extensionPorts?: CoreHostExtensionPorts;
|
|
59
67
|
describe(): Promise<HostDescription>;
|
|
60
68
|
executeTool(call: ToolCall, context: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
@@ -27,6 +27,7 @@ export declare class LocalAgentHost implements MarAgentHost {
|
|
|
27
27
|
readonly extensionPorts: import('./contracts.js').CoreHostExtensionPorts;
|
|
28
28
|
readonly events: MarAgentEvent[];
|
|
29
29
|
readonly requestToolApproval: MarAgentHost['requestToolApproval'];
|
|
30
|
+
readonly publishModelResource?: NonNullable<MarAgentHost['publishModelResource']>;
|
|
30
31
|
constructor(input: {
|
|
31
32
|
mcp?: import('../extensions/mcp.js').CoreMcpBackend;
|
|
32
33
|
operationTools?: CoreHostToolsBackend;
|
|
@@ -34,6 +35,7 @@ export declare class LocalAgentHost implements MarAgentHost {
|
|
|
34
35
|
callMcpOperation?: (input: ToolCall, call: CoreOperationContext, expected: NonNullable<McpToolCallContext['expectedTool']>) => Promise<ToolExecutionResult>;
|
|
35
36
|
network?: CoreNetworkBackend | false;
|
|
36
37
|
modelUsage?: import('../model/usage-observer.js').ModelUsageObserver;
|
|
38
|
+
publishModelResource?: MarAgentHost['publishModelResource'];
|
|
37
39
|
homeDirectory: string;
|
|
38
40
|
workspace: string;
|
|
39
41
|
mode?: 'normal' | 'node';
|
|
@@ -32,6 +32,7 @@ export class LocalAgentHost {
|
|
|
32
32
|
#extensions;
|
|
33
33
|
events = [];
|
|
34
34
|
requestToolApproval;
|
|
35
|
+
publishModelResource;
|
|
35
36
|
#mode;
|
|
36
37
|
#environment;
|
|
37
38
|
#sessionEnvironment;
|
|
@@ -41,6 +42,8 @@ export class LocalAgentHost {
|
|
|
41
42
|
constructor(input) {
|
|
42
43
|
this.modelUsage = input.modelUsage;
|
|
43
44
|
this.requestToolApproval = input.approval;
|
|
45
|
+
if (input.publishModelResource !== undefined)
|
|
46
|
+
this.publishModelResource = input.publishModelResource;
|
|
44
47
|
this.#home = resolve(input.homeDirectory);
|
|
45
48
|
this.#workspace = resolve(input.workspace);
|
|
46
49
|
this.#environment = input.environment ?? process.env;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { observeModelRequestUsage } from './usage-observer.js';
|
|
2
2
|
import { jsonToolInput } from './tool-input.js';
|
|
3
3
|
import { observationModelParts } from '../tools/code-mode/observations.js';
|
|
4
|
+
import { modelImageKey, modelImageUrl } from './image.js';
|
|
4
5
|
import { stableToolSchema } from '../tools/definition-projection.js';
|
|
5
6
|
import { randomUUID } from 'node:crypto';
|
|
6
7
|
import { MarAgentError } from '../error.js';
|
|
8
|
+
import { assertInlineMediaBudget } from '../session/inline-media.js';
|
|
7
9
|
import { resolveModelDefaultReasoningEffort } from './configuration.js';
|
|
8
10
|
import { isRetryableUpstreamOverloadCode, number, parseSse, record, text, observeModelStreamEvent, modelStreamEventObservedAt } from './sse.js';
|
|
9
11
|
import { fetchModelResponse, modelRetryMaxAttempts, isRetryableModelRequestError, isRetryableModelTransportError, modelRetryDelay, waitForModelRetry } from './http.js';
|
|
@@ -93,6 +95,7 @@ export class AnthropicMessagesAdapter {
|
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
97
|
async *startAttempt(request, signal) {
|
|
98
|
+
assertInlineMediaBudget(request);
|
|
96
99
|
const apiKey = this.configuration.apiKey;
|
|
97
100
|
if (apiKey === undefined)
|
|
98
101
|
throw new MarAgentError('MAR_AGENT_MODEL_CONFIG_INVALID', 'Anthropic Messages requires a static API key.');
|
|
@@ -588,22 +591,14 @@ function anthropicMessages(messages, images, tools = [], modelId, automaticCache
|
|
|
588
591
|
? { type: 'text', text: part.text }
|
|
589
592
|
: {
|
|
590
593
|
type: 'image',
|
|
591
|
-
source:
|
|
592
|
-
type: 'base64',
|
|
593
|
-
media_type: part.image.mimeType,
|
|
594
|
-
data: part.image.dataBase64
|
|
595
|
-
}
|
|
594
|
+
source: anthropicImageSource(part.image)
|
|
596
595
|
}) ??
|
|
597
596
|
(message.textBlocks !== undefined
|
|
598
597
|
? [
|
|
599
598
|
...anthropicTextBlocks(message.content, message.textBlocks),
|
|
600
599
|
...(message.images ?? []).map((image) => ({
|
|
601
600
|
type: 'image',
|
|
602
|
-
source:
|
|
603
|
-
type: 'base64',
|
|
604
|
-
media_type: image.mimeType,
|
|
605
|
-
data: image.dataBase64
|
|
606
|
-
}
|
|
601
|
+
source: anthropicImageSource(image)
|
|
607
602
|
}))
|
|
608
603
|
]
|
|
609
604
|
: message.images?.length
|
|
@@ -611,11 +606,7 @@ function anthropicMessages(messages, images, tools = [], modelId, automaticCache
|
|
|
611
606
|
{ type: 'text', text: message.content },
|
|
612
607
|
...message.images.map((image) => ({
|
|
613
608
|
type: 'image',
|
|
614
|
-
source:
|
|
615
|
-
type: 'base64',
|
|
616
|
-
media_type: image.mimeType,
|
|
617
|
-
data: image.dataBase64
|
|
618
|
-
}
|
|
609
|
+
source: anthropicImageSource(image)
|
|
619
610
|
}))
|
|
620
611
|
]
|
|
621
612
|
: message.content)
|
|
@@ -646,11 +637,7 @@ function anthropicMessages(messages, images, tools = [], modelId, automaticCache
|
|
|
646
637
|
? [
|
|
647
638
|
...userImages.map((image) => ({
|
|
648
639
|
type: 'image',
|
|
649
|
-
source:
|
|
650
|
-
type: 'base64',
|
|
651
|
-
media_type: image.mimeType,
|
|
652
|
-
data: image.dataBase64
|
|
653
|
-
}
|
|
640
|
+
source: anthropicImageSource(image)
|
|
654
641
|
})),
|
|
655
642
|
...anthropicTextBlocks(message.content, message.textBlocks)
|
|
656
643
|
]
|
|
@@ -658,11 +645,7 @@ function anthropicMessages(messages, images, tools = [], modelId, automaticCache
|
|
|
658
645
|
? [
|
|
659
646
|
...userImages.map((image) => ({
|
|
660
647
|
type: 'image',
|
|
661
|
-
source:
|
|
662
|
-
type: 'base64',
|
|
663
|
-
media_type: image.mimeType,
|
|
664
|
-
data: image.dataBase64
|
|
665
|
-
}
|
|
648
|
+
source: anthropicImageSource(image)
|
|
666
649
|
})),
|
|
667
650
|
{ type: 'text', text: message.content }
|
|
668
651
|
]
|
|
@@ -690,13 +673,19 @@ function isRealUserMessage(message) {
|
|
|
690
673
|
function uniqueModelImages(...groups) {
|
|
691
674
|
const seen = new Set();
|
|
692
675
|
return groups.flatMap((group) => (group ?? []).flatMap((image) => {
|
|
693
|
-
const key =
|
|
676
|
+
const key = modelImageKey(image);
|
|
694
677
|
if (seen.has(key))
|
|
695
678
|
return [];
|
|
696
679
|
seen.add(key);
|
|
697
680
|
return [image];
|
|
698
681
|
}));
|
|
699
682
|
}
|
|
683
|
+
function anthropicImageSource(image) {
|
|
684
|
+
const url = modelImageUrl(image);
|
|
685
|
+
return url === image.url
|
|
686
|
+
? { type: 'url', url }
|
|
687
|
+
: { type: 'base64', media_type: image.mimeType, data: image.dataBase64 };
|
|
688
|
+
}
|
|
700
689
|
function isObject(value) {
|
|
701
690
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
702
691
|
}
|
|
@@ -12,6 +12,7 @@ export declare function writeModelCatalog(home: string, catalog: CliModelCatalog
|
|
|
12
12
|
export declare function serializeModel(model: CliModelConfiguration): {
|
|
13
13
|
apiKey: string;
|
|
14
14
|
conversationModel?: boolean;
|
|
15
|
+
useResourceUrl?: boolean;
|
|
15
16
|
responsesConfigurationUpdates?: boolean;
|
|
16
17
|
codexCredential?: boolean;
|
|
17
18
|
responsesTransport?: import("./configuration.js").ResponsesTransport;
|
|
@@ -46,6 +47,7 @@ export declare function serializeModel(model: CliModelConfiguration): {
|
|
|
46
47
|
type: "CODEX_AUTH_FILE";
|
|
47
48
|
};
|
|
48
49
|
conversationModel?: boolean;
|
|
50
|
+
useResourceUrl?: boolean;
|
|
49
51
|
responsesConfigurationUpdates?: boolean;
|
|
50
52
|
codexCredential?: boolean;
|
|
51
53
|
responsesTransport?: import("./configuration.js").ResponsesTransport;
|
|
@@ -70,6 +70,7 @@ declare const rawModelSchema: z.ZodObject<{
|
|
|
70
70
|
conversationModel: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
71
71
|
titleGeneration: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
72
72
|
codeMode: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
73
|
+
useResourceUrl: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
73
74
|
fastMode: z.ZodOptional<z.ZodBoolean>;
|
|
74
75
|
serviceTier: z.ZodOptional<z.ZodEnum<{
|
|
75
76
|
default: "default";
|
|
@@ -100,8 +101,9 @@ declare const rawModelSchema: z.ZodObject<{
|
|
|
100
101
|
}, z.core.$strict>>;
|
|
101
102
|
enabled: z.ZodBoolean;
|
|
102
103
|
}, z.core.$strict>;
|
|
103
|
-
export interface MarAgentModelConfiguration extends Omit<z.infer<typeof rawModelSchema>, 'apiKey' | 'responsesPreviousResponseId' | 'responsesTransport' | 'conversationModel'> {
|
|
104
|
+
export interface MarAgentModelConfiguration extends Omit<z.infer<typeof rawModelSchema>, 'apiKey' | 'responsesPreviousResponseId' | 'responsesTransport' | 'conversationModel' | 'useResourceUrl'> {
|
|
104
105
|
conversationModel?: boolean;
|
|
106
|
+
useResourceUrl?: boolean;
|
|
105
107
|
apiKey?: SecretValue;
|
|
106
108
|
credentialProvider?: ModelCredentialProvider;
|
|
107
109
|
/** Whether this Responses endpoint accepts native configuration_update input items. */
|
|
@@ -50,6 +50,7 @@ const rawModelSchema = z
|
|
|
50
50
|
conversationModel: z.boolean().optional().default(true),
|
|
51
51
|
titleGeneration: z.boolean().optional().default(false),
|
|
52
52
|
codeMode: z.boolean().optional().default(false),
|
|
53
|
+
useResourceUrl: z.boolean().optional().default(false),
|
|
53
54
|
fastMode: z.boolean().optional(),
|
|
54
55
|
serviceTier: z.enum(['auto', 'default', 'flex', 'priority', 'fast', 'ultrafast']).optional(),
|
|
55
56
|
hostedWebSearch: z.boolean(),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ClientToolDefinition } from '../tools/contracts.js';
|
|
2
|
+
import type { ModelImage } from './image.js';
|
|
2
3
|
import type { MarAgentModelConfiguration, MarAgentReasoningEffort, ModelCredentialAcquireReason } from './configuration.js';
|
|
3
4
|
export type { ClientToolDefinition, ToolCaller } from '../tools/contracts.js';
|
|
4
5
|
export interface ModelTextBlock {
|
|
@@ -41,10 +42,7 @@ export interface ModelMessage {
|
|
|
41
42
|
provider?: 'OPENAI_RESPONSES' | 'ANTHROPIC_MESSAGES';
|
|
42
43
|
providerModelId?: string;
|
|
43
44
|
item?: Record<string, unknown>;
|
|
44
|
-
images?: readonly
|
|
45
|
-
mimeType: string;
|
|
46
|
-
dataBase64: string;
|
|
47
|
-
}[];
|
|
45
|
+
images?: readonly ModelImage[];
|
|
48
46
|
observations?: readonly import('../tools/code-mode/observations.js').CodeObservation[];
|
|
49
47
|
/** Runtime-only location used by the GC evidence adapter, never a Provider call. */
|
|
50
48
|
observationId?: string;
|
|
@@ -112,10 +110,7 @@ export interface ModelRequest {
|
|
|
112
110
|
/** Stable request-level effort while native configuration updates select the current effort. */
|
|
113
111
|
requestReasoningEffort?: MarAgentReasoningEffort;
|
|
114
112
|
promptCacheKey?: string;
|
|
115
|
-
images?: readonly
|
|
116
|
-
mimeType: string;
|
|
117
|
-
dataBase64: string;
|
|
118
|
-
}[];
|
|
113
|
+
images?: readonly ModelImage[];
|
|
119
114
|
onAttemptDiagnostic?: (diagnostic: ModelAttemptDiagnostic) => Promise<void> | void;
|
|
120
115
|
}
|
|
121
116
|
export interface ModelUsage {
|
|
@@ -228,5 +223,7 @@ export interface ModelTurnSession {
|
|
|
228
223
|
start(request: ModelRequest, signal: AbortSignal): AsyncIterable<ModelEvent>;
|
|
229
224
|
/** Drops incremental response state after a local context replacement. */
|
|
230
225
|
resetContinuation?(): void;
|
|
226
|
+
continuationInputCount?(): number;
|
|
227
|
+
commitContinuationInput?(messageCount: number): void;
|
|
231
228
|
close(): Promise<void>;
|
|
232
229
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ModelImage {
|
|
2
|
+
readonly resourceInputVersion?: 1;
|
|
3
|
+
readonly mimeType: string;
|
|
4
|
+
readonly dataBase64?: string;
|
|
5
|
+
readonly resourceId?: string;
|
|
6
|
+
readonly byteSize?: number;
|
|
7
|
+
/** Fixed published resource; image bytes are persisted separately. */
|
|
8
|
+
readonly url?: string;
|
|
9
|
+
readonly urlExpiresAt?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function modelImageUrl(image: ModelImage): string;
|
|
12
|
+
export declare function modelImageKey(image: ModelImage): string;
|
|
13
|
+
/** Only immutable URL references may enter durable model history. */
|
|
14
|
+
export declare function persistedModelImages(images: readonly ModelImage[] | undefined): ModelImage[];
|
|
15
|
+
/** Durable images contain a URL or resource reference, never inline image bytes. */
|
|
16
|
+
export declare function parseModelImages(value: unknown): ModelImage[] | undefined;
|
|
17
|
+
export declare function isModelImageUrl(value: unknown): value is string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function modelImageUrl(image) {
|
|
2
|
+
if (image.url !== undefined && isModelImageUrl(image.url))
|
|
3
|
+
return image.url;
|
|
4
|
+
if (typeof image.dataBase64 !== 'string' || image.dataBase64.length === 0)
|
|
5
|
+
throw new Error('Model image has no usable source.');
|
|
6
|
+
return `data:${image.mimeType};base64,${image.dataBase64}`;
|
|
7
|
+
}
|
|
8
|
+
export function modelImageKey(image) {
|
|
9
|
+
return `${image.mimeType}\u0000${modelImageUrl(image)}`;
|
|
10
|
+
}
|
|
11
|
+
/** Only immutable URL references may enter durable model history. */
|
|
12
|
+
export function persistedModelImages(images) {
|
|
13
|
+
return (images ?? [])
|
|
14
|
+
.filter((image) => isModelImageUrl(image.url) || image.resourceId !== undefined)
|
|
15
|
+
.map((image) => ({
|
|
16
|
+
resourceInputVersion: 1,
|
|
17
|
+
mimeType: image.mimeType,
|
|
18
|
+
...(image.url === undefined ? {} : { url: image.url }),
|
|
19
|
+
...(image.urlExpiresAt === undefined ? {} : { urlExpiresAt: image.urlExpiresAt }),
|
|
20
|
+
...(image.resourceId === undefined ? {} : { resourceId: image.resourceId }),
|
|
21
|
+
...(image.byteSize === undefined ? {} : { byteSize: image.byteSize })
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
/** Durable images contain a URL or resource reference, never inline image bytes. */
|
|
25
|
+
export function parseModelImages(value) {
|
|
26
|
+
if (!Array.isArray(value) ||
|
|
27
|
+
!value.every((image) => image &&
|
|
28
|
+
image.resourceInputVersion === 1 &&
|
|
29
|
+
typeof image.mimeType === 'string' &&
|
|
30
|
+
(image.url === undefined || isModelImageUrl(image.url)) &&
|
|
31
|
+
(image.resourceId === undefined ||
|
|
32
|
+
(typeof image.resourceId === 'string' && /^[a-f0-9]{64}$/u.test(image.resourceId))) &&
|
|
33
|
+
(image.byteSize === undefined ||
|
|
34
|
+
(Number.isSafeInteger(image.byteSize) && image.byteSize > 0)) &&
|
|
35
|
+
(image.urlExpiresAt === undefined ||
|
|
36
|
+
(Number.isSafeInteger(image.urlExpiresAt) && image.urlExpiresAt > 0)) &&
|
|
37
|
+
(image.url !== undefined || image.resourceId !== undefined)))
|
|
38
|
+
return undefined;
|
|
39
|
+
return persistedModelImages(value);
|
|
40
|
+
}
|
|
41
|
+
export function isModelImageUrl(value) {
|
|
42
|
+
if (typeof value !== 'string' || value.length === 0 || value.length > 8192)
|
|
43
|
+
return false;
|
|
44
|
+
try {
|
|
45
|
+
const url = new URL(value);
|
|
46
|
+
return ((url.protocol === 'https:' || url.protocol === 'http:') &&
|
|
47
|
+
url.username === '' &&
|
|
48
|
+
url.password === '');
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -15,12 +15,16 @@ interface ResponsesSessionState {
|
|
|
15
15
|
connectionId?: string;
|
|
16
16
|
proxyType?: 'DIRECT' | 'SOCKS5';
|
|
17
17
|
lastRequest?: ResponsesRequestBody;
|
|
18
|
+
lastMessageCount?: number;
|
|
19
|
+
lastInputItemCount?: number;
|
|
20
|
+
lastSystem?: string;
|
|
18
21
|
lastResponse?: {
|
|
19
22
|
readonly responseId: string;
|
|
20
23
|
readonly outputItems: readonly Record<string, unknown>[];
|
|
21
24
|
};
|
|
22
25
|
}
|
|
23
26
|
interface PreparedResponsesRequest {
|
|
27
|
+
readonly inputItemCount: number;
|
|
24
28
|
readonly fullBody: ResponsesRequestBody;
|
|
25
29
|
readonly body: ResponsesRequestBody;
|
|
26
30
|
readonly continuation: boolean;
|
|
@@ -47,9 +51,10 @@ declare class OpenAiResponsesTurnSession implements ModelTurnSession {
|
|
|
47
51
|
start(request: ModelRequest, signal: AbortSignal): AsyncIterable<ModelEvent>;
|
|
48
52
|
close(): Promise<void>;
|
|
49
53
|
resetContinuation(): void;
|
|
54
|
+
continuationInputCount(): number;
|
|
55
|
+
commitContinuationInput(messageCount: number): void;
|
|
50
56
|
captureCompletedResponseId(responseId: string | undefined): void;
|
|
51
57
|
prepareRequest(request: ModelRequest): PreparedResponsesRequest;
|
|
52
|
-
fullRequestBody(): ResponsesRequestBody;
|
|
53
58
|
currentTurnState(): string | undefined;
|
|
54
59
|
beginAttempt(): void;
|
|
55
60
|
captureWebSocketDiagnostic(diagnostic: ResponsesWebSocketDiagnostic): void;
|
|
@@ -68,5 +73,5 @@ declare class OpenAiResponsesTurnSession implements ModelTurnSession {
|
|
|
68
73
|
private connectWebSocket;
|
|
69
74
|
}
|
|
70
75
|
export declare function isOpenAiResponsesRecoverableStreamError(error: unknown): error is MarAgentError;
|
|
71
|
-
export declare function openAiInput(messages: ModelRequest['messages'], images: ModelRequest['images'] | undefined, modelId: string, requireEncryptedReasoning: boolean, configurationUpdates?: boolean, nativeTools?: boolean, tools?: ModelRequest['tools']): Record<string, unknown>[];
|
|
76
|
+
export declare function openAiInput(messages: ModelRequest['messages'], images: ModelRequest['images'] | undefined, modelId: string, requireEncryptedReasoning: boolean, configurationUpdates?: boolean, nativeTools?: boolean, tools?: ModelRequest['tools'], previousOutputItems?: readonly Record<string, unknown>[]): Record<string, unknown>[];
|
|
72
77
|
export {};
|