@myagentroam/agent 0.9.84 → 0.9.85
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/model/configuration.js +5 -0
- package/dist/model/contracts.d.ts +1 -2
- package/dist/model/openai-responses.d.ts +1 -2
- package/dist/model/openai-responses.js +23 -52
- package/dist/sdk/agent.js +1 -2
- package/dist/tools/agent-message.js +7 -2
- package/dist/tools/agent-start.js +1 -0
- package/dist/tools/agent-wait.js +3 -0
- package/package.json +2 -1
|
@@ -80,6 +80,11 @@ const rawModelSchema = z
|
|
|
80
80
|
});
|
|
81
81
|
if (value.protocol !== 'OPENAI_RESPONSES' && value.responsesPreviousResponseId)
|
|
82
82
|
context.addIssue({ code: 'custom', message: 'Responses continuation requires Responses.' });
|
|
83
|
+
if (value.responsesPreviousResponseId && value.responsesTransport?.transport !== 'WEBSOCKET')
|
|
84
|
+
context.addIssue({
|
|
85
|
+
code: 'custom',
|
|
86
|
+
message: 'Responses continuation requires WebSocket transport.'
|
|
87
|
+
});
|
|
83
88
|
if (value.protocol !== 'OPENAI_RESPONSES' && value.responsesTransport !== undefined)
|
|
84
89
|
context.addIssue({ code: 'custom', message: 'Responses transport requires Responses.' });
|
|
85
90
|
if (value.protocol !== 'OPENAI_RESPONSES' && value.responsesEncoding !== undefined)
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { MarAgentModelConfiguration, MarAgentReasoningEffort, ModelCredentialAcquireReason } from './configuration.js';
|
|
2
2
|
export interface ModelContinuationCheckpoint {
|
|
3
|
-
readonly version:
|
|
3
|
+
readonly version: 2;
|
|
4
4
|
readonly protocol: 'OPENAI_RESPONSES';
|
|
5
5
|
readonly configurationHash: string;
|
|
6
6
|
readonly responseId: string;
|
|
7
|
-
readonly requestPropertiesHash: string;
|
|
8
7
|
readonly inputPrefixLength: number;
|
|
9
8
|
readonly inputPrefixHash: string;
|
|
10
9
|
}
|
|
@@ -45,8 +45,7 @@ declare class OpenAiResponsesTurnSession implements ModelTurnSession {
|
|
|
45
45
|
private readonly adapter;
|
|
46
46
|
private readonly state;
|
|
47
47
|
private readonly cacheLease;
|
|
48
|
-
|
|
49
|
-
constructor(adapter: OpenAiResponsesAdapter, state: ResponsesSessionState, cacheLease: boolean, allowExternalContinuation: boolean);
|
|
48
|
+
constructor(adapter: OpenAiResponsesAdapter, state: ResponsesSessionState, cacheLease: boolean);
|
|
50
49
|
start(request: ModelRequest, signal: AbortSignal): AsyncIterable<ModelEvent>;
|
|
51
50
|
close(): Promise<void>;
|
|
52
51
|
resetContinuation(): void;
|
|
@@ -35,14 +35,16 @@ export class OpenAiResponsesAdapter {
|
|
|
35
35
|
if (this.#cacheLeased ||
|
|
36
36
|
this.#cachedState.lastRequest !== undefined ||
|
|
37
37
|
this.#cachedState.lastResponse !== undefined ||
|
|
38
|
+
!responsesContinuationEnabled(this.#configuration) ||
|
|
39
|
+
checkpoint.version !== 2 ||
|
|
38
40
|
checkpoint.protocol !== 'OPENAI_RESPONSES' ||
|
|
39
|
-
checkpoint.configurationHash !==
|
|
41
|
+
checkpoint.configurationHash !== responsesContinuationIdentityHash(this.#configuration))
|
|
40
42
|
return false;
|
|
41
43
|
this.#cachedState.restoredContinuation = checkpoint;
|
|
42
44
|
return true;
|
|
43
45
|
}
|
|
44
46
|
async *start(request, signal) {
|
|
45
|
-
const turn = new OpenAiResponsesTurnSession(this, {}, false
|
|
47
|
+
const turn = new OpenAiResponsesTurnSession(this, {}, false);
|
|
46
48
|
try {
|
|
47
49
|
yield* turn.start(request, signal);
|
|
48
50
|
}
|
|
@@ -59,7 +61,7 @@ export class OpenAiResponsesAdapter {
|
|
|
59
61
|
this.#cachedState = {};
|
|
60
62
|
this.#cacheLeased = true;
|
|
61
63
|
}
|
|
62
|
-
return new OpenAiResponsesTurnSession(this, state, cacheLease
|
|
64
|
+
return new OpenAiResponsesTurnSession(this, state, cacheLease);
|
|
63
65
|
}
|
|
64
66
|
async close() {
|
|
65
67
|
if (this.#closed)
|
|
@@ -546,17 +548,15 @@ class OpenAiResponsesTurnSession {
|
|
|
546
548
|
adapter;
|
|
547
549
|
state;
|
|
548
550
|
cacheLease;
|
|
549
|
-
allowExternalContinuation;
|
|
550
551
|
#active = false;
|
|
551
552
|
#closed = false;
|
|
552
553
|
#turnState;
|
|
553
554
|
#fullBody;
|
|
554
555
|
#connectionDiagnostic;
|
|
555
|
-
constructor(adapter, state, cacheLease
|
|
556
|
+
constructor(adapter, state, cacheLease) {
|
|
556
557
|
this.adapter = adapter;
|
|
557
558
|
this.state = state;
|
|
558
559
|
this.cacheLease = cacheLease;
|
|
559
|
-
this.allowExternalContinuation = allowExternalContinuation;
|
|
560
560
|
}
|
|
561
561
|
async *start(request, signal) {
|
|
562
562
|
if (this.#closed)
|
|
@@ -573,7 +573,7 @@ class OpenAiResponsesTurnSession {
|
|
|
573
573
|
this.#fullBody = prepared.fullBody;
|
|
574
574
|
if (this.adapter.configuration.responsesEncoding === 'LITE' &&
|
|
575
575
|
this.adapter.configuration.responsesTransport?.transport === 'WEBSOCKET' &&
|
|
576
|
-
this.adapter.configuration
|
|
576
|
+
responsesContinuationEnabled(this.adapter.configuration) &&
|
|
577
577
|
this.state.lastRequest === undefined &&
|
|
578
578
|
request.allowTools !== false &&
|
|
579
579
|
request.toolChoice !== 'none' &&
|
|
@@ -626,7 +626,7 @@ class OpenAiResponsesTurnSession {
|
|
|
626
626
|
completed = event.reason === 'completed' || event.reason === 'tool_use';
|
|
627
627
|
yield event;
|
|
628
628
|
}
|
|
629
|
-
if (this.adapter.configuration
|
|
629
|
+
if (responsesContinuationEnabled(this.adapter.configuration) &&
|
|
630
630
|
completed &&
|
|
631
631
|
responseId !== undefined &&
|
|
632
632
|
(outputItems.length > 0 || !sawUnrepresentedOutput)) {
|
|
@@ -656,17 +656,18 @@ class OpenAiResponsesTurnSession {
|
|
|
656
656
|
clearResponsesContinuation(this.state);
|
|
657
657
|
}
|
|
658
658
|
continuationCheckpoint() {
|
|
659
|
+
if (!responsesContinuationEnabled(this.adapter.configuration))
|
|
660
|
+
return undefined;
|
|
659
661
|
const request = this.state.lastRequest;
|
|
660
662
|
const response = this.state.lastResponse;
|
|
661
663
|
if (request === undefined || response === undefined)
|
|
662
664
|
return this.state.restoredContinuation;
|
|
663
665
|
const baseline = [...request.input, ...response.outputItems];
|
|
664
666
|
return {
|
|
665
|
-
version:
|
|
667
|
+
version: 2,
|
|
666
668
|
protocol: 'OPENAI_RESPONSES',
|
|
667
|
-
configurationHash:
|
|
669
|
+
configurationHash: responsesContinuationIdentityHash(this.adapter.configuration),
|
|
668
670
|
responseId: response.responseId,
|
|
669
|
-
requestPropertiesHash: responsesRequestPropertiesHash(request),
|
|
670
671
|
inputPrefixLength: baseline.length,
|
|
671
672
|
inputPrefixHash: hashResponsesValue(baseline)
|
|
672
673
|
};
|
|
@@ -677,7 +678,7 @@ class OpenAiResponsesTurnSession {
|
|
|
677
678
|
this.state.socket.readyState !== WebSocket.OPEN)
|
|
678
679
|
invalidateResponsesWebSocket(this.state, false);
|
|
679
680
|
const fullBody = responsesRequestBody(this.adapter.configuration, request, request.messages, this.adapter.prefixIdentity);
|
|
680
|
-
if (this.adapter.configuration
|
|
681
|
+
if (responsesContinuationEnabled(this.adapter.configuration)) {
|
|
681
682
|
const incremental = incrementalResponsesInput(this.state, fullBody);
|
|
682
683
|
if (incremental !== undefined) {
|
|
683
684
|
const responseId = this.state.lastResponse.responseId;
|
|
@@ -692,20 +693,6 @@ class OpenAiResponsesTurnSession {
|
|
|
692
693
|
continuation: true
|
|
693
694
|
};
|
|
694
695
|
}
|
|
695
|
-
if (this.allowExternalContinuation &&
|
|
696
|
-
request.continuation !== undefined &&
|
|
697
|
-
this.adapter.configuration.responsesTransport?.transport !== 'WEBSOCKET') {
|
|
698
|
-
const deltaBody = responsesRequestBody(this.adapter.configuration, request, request.continuation.deltaMessages);
|
|
699
|
-
return {
|
|
700
|
-
fullBody,
|
|
701
|
-
body: {
|
|
702
|
-
...fullBody,
|
|
703
|
-
input: deltaBody.input,
|
|
704
|
-
previous_response_id: request.continuation.previousResponseId
|
|
705
|
-
},
|
|
706
|
-
continuation: true
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
696
|
}
|
|
710
697
|
return {
|
|
711
698
|
fullBody,
|
|
@@ -899,7 +886,6 @@ function incrementalResponsesInput(state, current) {
|
|
|
899
886
|
if (previous === undefined || completion === undefined) {
|
|
900
887
|
const restored = state.restoredContinuation;
|
|
901
888
|
if (restored === undefined ||
|
|
902
|
-
restored.requestPropertiesHash !== responsesRequestPropertiesHash(current) ||
|
|
903
889
|
current.input.length < restored.inputPrefixLength ||
|
|
904
890
|
restored.inputPrefixHash !==
|
|
905
891
|
hashResponsesValue(current.input.slice(0, restored.inputPrefixLength)))
|
|
@@ -907,8 +893,6 @@ function incrementalResponsesInput(state, current) {
|
|
|
907
893
|
state.lastResponse = { responseId: restored.responseId, outputItems: [] };
|
|
908
894
|
return current.input.slice(restored.inputPrefixLength);
|
|
909
895
|
}
|
|
910
|
-
if (!responsesRequestPropertiesMatch(previous, current))
|
|
911
|
-
return undefined;
|
|
912
896
|
const baseline = [...previous.input, ...completion.outputItems];
|
|
913
897
|
if (current.input.length < baseline.length)
|
|
914
898
|
return undefined;
|
|
@@ -917,37 +901,24 @@ function incrementalResponsesInput(state, current) {
|
|
|
917
901
|
return undefined;
|
|
918
902
|
return current.input.slice(baseline.length);
|
|
919
903
|
}
|
|
920
|
-
function responsesRequestPropertiesMatch(previous, current) {
|
|
921
|
-
return RESPONSES_REQUEST_PROPERTY_KEYS.every((key) => isDeepStrictEqual(previous[key], current[key]));
|
|
922
|
-
}
|
|
923
904
|
function clearResponsesContinuation(state) {
|
|
924
905
|
delete state.lastRequest;
|
|
925
906
|
delete state.lastResponse;
|
|
926
907
|
delete state.restoredContinuation;
|
|
927
908
|
}
|
|
928
|
-
const RESPONSES_REQUEST_PROPERTY_KEYS = [
|
|
929
|
-
'model',
|
|
930
|
-
'instructions',
|
|
931
|
-
'tools',
|
|
932
|
-
'tool_choice',
|
|
933
|
-
'parallel_tool_calls',
|
|
934
|
-
'reasoning',
|
|
935
|
-
'store',
|
|
936
|
-
'stream',
|
|
937
|
-
'include',
|
|
938
|
-
'prompt_cache_key',
|
|
939
|
-
'text',
|
|
940
|
-
'client_metadata'
|
|
941
|
-
];
|
|
942
|
-
function responsesRequestPropertiesHash(request) {
|
|
943
|
-
return hashResponsesValue(Object.fromEntries(RESPONSES_REQUEST_PROPERTY_KEYS.map((key) => [key, request[key]])));
|
|
944
|
-
}
|
|
945
909
|
function hashResponsesValue(value) {
|
|
946
910
|
return createHash('sha256').update(JSON.stringify(value)).digest('hex');
|
|
947
911
|
}
|
|
948
|
-
function
|
|
949
|
-
|
|
950
|
-
|
|
912
|
+
function responsesContinuationIdentityHash(configuration) {
|
|
913
|
+
return hashResponsesValue({
|
|
914
|
+
endpoint: new URL(responsesEndpoint(configuration.baseUrl)).toString(),
|
|
915
|
+
modelId: configuration.modelId,
|
|
916
|
+
responsesEncoding: configuration.responsesEncoding ?? 'STANDARD'
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
function responsesContinuationEnabled(configuration) {
|
|
920
|
+
return (configuration.responsesPreviousResponseId === true &&
|
|
921
|
+
configuration.responsesTransport?.transport === 'WEBSOCKET');
|
|
951
922
|
}
|
|
952
923
|
function responsesCredentialFingerprint(credential) {
|
|
953
924
|
return hashResponsesValue({
|
package/dist/sdk/agent.js
CHANGED
|
@@ -1600,11 +1600,10 @@ function isModelContinuationCheckpoint(value) {
|
|
|
1600
1600
|
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
1601
1601
|
return false;
|
|
1602
1602
|
const checkpoint = value;
|
|
1603
|
-
return (checkpoint.version ===
|
|
1603
|
+
return (checkpoint.version === 2 &&
|
|
1604
1604
|
checkpoint.protocol === 'OPENAI_RESPONSES' &&
|
|
1605
1605
|
isBoundedString(checkpoint.configurationHash, 64) &&
|
|
1606
1606
|
isBoundedString(checkpoint.responseId, 1_024) &&
|
|
1607
|
-
isBoundedString(checkpoint.requestPropertiesHash, 64) &&
|
|
1608
1607
|
Number.isSafeInteger(checkpoint.inputPrefixLength) &&
|
|
1609
1608
|
checkpoint.inputPrefixLength >= 0 &&
|
|
1610
1609
|
isBoundedString(checkpoint.inputPrefixHash, 64));
|
|
@@ -33,7 +33,10 @@ function parseAgentMessageInput(value) {
|
|
|
33
33
|
return invalid();
|
|
34
34
|
const input = value;
|
|
35
35
|
if (Object.keys(input).some((key) => !['agentId', 'message', 'delivery'].includes(key)) ||
|
|
36
|
-
(input.delivery !== undefined &&
|
|
36
|
+
(input.delivery !== undefined &&
|
|
37
|
+
input.delivery !== null &&
|
|
38
|
+
input.delivery !== 'append' &&
|
|
39
|
+
input.delivery !== 'replace') ||
|
|
37
40
|
typeof input.agentId !== 'string' ||
|
|
38
41
|
input.agentId.trim().length === 0 ||
|
|
39
42
|
typeof input.message !== 'string' ||
|
|
@@ -43,7 +46,9 @@ function parseAgentMessageInput(value) {
|
|
|
43
46
|
return {
|
|
44
47
|
agentId: input.agentId.trim(),
|
|
45
48
|
message: input.message,
|
|
46
|
-
...(input.delivery ===
|
|
49
|
+
...(input.delivery === 'append' || input.delivery === 'replace'
|
|
50
|
+
? { delivery: input.delivery }
|
|
51
|
+
: {})
|
|
47
52
|
};
|
|
48
53
|
}
|
|
49
54
|
function invalid() {
|
|
@@ -62,6 +62,7 @@ function parseAgentStartInput(value) {
|
|
|
62
62
|
input.modelId !== null &&
|
|
63
63
|
(typeof input.modelId !== 'string' || input.modelId.trim().length === 0)) ||
|
|
64
64
|
(input.reasoningEffort !== undefined &&
|
|
65
|
+
input.reasoningEffort !== null &&
|
|
65
66
|
(typeof input.reasoningEffort !== 'string' ||
|
|
66
67
|
!marAgentReasoningEffortSchema.safeParse(input.reasoningEffort.trim()).success)) ||
|
|
67
68
|
(input.background !== undefined &&
|
package/dist/tools/agent-wait.js
CHANGED
|
@@ -46,11 +46,14 @@ function parseAgentWaitInput(value) {
|
|
|
46
46
|
const input = value;
|
|
47
47
|
if (Object.keys(input).some((key) => !['agentId', 'waitFor', 'waitMs'].includes(key)) ||
|
|
48
48
|
(input.agentId !== undefined &&
|
|
49
|
+
input.agentId !== null &&
|
|
49
50
|
(typeof input.agentId !== 'string' || input.agentId.trim().length === 0)) ||
|
|
50
51
|
(input.waitFor !== undefined &&
|
|
52
|
+
input.waitFor !== null &&
|
|
51
53
|
input.waitFor !== 'completion' &&
|
|
52
54
|
input.waitFor !== 'message') ||
|
|
53
55
|
(input.waitMs !== undefined &&
|
|
56
|
+
input.waitMs !== null &&
|
|
54
57
|
(!Number.isInteger(input.waitMs) ||
|
|
55
58
|
input.waitMs < TOOL_EXECUTION_LIMITS.agentWaitMinWaitMs ||
|
|
56
59
|
input.waitMs > TOOL_EXECUTION_LIMITS.agentWaitMaxWaitMs)))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/agent",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.85",
|
|
4
4
|
"description": "Embeddable MAR coding agent SDK and CLI.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"build": "node ../scripts/clean-build-output.mjs dist && tsc -p tsconfig.json",
|
|
43
43
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
44
44
|
"test:unit": "vitest run --config vitest.config.ts test/unit",
|
|
45
|
+
"analyze:session": "node test/tools/session-analyzer.mjs",
|
|
45
46
|
"benchmark:compaction": "node test/e2e/compaction-benchmark.mjs",
|
|
46
47
|
"test:performance": "vitest run --config vitest.performance.config.ts",
|
|
47
48
|
"test:memory": "node --expose-gc ./node_modules/vitest/vitest.mjs run --config vitest.memory.config.ts",
|