@nextclaw/kernel 0.6.14 → 0.6.16
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.d.ts +36 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +237 -125
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -5,8 +5,8 @@ import { APP_NAME, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, CLEAR_THINKING_TOK
|
|
|
5
5
|
import { NCP_AI_EXECUTION_METADATA_KEY, NcpEventType, createUnavailableNcpAiExecutionMetadata, normalizeAssistantText, readNcpAiExecutionMetadata, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
|
|
6
6
|
import { LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool, ncpMessageToOpenAiMessages, validateToolArgs } from "@nextclaw/ncp-agent-runtime";
|
|
7
7
|
import { createHash, createHmac, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
8
|
-
import { CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, Ingress, PANEL_APP_INLINE_HOST_CONTRACT, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode, readInlineContentHeight } from "@nextclaw/shared";
|
|
9
|
-
import { catchError, from, lastValueFrom, tap } from "rxjs";
|
|
8
|
+
import { CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_INLINE_TOKENS_SCHEMA_VERSION, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, Ingress, PANEL_APP_INLINE_HOST_CONTRACT, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode, readInlineContentHeight } from "@nextclaw/shared";
|
|
9
|
+
import { catchError, filter, from, lastValueFrom, tap } from "rxjs";
|
|
10
10
|
import { appendFileSync, chmodSync, constants, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
|
12
12
|
import { execFileSync, spawn } from "node:child_process";
|
|
@@ -692,7 +692,11 @@ function createUnavailableAiExecutionMetadataEvent(params) {
|
|
|
692
692
|
};
|
|
693
693
|
}
|
|
694
694
|
//#endregion
|
|
695
|
-
//#region src/
|
|
695
|
+
//#region src/utils/agent-run-request.utils.ts
|
|
696
|
+
function readOptionalString$11(value) {
|
|
697
|
+
if (typeof value !== "string") return;
|
|
698
|
+
return value.trim() || void 0;
|
|
699
|
+
}
|
|
696
700
|
function toAgentRunRequest(envelope) {
|
|
697
701
|
const metadata = envelope.metadata ?? {};
|
|
698
702
|
const peerId = readOptionalString$11(envelope.peerId);
|
|
@@ -730,26 +734,21 @@ function toAgentRunRequest(envelope) {
|
|
|
730
734
|
const messageSessionId = readOptionalString$11(sourceMessage.sessionId);
|
|
731
735
|
const sessionId = envelopeSessionId ?? messageSessionId;
|
|
732
736
|
if (sessionId && peerId) throw new Error("agent-run.send cannot accept both sessionId and peerId.");
|
|
733
|
-
const message = {
|
|
734
|
-
...sourceMessage,
|
|
735
|
-
sessionId: sessionId ?? "",
|
|
736
|
-
id: sourceMessage.id ?? `user-message-${randomUUID()}`,
|
|
737
|
-
role: sourceMessage.role ?? "user",
|
|
738
|
-
status: sourceMessage.status ?? "final",
|
|
739
|
-
timestamp: sourceMessage.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
740
|
-
parts: structuredClone(sourceMessage.parts)
|
|
741
|
-
};
|
|
742
737
|
return {
|
|
743
738
|
...requestMetadata,
|
|
744
739
|
sessionId,
|
|
745
740
|
peerId,
|
|
746
|
-
message
|
|
741
|
+
message: {
|
|
742
|
+
...sourceMessage,
|
|
743
|
+
sessionId: sessionId ?? "",
|
|
744
|
+
id: sourceMessage.id ?? `user-message-${randomUUID()}`,
|
|
745
|
+
role: sourceMessage.role ?? "user",
|
|
746
|
+
status: sourceMessage.status ?? "final",
|
|
747
|
+
timestamp: sourceMessage.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
748
|
+
parts: structuredClone(sourceMessage.parts)
|
|
749
|
+
}
|
|
747
750
|
};
|
|
748
751
|
}
|
|
749
|
-
function readOptionalString$11(value) {
|
|
750
|
-
if (typeof value !== "string") return;
|
|
751
|
-
return value.trim() || void 0;
|
|
752
|
-
}
|
|
753
752
|
function createCompletedAssistantMessageEvent(params) {
|
|
754
753
|
return {
|
|
755
754
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -761,6 +760,17 @@ function createCompletedAssistantMessageEvent(params) {
|
|
|
761
760
|
}
|
|
762
761
|
};
|
|
763
762
|
}
|
|
763
|
+
function createMessageSentEvent(params) {
|
|
764
|
+
return {
|
|
765
|
+
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
766
|
+
type: NcpEventType.MessageSent,
|
|
767
|
+
payload: {
|
|
768
|
+
sessionId: params.sessionId,
|
|
769
|
+
message: params.message,
|
|
770
|
+
correlationId: params.correlationId
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
}
|
|
764
774
|
function createSyntheticRunErrorEvent(params) {
|
|
765
775
|
const { correlationId, error, runId, sessionId, startedAt } = params;
|
|
766
776
|
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -807,19 +817,16 @@ function readMessageTask(message) {
|
|
|
807
817
|
return message.parts.flatMap((part) => (part.type === "text" || part.type === "rich-text" || part.type === "reasoning") && part.text.trim() ? [part.text.trim()] : [])[0] ?? "Session";
|
|
808
818
|
}
|
|
809
819
|
function resolveRunSpec(params) {
|
|
810
|
-
const {
|
|
811
|
-
const modelSource = request.model !== void 0 ? "request" : session.model !== void 0 ? "session" : "default";
|
|
812
|
-
const model = request.model ?? session.model ?? configManager.getDefaultModel();
|
|
813
|
-
const agentId = request.agentId ?? session.agentId ?? agentManager.getDefaultAgentId();
|
|
820
|
+
const { defaultAgentId, model, modelMaxTokens, request, runId, session } = params;
|
|
814
821
|
return {
|
|
815
|
-
modelSource,
|
|
822
|
+
modelSource: request.model !== void 0 ? "request" : session.model !== void 0 ? "session" : "default",
|
|
816
823
|
spec: {
|
|
817
824
|
runId,
|
|
818
825
|
runtimeId: session.agentRuntimeId,
|
|
819
|
-
agentId,
|
|
826
|
+
agentId: request.agentId ?? session.agentId ?? defaultAgentId,
|
|
820
827
|
model,
|
|
821
828
|
requestedModel: request.model ?? null,
|
|
822
|
-
maxTokens: request.maxTokens ??
|
|
829
|
+
maxTokens: request.maxTokens ?? modelMaxTokens,
|
|
823
830
|
thinkingEffort: request.thinkingEffort ?? session.thinkingEffort ?? null,
|
|
824
831
|
correlationId: request.correlationId
|
|
825
832
|
}
|
|
@@ -850,8 +857,11 @@ function attachRunSpecMetadata(params) {
|
|
|
850
857
|
metadata
|
|
851
858
|
};
|
|
852
859
|
}
|
|
860
|
+
//#endregion
|
|
861
|
+
//#region src/managers/agent-run-request.manager.ts
|
|
853
862
|
var AgentRunRequestManager = class {
|
|
854
863
|
cleanups = [];
|
|
864
|
+
observedSessionRuns = /* @__PURE__ */ new Set();
|
|
855
865
|
started = false;
|
|
856
866
|
constructor(agentRuntimeManager, agentManager, configManager, contextProviderManager, eventBus, ingress, sessionManager, sessionRunManager, toolProviderManager) {
|
|
857
867
|
this.agentRuntimeManager = agentRuntimeManager;
|
|
@@ -871,8 +881,18 @@ var AgentRunRequestManager = class {
|
|
|
871
881
|
};
|
|
872
882
|
dispose = () => {
|
|
873
883
|
while (this.cleanups.length > 0) this.cleanups.pop()?.();
|
|
884
|
+
this.observedSessionRuns.clear();
|
|
874
885
|
this.started = false;
|
|
875
886
|
};
|
|
887
|
+
listQueuedInputs = (sessionId) => {
|
|
888
|
+
return this.sessionRunManager.getSessionRun(sessionId)?.listQueuedRequests().map(this.toQueuedInput) ?? [];
|
|
889
|
+
};
|
|
890
|
+
removeQueuedInput = (sessionId, queuedInputId) => {
|
|
891
|
+
const removed = this.sessionRunManager.getSessionRun(sessionId)?.removeQueuedRequest(queuedInputId) ?? null;
|
|
892
|
+
if (!removed) return null;
|
|
893
|
+
this.publishRunQueueUpdated(sessionId);
|
|
894
|
+
return this.toQueuedInput(removed);
|
|
895
|
+
};
|
|
876
896
|
handleSendRequest = async (envelope) => {
|
|
877
897
|
if (!envelope.payload) throw new Error("Invalid agent run send request.");
|
|
878
898
|
return toRunHandle(await this.send(toAgentRunRequest(envelope.payload)));
|
|
@@ -899,41 +919,46 @@ var AgentRunRequestManager = class {
|
|
|
899
919
|
};
|
|
900
920
|
send = async (request) => {
|
|
901
921
|
const session = await this.getOrCreateSessionForRequest(request);
|
|
902
|
-
const sessionRun =
|
|
922
|
+
const sessionRun = await this.sessionRunManager.getOrCreateSessionRun(session.sessionId);
|
|
923
|
+
this.observeSessionRun(sessionRun);
|
|
903
924
|
const baseMessage = {
|
|
904
925
|
...request.message,
|
|
905
926
|
sessionId: session.sessionId
|
|
906
927
|
};
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
928
|
+
const queuedRequest = sessionRun.enqueueRequest({
|
|
929
|
+
...request,
|
|
930
|
+
sessionId: session.sessionId,
|
|
931
|
+
message: baseMessage
|
|
932
|
+
}, session);
|
|
933
|
+
const activeRequest = sessionRun.beginNextRun();
|
|
934
|
+
this.publishRunQueueUpdated(session.sessionId);
|
|
935
|
+
if (activeRequest?.id === queuedRequest.id) await this.startQueuedRun(sessionRun, activeRequest);
|
|
936
|
+
else if (activeRequest) this.startQueuedRun(sessionRun, activeRequest).catch(() => void 0);
|
|
937
|
+
return {
|
|
938
|
+
sessionId: session.sessionId,
|
|
939
|
+
userMessageId: queuedRequest.request.message.id,
|
|
940
|
+
runId: activeRequest?.id === queuedRequest.id ? activeRequest.runId : null,
|
|
941
|
+
correlationId: request.correlationId
|
|
942
|
+
};
|
|
943
|
+
};
|
|
944
|
+
startQueuedRun = async (sessionRun, activeRequest) => {
|
|
945
|
+
const { request, session } = activeRequest;
|
|
919
946
|
const requestRunStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
920
|
-
const
|
|
921
|
-
try {
|
|
922
|
-
return sessionRun.beginRun();
|
|
923
|
-
} catch (error) {
|
|
924
|
-
stopPublishingRunStatus();
|
|
925
|
-
throw error;
|
|
926
|
-
}
|
|
927
|
-
})();
|
|
947
|
+
const model = request.model ?? session.model ?? this.configManager.getDefaultModel();
|
|
928
948
|
const { modelSource, spec } = resolveRunSpec({
|
|
929
|
-
|
|
930
|
-
|
|
949
|
+
defaultAgentId: this.agentManager.getDefaultAgentId(),
|
|
950
|
+
model,
|
|
951
|
+
modelMaxTokens: this.configManager.getModelMaxTokens(model),
|
|
931
952
|
request,
|
|
932
|
-
runId:
|
|
953
|
+
runId: activeRequest.runId,
|
|
933
954
|
session
|
|
934
955
|
});
|
|
935
956
|
const message = attachRunSpecMetadata({
|
|
936
|
-
message:
|
|
957
|
+
message: {
|
|
958
|
+
...request.message,
|
|
959
|
+
sessionId: session.sessionId,
|
|
960
|
+
timestamp: requestRunStartedAt
|
|
961
|
+
},
|
|
937
962
|
modelSource,
|
|
938
963
|
request,
|
|
939
964
|
session,
|
|
@@ -945,32 +970,44 @@ var AgentRunRequestManager = class {
|
|
|
945
970
|
sessionId: session.sessionId,
|
|
946
971
|
message
|
|
947
972
|
};
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
sessionRun
|
|
973
|
+
const messageSentEvent = createMessageSentEvent({
|
|
974
|
+
sessionId: session.sessionId,
|
|
975
|
+
message,
|
|
976
|
+
correlationId: request.correlationId
|
|
953
977
|
});
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
978
|
+
await sessionRun.applyEvents([messageSentEvent]);
|
|
979
|
+
this.publishNcpEvent(messageSentEvent);
|
|
980
|
+
try {
|
|
981
|
+
const runtime = this.agentRuntimeManager.getOrCreate({
|
|
982
|
+
agentRuntimeId: session.agentRuntimeId,
|
|
959
983
|
session,
|
|
984
|
+
sessionRun
|
|
985
|
+
});
|
|
986
|
+
const contextBlocks = await this.contextProviderManager.buildContext(providerRequest);
|
|
987
|
+
const tools = await this.toolProviderManager.buildTools(providerRequest);
|
|
988
|
+
sessionRun.inbox.enqueue(message);
|
|
989
|
+
this.startRuntimeRun({
|
|
990
|
+
options: {
|
|
991
|
+
contextBlocks,
|
|
992
|
+
session,
|
|
993
|
+
sessionRun,
|
|
994
|
+
signal: activeRequest.signal,
|
|
995
|
+
tools
|
|
996
|
+
},
|
|
997
|
+
requestRunStartedAt,
|
|
998
|
+
runtime,
|
|
999
|
+
spec
|
|
1000
|
+
});
|
|
1001
|
+
} catch (error) {
|
|
1002
|
+
await this.publishRunStartupFailure({
|
|
1003
|
+
error,
|
|
1004
|
+
requestRunStartedAt,
|
|
960
1005
|
sessionRun,
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
spec
|
|
967
|
-
});
|
|
968
|
-
return {
|
|
969
|
-
sessionId: session.sessionId,
|
|
970
|
-
userMessageId: message.id,
|
|
971
|
-
runId: spec.runId,
|
|
972
|
-
correlationId: request.correlationId
|
|
973
|
-
};
|
|
1006
|
+
spec
|
|
1007
|
+
});
|
|
1008
|
+
this.startNextQueuedRun(sessionRun);
|
|
1009
|
+
throw error;
|
|
1010
|
+
}
|
|
974
1011
|
};
|
|
975
1012
|
startRuntimeRun = (params) => {
|
|
976
1013
|
const { options, requestRunStartedAt, runtime, spec } = params;
|
|
@@ -979,7 +1016,7 @@ var AgentRunRequestManager = class {
|
|
|
979
1016
|
let executionMetadataSeen = false;
|
|
980
1017
|
let runtimeFailed = false;
|
|
981
1018
|
let runStartedAt = requestRunStartedAt;
|
|
982
|
-
lastValueFrom(from(runtime.run(spec, options)).pipe(tap((event) => {
|
|
1019
|
+
lastValueFrom(from(runtime.run(spec, options)).pipe(filter((event) => event.type !== NcpEventType.MessageSent), tap((event) => {
|
|
983
1020
|
const eventsToPublish = [];
|
|
984
1021
|
if (event.type === NcpEventType.RunError) runtimeFailed = true;
|
|
985
1022
|
if (hasAiExecutionMetadata(event)) executionMetadataSeen = true;
|
|
@@ -996,10 +1033,7 @@ var AgentRunRequestManager = class {
|
|
|
996
1033
|
messageCompletedSeen = true;
|
|
997
1034
|
}
|
|
998
1035
|
eventsToPublish.push(event);
|
|
999
|
-
|
|
1000
|
-
emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1001
|
-
source: "agent-run-request"
|
|
1002
|
-
});
|
|
1036
|
+
eventsToPublish.forEach(this.publishNcpEvent);
|
|
1003
1037
|
}), catchError(async (error) => {
|
|
1004
1038
|
runtimeFailed = true;
|
|
1005
1039
|
if (!executionMetadataSeen) {
|
|
@@ -1008,10 +1042,7 @@ var AgentRunRequestManager = class {
|
|
|
1008
1042
|
sessionId: session.sessionId
|
|
1009
1043
|
});
|
|
1010
1044
|
await sessionRun.applyEvents([metadataEvent]);
|
|
1011
|
-
this.
|
|
1012
|
-
emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1013
|
-
source: "agent-run-request"
|
|
1014
|
-
});
|
|
1045
|
+
this.publishNcpEvent(metadataEvent);
|
|
1015
1046
|
}
|
|
1016
1047
|
const event = createSyntheticRunErrorEvent({
|
|
1017
1048
|
error,
|
|
@@ -1021,19 +1052,75 @@ var AgentRunRequestManager = class {
|
|
|
1021
1052
|
startedAt: runStartedAt
|
|
1022
1053
|
});
|
|
1023
1054
|
await sessionRun.applyEvents([event]);
|
|
1024
|
-
this.
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
});
|
|
1028
|
-
})), { defaultValue: void 0 }).finally(() => {
|
|
1029
|
-
if (!runtimeFailed) return;
|
|
1030
|
-
this.agentRuntimeManager.disposeRuntime({
|
|
1055
|
+
this.publishNcpEvent(event);
|
|
1056
|
+
})), { defaultValue: void 0 }).finally(async () => {
|
|
1057
|
+
if (runtimeFailed) await this.agentRuntimeManager.disposeRuntime({
|
|
1031
1058
|
agentRuntimeId: session.agentRuntimeId,
|
|
1032
1059
|
session,
|
|
1033
1060
|
sessionRun
|
|
1034
1061
|
}).catch(() => void 0);
|
|
1062
|
+
this.startNextQueuedRun(sessionRun);
|
|
1063
|
+
});
|
|
1064
|
+
};
|
|
1065
|
+
publishRunStartupFailure = async (params) => {
|
|
1066
|
+
const { error, requestRunStartedAt, sessionRun, spec } = params;
|
|
1067
|
+
const metadataEvent = createUnavailableAiExecutionMetadataEvent({
|
|
1068
|
+
spec,
|
|
1069
|
+
sessionId: sessionRun.sessionId
|
|
1070
|
+
});
|
|
1071
|
+
const errorEvent = createSyntheticRunErrorEvent({
|
|
1072
|
+
error,
|
|
1073
|
+
runId: spec.runId,
|
|
1074
|
+
sessionId: sessionRun.sessionId,
|
|
1075
|
+
correlationId: spec.correlationId,
|
|
1076
|
+
startedAt: requestRunStartedAt
|
|
1035
1077
|
});
|
|
1078
|
+
await sessionRun.applyEvents([metadataEvent, errorEvent]);
|
|
1079
|
+
this.publishNcpEvent(metadataEvent);
|
|
1080
|
+
this.publishNcpEvent(errorEvent);
|
|
1036
1081
|
};
|
|
1082
|
+
startNextQueuedRun = (sessionRun) => {
|
|
1083
|
+
const nextRequest = sessionRun.beginNextRun();
|
|
1084
|
+
if (!nextRequest) return;
|
|
1085
|
+
this.publishRunQueueUpdated(sessionRun.sessionId);
|
|
1086
|
+
this.startQueuedRun(sessionRun, nextRequest).catch(() => void 0);
|
|
1087
|
+
};
|
|
1088
|
+
observeSessionRun = (sessionRun) => {
|
|
1089
|
+
if (this.observedSessionRuns.has(sessionRun)) return;
|
|
1090
|
+
this.observedSessionRuns.add(sessionRun);
|
|
1091
|
+
const stop = sessionRun.onStatusChange((status) => {
|
|
1092
|
+
this.eventBus.emit(eventKeys.sessionRunStatus, {
|
|
1093
|
+
sessionKey: sessionRun.sessionId,
|
|
1094
|
+
status
|
|
1095
|
+
}, {
|
|
1096
|
+
emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1097
|
+
source: "agent-run-request"
|
|
1098
|
+
});
|
|
1099
|
+
});
|
|
1100
|
+
this.cleanups.push(() => {
|
|
1101
|
+
stop();
|
|
1102
|
+
this.observedSessionRuns.delete(sessionRun);
|
|
1103
|
+
});
|
|
1104
|
+
};
|
|
1105
|
+
publishRunQueueUpdated = (sessionId) => {
|
|
1106
|
+
this.eventBus.emit(eventKeys.sessionRunQueueUpdated, { sessionKey: sessionId }, {
|
|
1107
|
+
emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1108
|
+
source: "agent-run-request"
|
|
1109
|
+
});
|
|
1110
|
+
};
|
|
1111
|
+
publishNcpEvent = (event) => {
|
|
1112
|
+
this.eventBus.emit(eventKeys.ncpEvent, event, {
|
|
1113
|
+
emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1114
|
+
source: "agent-run-request"
|
|
1115
|
+
});
|
|
1116
|
+
};
|
|
1117
|
+
toQueuedInput = (queuedRequest) => ({
|
|
1118
|
+
id: queuedRequest.id,
|
|
1119
|
+
sessionId: queuedRequest.request.message.sessionId,
|
|
1120
|
+
enqueuedAt: queuedRequest.enqueuedAt,
|
|
1121
|
+
message: structuredClone(queuedRequest.request.message),
|
|
1122
|
+
metadata: structuredClone(queuedRequest.request.metadata ?? {})
|
|
1123
|
+
});
|
|
1037
1124
|
getOrCreateSessionForRequest = async (request) => {
|
|
1038
1125
|
const sessionMaterialization = readSessionMaterialization(request.metadata ?? {});
|
|
1039
1126
|
if (sessionMaterialization && (request.sessionId || request.peerId)) throw new Error("session_materialization requires a new session request.");
|
|
@@ -7344,6 +7431,7 @@ var SessionRun = class {
|
|
|
7344
7431
|
inbox = new MessageInbox();
|
|
7345
7432
|
sessionId;
|
|
7346
7433
|
statusListeners = /* @__PURE__ */ new Set();
|
|
7434
|
+
queuedRequests = [];
|
|
7347
7435
|
activeRunId = null;
|
|
7348
7436
|
activeRunController = null;
|
|
7349
7437
|
constructor(seed, stateManager = new DefaultNcpAgentConversationStateManager()) {
|
|
@@ -7369,32 +7457,52 @@ var SessionRun = class {
|
|
|
7369
7457
|
this.statusListeners.delete(listener);
|
|
7370
7458
|
};
|
|
7371
7459
|
};
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
const
|
|
7375
|
-
|
|
7460
|
+
enqueueRequest = (request, session) => {
|
|
7461
|
+
const wasBusy = this.isBusy();
|
|
7462
|
+
const queuedRequest = {
|
|
7463
|
+
id: `queued-input-${randomUUID()}`,
|
|
7464
|
+
runId: `agent-run-${randomUUID()}`,
|
|
7465
|
+
enqueuedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7466
|
+
request: structuredClone(request),
|
|
7467
|
+
session: structuredClone(session)
|
|
7468
|
+
};
|
|
7469
|
+
this.queuedRequests.push(queuedRequest);
|
|
7470
|
+
this.emitStatusChangeIfNeeded(wasBusy);
|
|
7471
|
+
return structuredClone(queuedRequest);
|
|
7472
|
+
};
|
|
7473
|
+
listQueuedRequests = () => structuredClone(this.queuedRequests);
|
|
7474
|
+
removeQueuedRequest = (queuedRequestId) => {
|
|
7475
|
+
const index = this.queuedRequests.findIndex(({ id }) => id === queuedRequestId);
|
|
7476
|
+
if (index < 0) return null;
|
|
7477
|
+
const wasBusy = this.isBusy();
|
|
7478
|
+
const [removed] = this.queuedRequests.splice(index, 1);
|
|
7479
|
+
this.emitStatusChangeIfNeeded(wasBusy);
|
|
7480
|
+
return removed ? structuredClone(removed) : null;
|
|
7481
|
+
};
|
|
7482
|
+
beginNextRun = () => {
|
|
7483
|
+
if (this.activeRunId) return null;
|
|
7484
|
+
const wasBusy = this.isBusy();
|
|
7485
|
+
const queuedRequest = this.queuedRequests.shift();
|
|
7486
|
+
if (!queuedRequest) return null;
|
|
7376
7487
|
const controller = new AbortController();
|
|
7377
|
-
this.activeRunId = runId;
|
|
7488
|
+
this.activeRunId = queuedRequest.runId;
|
|
7378
7489
|
this.activeRunController = controller;
|
|
7379
|
-
this.emitStatusChangeIfNeeded(
|
|
7490
|
+
this.emitStatusChangeIfNeeded(wasBusy);
|
|
7380
7491
|
return {
|
|
7381
|
-
|
|
7492
|
+
...structuredClone(queuedRequest),
|
|
7382
7493
|
signal: controller.signal
|
|
7383
7494
|
};
|
|
7384
7495
|
};
|
|
7385
7496
|
abortRun = (runId, reason) => {
|
|
7386
7497
|
if (!this.activeRunId || !this.activeRunController) return false;
|
|
7387
7498
|
if (runId && this.activeRunId !== runId) return false;
|
|
7388
|
-
const wasRunning = this.isRunning();
|
|
7389
7499
|
this.activeRunController.abort(reason);
|
|
7390
|
-
this.activeRunController = null;
|
|
7391
|
-
this.activeRunId = null;
|
|
7392
|
-
this.emitStatusChangeIfNeeded(wasRunning);
|
|
7393
7500
|
return true;
|
|
7394
7501
|
};
|
|
7395
7502
|
isRunning = () => this.activeRunId !== null;
|
|
7503
|
+
isBusy = () => this.isRunning() || this.queuedRequests.length > 0;
|
|
7396
7504
|
dispose = () => {
|
|
7397
|
-
const
|
|
7505
|
+
const wasBusy = this.isBusy();
|
|
7398
7506
|
this.activeRunController?.abort({
|
|
7399
7507
|
code: "abort-error",
|
|
7400
7508
|
message: "Session run owner was disposed; the current run was cancelled.",
|
|
@@ -7402,33 +7510,46 @@ var SessionRun = class {
|
|
|
7402
7510
|
});
|
|
7403
7511
|
this.activeRunController = null;
|
|
7404
7512
|
this.activeRunId = null;
|
|
7405
|
-
this.
|
|
7513
|
+
this.queuedRequests.length = 0;
|
|
7514
|
+
this.emitStatusChangeIfNeeded(wasBusy);
|
|
7406
7515
|
this.statusListeners.clear();
|
|
7407
7516
|
};
|
|
7408
7517
|
applyRunEvents = (events) => {
|
|
7409
|
-
const
|
|
7518
|
+
const wasBusy = this.isBusy();
|
|
7410
7519
|
for (const event of events) {
|
|
7411
7520
|
if (event.type === NcpEventType.RunStarted && event.payload.runId) this.activeRunId = event.payload.runId;
|
|
7412
|
-
if ((event.type === NcpEventType.RunFinished || event.type === NcpEventType.RunError) && (!event.payload.runId || event.payload.runId === this.activeRunId)) {
|
|
7521
|
+
if ((event.type === NcpEventType.MessageAbort || event.type === NcpEventType.RunFinished || event.type === NcpEventType.RunError) && (!event.payload.runId || event.payload.runId === this.activeRunId)) {
|
|
7413
7522
|
this.activeRunId = null;
|
|
7414
7523
|
this.activeRunController = null;
|
|
7415
7524
|
}
|
|
7416
7525
|
}
|
|
7417
|
-
this.emitStatusChangeIfNeeded(
|
|
7526
|
+
this.emitStatusChangeIfNeeded(wasBusy);
|
|
7418
7527
|
};
|
|
7419
|
-
emitStatusChangeIfNeeded = (
|
|
7420
|
-
const
|
|
7421
|
-
if (
|
|
7422
|
-
for (const listener of [...this.statusListeners]) listener(
|
|
7528
|
+
emitStatusChangeIfNeeded = (wasBusy) => {
|
|
7529
|
+
const busy = this.isBusy();
|
|
7530
|
+
if (busy === wasBusy) return;
|
|
7531
|
+
for (const listener of [...this.statusListeners]) listener(busy ? "running" : "idle");
|
|
7423
7532
|
};
|
|
7424
7533
|
};
|
|
7425
7534
|
var SessionRunManager = class {
|
|
7426
7535
|
runs = /* @__PURE__ */ new Map();
|
|
7536
|
+
pendingCreations = /* @__PURE__ */ new Map();
|
|
7427
7537
|
constructor(sessionManager) {
|
|
7428
7538
|
this.sessionManager = sessionManager;
|
|
7429
7539
|
}
|
|
7430
7540
|
getSessionRun = (sessionId) => this.runs.get(sessionId) ?? null;
|
|
7431
|
-
isSessionRunning = (sessionId) => this.runs.get(sessionId.trim())?.
|
|
7541
|
+
isSessionRunning = (sessionId) => this.runs.get(sessionId.trim())?.isBusy() ?? false;
|
|
7542
|
+
getOrCreateSessionRun = async (sessionId) => {
|
|
7543
|
+
const existing = this.getSessionRun(sessionId);
|
|
7544
|
+
if (existing) return existing;
|
|
7545
|
+
const pending = this.pendingCreations.get(sessionId);
|
|
7546
|
+
if (pending) return await pending;
|
|
7547
|
+
const creation = this.createSessionRun(sessionId).finally(() => {
|
|
7548
|
+
this.pendingCreations.delete(sessionId);
|
|
7549
|
+
});
|
|
7550
|
+
this.pendingCreations.set(sessionId, creation);
|
|
7551
|
+
return await creation;
|
|
7552
|
+
};
|
|
7432
7553
|
createSessionRun = async (sessionId) => {
|
|
7433
7554
|
if (this.runs.has(sessionId)) throw new Error(`Session run already exists: ${sessionId}`);
|
|
7434
7555
|
const run = new SessionRun({
|
|
@@ -7447,6 +7568,7 @@ var SessionRunManager = class {
|
|
|
7447
7568
|
dispose = () => {
|
|
7448
7569
|
for (const run of this.runs.values()) run.dispose();
|
|
7449
7570
|
this.runs.clear();
|
|
7571
|
+
this.pendingCreations.clear();
|
|
7450
7572
|
};
|
|
7451
7573
|
};
|
|
7452
7574
|
//#endregion
|
|
@@ -9494,7 +9616,6 @@ var NcpAgentRuntimeWrapper = class {
|
|
|
9494
9616
|
const messages = sessionRun.inbox.drain();
|
|
9495
9617
|
let executionMetadataSeen = false;
|
|
9496
9618
|
try {
|
|
9497
|
-
for (const event of this.toMessageSentEvents(messages, spec, sessionRun.sessionId)) yield await this.applyEvent(sessionRun, event);
|
|
9498
9619
|
const input = {
|
|
9499
9620
|
sessionId: sessionRun.sessionId,
|
|
9500
9621
|
runId: spec.runId,
|
|
@@ -9545,15 +9666,6 @@ var NcpAgentRuntimeWrapper = class {
|
|
|
9545
9666
|
});
|
|
9546
9667
|
return this.runtime;
|
|
9547
9668
|
};
|
|
9548
|
-
toMessageSentEvents = (messages, spec, sessionId) => messages.map((message) => ({
|
|
9549
|
-
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9550
|
-
type: NcpEventType.MessageSent,
|
|
9551
|
-
payload: {
|
|
9552
|
-
sessionId,
|
|
9553
|
-
message,
|
|
9554
|
-
correlationId: spec.correlationId
|
|
9555
|
-
}
|
|
9556
|
-
}));
|
|
9557
9669
|
buildMetadata = (session, spec) => ({
|
|
9558
9670
|
...session.metadata,
|
|
9559
9671
|
agentId: spec.agentId,
|
|
@@ -10386,21 +10498,21 @@ function readString$2(value) {
|
|
|
10386
10498
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
10387
10499
|
}
|
|
10388
10500
|
function readWorkspaceReferences(metadata) {
|
|
10389
|
-
const
|
|
10390
|
-
|
|
10501
|
+
const raw = metadata?.[CHAT_INLINE_TOKENS_METADATA_KEY];
|
|
10502
|
+
const rawTokens = Array.isArray(raw) ? raw : isRecord$2(raw) && raw.schemaVersion === CHAT_INLINE_TOKENS_SCHEMA_VERSION && Array.isArray(raw.items) ? raw.items : null;
|
|
10503
|
+
if (!rawTokens) return [];
|
|
10391
10504
|
const references = [];
|
|
10392
10505
|
const seen = /* @__PURE__ */ new Set();
|
|
10393
10506
|
for (const rawToken of rawTokens) {
|
|
10394
10507
|
if (!isRecord$2(rawToken)) continue;
|
|
10395
|
-
const
|
|
10396
|
-
const
|
|
10397
|
-
const key = readString$2(token.key);
|
|
10508
|
+
const kind = rawToken.kind === CHAT_WORKSPACE_FILE_TOKEN_KIND ? CHAT_WORKSPACE_FILE_TOKEN_KIND : rawToken.kind === CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND ? CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND : null;
|
|
10509
|
+
const key = readString$2(rawToken.key);
|
|
10398
10510
|
if (!kind || !key || seen.has(`${kind}:${key}`)) continue;
|
|
10399
10511
|
seen.add(`${kind}:${key}`);
|
|
10400
10512
|
references.push({
|
|
10401
10513
|
kind,
|
|
10402
10514
|
key,
|
|
10403
|
-
label: readString$2(
|
|
10515
|
+
label: readString$2(rawToken.label) ?? key
|
|
10404
10516
|
});
|
|
10405
10517
|
}
|
|
10406
10518
|
return references;
|