@agentxjs/runtime 1.5.11 → 1.6.0
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.js +397 -274
- package/dist/index.js.map +7 -6
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -410,7 +410,7 @@ class AgentInteractor {
|
|
|
410
410
|
}
|
|
411
411
|
// src/internal/RuntimeAgent.ts
|
|
412
412
|
import { createAgent } from "@agentxjs/agent";
|
|
413
|
-
import { createLogger as
|
|
413
|
+
import { createLogger as createLogger8 } from "@agentxjs/common";
|
|
414
414
|
|
|
415
415
|
// src/environment/ClaudeReceptor.ts
|
|
416
416
|
import { createLogger as createLogger4 } from "@agentxjs/common";
|
|
@@ -658,7 +658,76 @@ class ClaudeReceptor {
|
|
|
658
658
|
}
|
|
659
659
|
|
|
660
660
|
// src/environment/ClaudeEffector.ts
|
|
661
|
-
import {
|
|
661
|
+
import { Subject as Subject3, TimeoutError } from "rxjs";
|
|
662
|
+
import { timeout } from "rxjs/operators";
|
|
663
|
+
import { createLogger as createLogger7 } from "@agentxjs/common";
|
|
664
|
+
|
|
665
|
+
// src/environment/helpers.ts
|
|
666
|
+
function isTextPart(part) {
|
|
667
|
+
return part.type === "text";
|
|
668
|
+
}
|
|
669
|
+
function isImagePart(part) {
|
|
670
|
+
return part.type === "image";
|
|
671
|
+
}
|
|
672
|
+
function isFilePart(part) {
|
|
673
|
+
return part.type === "file";
|
|
674
|
+
}
|
|
675
|
+
function buildSDKContent(message) {
|
|
676
|
+
if (typeof message.content === "string") {
|
|
677
|
+
return message.content;
|
|
678
|
+
}
|
|
679
|
+
if (!Array.isArray(message.content)) {
|
|
680
|
+
return "";
|
|
681
|
+
}
|
|
682
|
+
const parts = message.content;
|
|
683
|
+
const hasNonTextParts = parts.some((p) => !isTextPart(p));
|
|
684
|
+
if (!hasNonTextParts) {
|
|
685
|
+
return parts.filter(isTextPart).map((p) => p.text).join(`
|
|
686
|
+
`);
|
|
687
|
+
}
|
|
688
|
+
return parts.map((part) => {
|
|
689
|
+
if (isTextPart(part)) {
|
|
690
|
+
return {
|
|
691
|
+
type: "text",
|
|
692
|
+
text: part.text
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
if (isImagePart(part)) {
|
|
696
|
+
return {
|
|
697
|
+
type: "image",
|
|
698
|
+
source: {
|
|
699
|
+
type: "base64",
|
|
700
|
+
media_type: part.mediaType,
|
|
701
|
+
data: part.data
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
if (isFilePart(part)) {
|
|
706
|
+
return {
|
|
707
|
+
type: "document",
|
|
708
|
+
source: {
|
|
709
|
+
type: "base64",
|
|
710
|
+
media_type: part.mediaType,
|
|
711
|
+
data: part.data
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
return { type: "text", text: "" };
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
function buildSDKUserMessage(message, sessionId) {
|
|
719
|
+
return {
|
|
720
|
+
type: "user",
|
|
721
|
+
message: { role: "user", content: buildSDKContent(message) },
|
|
722
|
+
parent_tool_use_id: null,
|
|
723
|
+
session_id: sessionId
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// src/environment/SDKQueryLifecycle.ts
|
|
728
|
+
import {
|
|
729
|
+
query
|
|
730
|
+
} from "@anthropic-ai/claude-agent-sdk";
|
|
662
731
|
import { Subject as Subject2 } from "rxjs";
|
|
663
732
|
import { createLogger as createLogger6 } from "@agentxjs/common";
|
|
664
733
|
|
|
@@ -699,6 +768,7 @@ function buildOptions(context, abortController) {
|
|
|
699
768
|
if (!env.PATH && process.env.PATH) {
|
|
700
769
|
env.PATH = process.env.PATH;
|
|
701
770
|
}
|
|
771
|
+
env.AGENTX_ENVIRONMENT = "true";
|
|
702
772
|
if (context.baseUrl) {
|
|
703
773
|
env.ANTHROPIC_BASE_URL = context.baseUrl;
|
|
704
774
|
}
|
|
@@ -763,68 +833,6 @@ function buildOptions(context, abortController) {
|
|
|
763
833
|
return options;
|
|
764
834
|
}
|
|
765
835
|
|
|
766
|
-
// src/environment/helpers.ts
|
|
767
|
-
function isTextPart(part) {
|
|
768
|
-
return part.type === "text";
|
|
769
|
-
}
|
|
770
|
-
function isImagePart(part) {
|
|
771
|
-
return part.type === "image";
|
|
772
|
-
}
|
|
773
|
-
function isFilePart(part) {
|
|
774
|
-
return part.type === "file";
|
|
775
|
-
}
|
|
776
|
-
function buildSDKContent(message) {
|
|
777
|
-
if (typeof message.content === "string") {
|
|
778
|
-
return message.content;
|
|
779
|
-
}
|
|
780
|
-
if (!Array.isArray(message.content)) {
|
|
781
|
-
return "";
|
|
782
|
-
}
|
|
783
|
-
const parts = message.content;
|
|
784
|
-
const hasNonTextParts = parts.some((p) => !isTextPart(p));
|
|
785
|
-
if (!hasNonTextParts) {
|
|
786
|
-
return parts.filter(isTextPart).map((p) => p.text).join(`
|
|
787
|
-
`);
|
|
788
|
-
}
|
|
789
|
-
return parts.map((part) => {
|
|
790
|
-
if (isTextPart(part)) {
|
|
791
|
-
return {
|
|
792
|
-
type: "text",
|
|
793
|
-
text: part.text
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
if (isImagePart(part)) {
|
|
797
|
-
return {
|
|
798
|
-
type: "image",
|
|
799
|
-
source: {
|
|
800
|
-
type: "base64",
|
|
801
|
-
media_type: part.mediaType,
|
|
802
|
-
data: part.data
|
|
803
|
-
}
|
|
804
|
-
};
|
|
805
|
-
}
|
|
806
|
-
if (isFilePart(part)) {
|
|
807
|
-
return {
|
|
808
|
-
type: "document",
|
|
809
|
-
source: {
|
|
810
|
-
type: "base64",
|
|
811
|
-
media_type: part.mediaType,
|
|
812
|
-
data: part.data
|
|
813
|
-
}
|
|
814
|
-
};
|
|
815
|
-
}
|
|
816
|
-
return { type: "text", text: "" };
|
|
817
|
-
});
|
|
818
|
-
}
|
|
819
|
-
function buildSDKUserMessage(message, sessionId) {
|
|
820
|
-
return {
|
|
821
|
-
type: "user",
|
|
822
|
-
message: { role: "user", content: buildSDKContent(message) },
|
|
823
|
-
parent_tool_use_id: null,
|
|
824
|
-
session_id: sessionId
|
|
825
|
-
};
|
|
826
|
-
}
|
|
827
|
-
|
|
828
836
|
// src/environment/observableToAsyncIterable.ts
|
|
829
837
|
async function* observableToAsyncIterable(observable) {
|
|
830
838
|
const queue = [];
|
|
@@ -889,97 +897,28 @@ async function* observableToAsyncIterable(observable) {
|
|
|
889
897
|
}
|
|
890
898
|
}
|
|
891
899
|
|
|
892
|
-
// src/environment/
|
|
893
|
-
var logger6 = createLogger6("
|
|
894
|
-
var DEFAULT_TIMEOUT = 30000;
|
|
900
|
+
// src/environment/SDKQueryLifecycle.ts
|
|
901
|
+
var logger6 = createLogger6("environment/SDKQueryLifecycle");
|
|
895
902
|
|
|
896
|
-
class
|
|
903
|
+
class SDKQueryLifecycle {
|
|
897
904
|
config;
|
|
898
|
-
|
|
905
|
+
callbacks;
|
|
899
906
|
promptSubject = new Subject2;
|
|
900
|
-
currentAbortController = null;
|
|
901
907
|
claudeQuery = null;
|
|
902
908
|
isInitialized = false;
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
constructor(config, receptor) {
|
|
909
|
+
abortController = null;
|
|
910
|
+
constructor(config, callbacks = {}) {
|
|
906
911
|
this.config = config;
|
|
907
|
-
this.
|
|
912
|
+
this.callbacks = callbacks;
|
|
908
913
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
agentId: this.config.agentId
|
|
912
|
-
});
|
|
913
|
-
consumer.on("user_message", async (event) => {
|
|
914
|
-
const typedEvent = event;
|
|
915
|
-
logger6.debug("user_message event received", {
|
|
916
|
-
eventAgentId: typedEvent.context?.agentId,
|
|
917
|
-
myAgentId: this.config.agentId,
|
|
918
|
-
matches: typedEvent.context?.agentId === this.config.agentId
|
|
919
|
-
});
|
|
920
|
-
if (typedEvent.context?.agentId !== this.config.agentId) {
|
|
921
|
-
return;
|
|
922
|
-
}
|
|
923
|
-
const message = typedEvent.data;
|
|
924
|
-
const meta = {
|
|
925
|
-
requestId: typedEvent.requestId || "",
|
|
926
|
-
context: typedEvent.context || {}
|
|
927
|
-
};
|
|
928
|
-
await this.send(message, meta);
|
|
929
|
-
});
|
|
930
|
-
consumer.on("interrupt", (event) => {
|
|
931
|
-
const typedEvent = event;
|
|
932
|
-
if (typedEvent.context?.agentId !== this.config.agentId) {
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
const meta = {
|
|
936
|
-
requestId: typedEvent.requestId || "",
|
|
937
|
-
context: typedEvent.context || {}
|
|
938
|
-
};
|
|
939
|
-
this.interrupt(meta);
|
|
940
|
-
});
|
|
941
|
-
}
|
|
942
|
-
async send(message, meta) {
|
|
943
|
-
this.wasInterrupted = false;
|
|
944
|
-
this.currentAbortController = new AbortController;
|
|
945
|
-
this.currentMeta = meta;
|
|
946
|
-
const timeout = this.config.timeout ?? DEFAULT_TIMEOUT;
|
|
947
|
-
const timeoutId = setTimeout(() => {
|
|
948
|
-
logger6.warn("Request timeout", { timeout });
|
|
949
|
-
this.currentAbortController?.abort(new Error(`Request timeout after ${timeout}ms`));
|
|
950
|
-
}, timeout);
|
|
951
|
-
try {
|
|
952
|
-
await this.initialize(this.currentAbortController);
|
|
953
|
-
const sessionId = this.config.sessionId || "default";
|
|
954
|
-
const sdkUserMessage = buildSDKUserMessage(message, sessionId);
|
|
955
|
-
logger6.debug("Sending message to Claude", {
|
|
956
|
-
content: typeof message.content === "string" ? message.content.substring(0, 80) : "[structured]",
|
|
957
|
-
timeout,
|
|
958
|
-
requestId: meta.requestId
|
|
959
|
-
});
|
|
960
|
-
this.promptSubject.next(sdkUserMessage);
|
|
961
|
-
} finally {
|
|
962
|
-
clearTimeout(timeoutId);
|
|
963
|
-
this.currentAbortController = null;
|
|
964
|
-
this.wasInterrupted = false;
|
|
965
|
-
}
|
|
914
|
+
get initialized() {
|
|
915
|
+
return this.isInitialized;
|
|
966
916
|
}
|
|
967
|
-
|
|
968
|
-
if (this.claudeQuery) {
|
|
969
|
-
logger6.debug("Interrupting Claude query", { requestId: meta?.requestId });
|
|
970
|
-
this.wasInterrupted = true;
|
|
971
|
-
if (meta) {
|
|
972
|
-
this.currentMeta = meta;
|
|
973
|
-
}
|
|
974
|
-
this.claudeQuery.interrupt().catch((err) => {
|
|
975
|
-
logger6.debug("SDK interrupt() error (may be expected)", { error: err });
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
async initialize(abortController) {
|
|
917
|
+
async initialize() {
|
|
980
918
|
if (this.isInitialized)
|
|
981
919
|
return;
|
|
982
|
-
logger6.info("Initializing
|
|
920
|
+
logger6.info("Initializing SDKQueryLifecycle");
|
|
921
|
+
this.abortController = new AbortController;
|
|
983
922
|
const context = {
|
|
984
923
|
apiKey: this.config.apiKey,
|
|
985
924
|
baseUrl: this.config.baseUrl,
|
|
@@ -989,7 +928,7 @@ class ClaudeEffector {
|
|
|
989
928
|
resume: this.config.resumeSessionId,
|
|
990
929
|
mcpServers: this.config.mcpServers
|
|
991
930
|
};
|
|
992
|
-
const sdkOptions = buildOptions(context, abortController);
|
|
931
|
+
const sdkOptions = buildOptions(context, this.abortController);
|
|
993
932
|
const promptStream = observableToAsyncIterable(this.promptSubject);
|
|
994
933
|
this.claudeQuery = query({
|
|
995
934
|
prompt: promptStream,
|
|
@@ -997,7 +936,47 @@ class ClaudeEffector {
|
|
|
997
936
|
});
|
|
998
937
|
this.isInitialized = true;
|
|
999
938
|
this.startBackgroundListener();
|
|
1000
|
-
logger6.info("
|
|
939
|
+
logger6.info("SDKQueryLifecycle initialized");
|
|
940
|
+
}
|
|
941
|
+
send(message) {
|
|
942
|
+
if (!this.isInitialized) {
|
|
943
|
+
throw new Error("SDKQueryLifecycle not initialized. Call initialize() first.");
|
|
944
|
+
}
|
|
945
|
+
this.promptSubject.next(message);
|
|
946
|
+
}
|
|
947
|
+
interrupt() {
|
|
948
|
+
if (this.claudeQuery) {
|
|
949
|
+
logger6.debug("Interrupting SDK query");
|
|
950
|
+
this.claudeQuery.interrupt().catch((err) => {
|
|
951
|
+
logger6.debug("SDK interrupt() error (may be expected)", { error: err });
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
reset() {
|
|
956
|
+
logger6.debug("Resetting SDKQueryLifecycle");
|
|
957
|
+
this.promptSubject.complete();
|
|
958
|
+
if (this.claudeQuery) {
|
|
959
|
+
this.claudeQuery.interrupt().catch((err) => {
|
|
960
|
+
logger6.debug("SDK interrupt() during reset (may be expected)", { error: err });
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
this.isInitialized = false;
|
|
964
|
+
this.claudeQuery = null;
|
|
965
|
+
this.abortController = null;
|
|
966
|
+
this.promptSubject = new Subject2;
|
|
967
|
+
}
|
|
968
|
+
dispose() {
|
|
969
|
+
logger6.debug("Disposing SDKQueryLifecycle");
|
|
970
|
+
if (this.claudeQuery) {
|
|
971
|
+
this.claudeQuery.interrupt().catch((err) => {
|
|
972
|
+
logger6.debug("SDK interrupt() during dispose (may be expected)", { error: err });
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
if (this.abortController) {
|
|
976
|
+
this.abortController.abort();
|
|
977
|
+
}
|
|
978
|
+
this.reset();
|
|
979
|
+
logger6.debug("SDKQueryLifecycle disposed");
|
|
1001
980
|
}
|
|
1002
981
|
startBackgroundListener() {
|
|
1003
982
|
(async () => {
|
|
@@ -1006,50 +985,36 @@ class ClaudeEffector {
|
|
|
1006
985
|
logger6.debug("SDK message received", {
|
|
1007
986
|
type: sdkMsg.type,
|
|
1008
987
|
subtype: sdkMsg.subtype,
|
|
1009
|
-
sessionId: sdkMsg.session_id
|
|
1010
|
-
hasCurrentMeta: !!this.currentMeta
|
|
988
|
+
sessionId: sdkMsg.session_id
|
|
1011
989
|
});
|
|
1012
|
-
if (sdkMsg.
|
|
1013
|
-
this.
|
|
990
|
+
if (sdkMsg.session_id && this.callbacks.onSessionIdCaptured) {
|
|
991
|
+
this.callbacks.onSessionIdCaptured(sdkMsg.session_id);
|
|
1014
992
|
}
|
|
1015
|
-
if (sdkMsg.type === "
|
|
1016
|
-
this.
|
|
993
|
+
if (sdkMsg.type === "stream_event") {
|
|
994
|
+
this.callbacks.onStreamEvent?.(sdkMsg);
|
|
1017
995
|
}
|
|
1018
|
-
if (sdkMsg.
|
|
1019
|
-
this.
|
|
996
|
+
if (sdkMsg.type === "user") {
|
|
997
|
+
this.callbacks.onUserMessage?.(sdkMsg);
|
|
1020
998
|
}
|
|
1021
999
|
if (sdkMsg.type === "result") {
|
|
1022
|
-
const resultMsg = sdkMsg;
|
|
1023
|
-
logger6.info("SDK result received (full)", {
|
|
1024
|
-
fullResult: JSON.stringify(sdkMsg, null, 2)
|
|
1025
|
-
});
|
|
1026
1000
|
logger6.info("SDK result received", {
|
|
1027
|
-
subtype:
|
|
1028
|
-
|
|
1029
|
-
errors: resultMsg.errors,
|
|
1030
|
-
wasInterrupted: this.wasInterrupted
|
|
1001
|
+
subtype: sdkMsg.subtype,
|
|
1002
|
+
is_error: sdkMsg.is_error
|
|
1031
1003
|
});
|
|
1032
|
-
|
|
1033
|
-
this.receptor.emitInterrupted("user_interrupt", this.currentMeta || undefined);
|
|
1034
|
-
} else if (resultMsg.is_error && this.currentMeta) {
|
|
1035
|
-
const fullResult = sdkMsg;
|
|
1036
|
-
const errorMessage = fullResult.error?.message || fullResult.errors?.join(", ") || (typeof fullResult.result === "string" ? fullResult.result : null) || "An error occurred";
|
|
1037
|
-
const errorCode = fullResult.error?.type || resultMsg.subtype || "api_error";
|
|
1038
|
-
this.receptor.emitError(errorMessage, errorCode, this.currentMeta);
|
|
1039
|
-
}
|
|
1004
|
+
this.callbacks.onResult?.(sdkMsg);
|
|
1040
1005
|
}
|
|
1041
1006
|
}
|
|
1007
|
+
this.callbacks.onListenerExit?.("normal");
|
|
1042
1008
|
} catch (error) {
|
|
1043
1009
|
if (this.isAbortError(error)) {
|
|
1044
1010
|
logger6.debug("Background listener aborted (expected during interrupt)");
|
|
1045
|
-
this.
|
|
1011
|
+
this.callbacks.onListenerExit?.("abort");
|
|
1046
1012
|
} else {
|
|
1047
1013
|
logger6.error("Background listener error", { error });
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
this.receptor.emitError(errorMessage, "runtime_error", this.currentMeta);
|
|
1051
|
-
}
|
|
1014
|
+
this.callbacks.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
1015
|
+
this.callbacks.onListenerExit?.("error");
|
|
1052
1016
|
}
|
|
1017
|
+
this.reset();
|
|
1053
1018
|
}
|
|
1054
1019
|
})();
|
|
1055
1020
|
}
|
|
@@ -1064,18 +1029,176 @@ class ClaudeEffector {
|
|
|
1064
1029
|
}
|
|
1065
1030
|
return false;
|
|
1066
1031
|
}
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
// src/environment/ClaudeEffector.ts
|
|
1035
|
+
var logger7 = createLogger7("environment/ClaudeEffector");
|
|
1036
|
+
var DEFAULT_TIMEOUT = 600000;
|
|
1037
|
+
|
|
1038
|
+
class ClaudeEffector {
|
|
1039
|
+
config;
|
|
1040
|
+
receptor;
|
|
1041
|
+
queryLifecycle;
|
|
1042
|
+
currentMeta = null;
|
|
1043
|
+
wasInterrupted = false;
|
|
1044
|
+
pendingRequest$ = null;
|
|
1045
|
+
pendingSubscription = null;
|
|
1046
|
+
constructor(config, receptor) {
|
|
1047
|
+
this.config = config;
|
|
1048
|
+
this.receptor = receptor;
|
|
1049
|
+
this.queryLifecycle = new SDKQueryLifecycle({
|
|
1050
|
+
apiKey: config.apiKey,
|
|
1051
|
+
baseUrl: config.baseUrl,
|
|
1052
|
+
model: config.model,
|
|
1053
|
+
systemPrompt: config.systemPrompt,
|
|
1054
|
+
cwd: config.cwd,
|
|
1055
|
+
resumeSessionId: config.resumeSessionId,
|
|
1056
|
+
mcpServers: config.mcpServers
|
|
1057
|
+
}, {
|
|
1058
|
+
onStreamEvent: (msg) => this.handleStreamEvent(msg),
|
|
1059
|
+
onUserMessage: (msg) => this.handleUserMessage(msg),
|
|
1060
|
+
onResult: (msg) => this.handleResult(msg),
|
|
1061
|
+
onSessionIdCaptured: config.onSessionIdCaptured,
|
|
1062
|
+
onError: (error) => this.handleError(error),
|
|
1063
|
+
onListenerExit: (reason) => this.handleListenerExit(reason)
|
|
1064
|
+
});
|
|
1071
1065
|
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1066
|
+
connect(consumer) {
|
|
1067
|
+
logger7.debug("ClaudeEffector connected to SystemBusConsumer", {
|
|
1068
|
+
agentId: this.config.agentId
|
|
1069
|
+
});
|
|
1070
|
+
consumer.on("user_message", async (event) => {
|
|
1071
|
+
const typedEvent = event;
|
|
1072
|
+
if (typedEvent.context?.agentId !== this.config.agentId) {
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
const message = typedEvent.data;
|
|
1076
|
+
const meta = {
|
|
1077
|
+
requestId: typedEvent.requestId || "",
|
|
1078
|
+
context: typedEvent.context || {}
|
|
1079
|
+
};
|
|
1080
|
+
await this.send(message, meta);
|
|
1081
|
+
});
|
|
1082
|
+
consumer.on("interrupt", (event) => {
|
|
1083
|
+
const typedEvent = event;
|
|
1084
|
+
if (typedEvent.context?.agentId !== this.config.agentId) {
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
const meta = {
|
|
1088
|
+
requestId: typedEvent.requestId || "",
|
|
1089
|
+
context: typedEvent.context || {}
|
|
1090
|
+
};
|
|
1091
|
+
this.interrupt(meta);
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
async send(message, meta) {
|
|
1095
|
+
this.wasInterrupted = false;
|
|
1096
|
+
this.currentMeta = meta;
|
|
1097
|
+
this.cleanupPendingRequest();
|
|
1098
|
+
const timeoutMs = this.config.timeout ?? DEFAULT_TIMEOUT;
|
|
1099
|
+
try {
|
|
1100
|
+
await this.queryLifecycle.initialize();
|
|
1101
|
+
const sessionId = this.config.sessionId || "default";
|
|
1102
|
+
const sdkUserMessage = buildSDKUserMessage(message, sessionId);
|
|
1103
|
+
logger7.debug("Sending message to Claude", {
|
|
1104
|
+
content: typeof message.content === "string" ? message.content.substring(0, 80) : "[structured]",
|
|
1105
|
+
timeout: timeoutMs,
|
|
1106
|
+
requestId: meta.requestId
|
|
1107
|
+
});
|
|
1108
|
+
this.pendingRequest$ = new Subject3;
|
|
1109
|
+
this.pendingSubscription = this.pendingRequest$.pipe(timeout(timeoutMs)).subscribe({
|
|
1110
|
+
complete: () => {
|
|
1111
|
+
logger7.debug("Request completed within timeout", { requestId: meta.requestId });
|
|
1112
|
+
},
|
|
1113
|
+
error: (err) => {
|
|
1114
|
+
if (err instanceof TimeoutError) {
|
|
1115
|
+
logger7.warn("Request timeout", { timeout: timeoutMs, requestId: meta.requestId });
|
|
1116
|
+
this.handleTimeout(meta);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
});
|
|
1120
|
+
this.queryLifecycle.send(sdkUserMessage);
|
|
1121
|
+
} catch (error) {
|
|
1122
|
+
this.cleanupPendingRequest();
|
|
1123
|
+
throw error;
|
|
1076
1124
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1125
|
+
}
|
|
1126
|
+
interrupt(meta) {
|
|
1127
|
+
logger7.debug("Interrupting Claude query", { requestId: meta?.requestId });
|
|
1128
|
+
this.wasInterrupted = true;
|
|
1129
|
+
if (meta) {
|
|
1130
|
+
this.currentMeta = meta;
|
|
1131
|
+
}
|
|
1132
|
+
this.queryLifecycle.interrupt();
|
|
1133
|
+
}
|
|
1134
|
+
handleStreamEvent(msg) {
|
|
1135
|
+
if (this.currentMeta) {
|
|
1136
|
+
this.receptor.feed(msg, this.currentMeta);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
handleUserMessage(msg) {
|
|
1140
|
+
if (this.currentMeta) {
|
|
1141
|
+
this.receptor.feedUserMessage(msg, this.currentMeta);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
handleResult(msg) {
|
|
1145
|
+
this.completePendingRequest();
|
|
1146
|
+
const resultMsg = msg;
|
|
1147
|
+
logger7.info("SDK result received", {
|
|
1148
|
+
subtype: resultMsg.subtype,
|
|
1149
|
+
isError: resultMsg.is_error,
|
|
1150
|
+
wasInterrupted: this.wasInterrupted
|
|
1151
|
+
});
|
|
1152
|
+
if (resultMsg.subtype === "error_during_execution" && this.wasInterrupted) {
|
|
1153
|
+
this.receptor.emitInterrupted("user_interrupt", this.currentMeta || undefined);
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
if (resultMsg.is_error && this.currentMeta) {
|
|
1157
|
+
const errorMessage = resultMsg.error?.message || resultMsg.errors?.join(", ") || (typeof resultMsg.result === "string" ? resultMsg.result : null) || "An error occurred";
|
|
1158
|
+
const errorCode = resultMsg.error?.type || resultMsg.subtype || "api_error";
|
|
1159
|
+
this.receptor.emitError(errorMessage, errorCode, this.currentMeta);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
handleError(error) {
|
|
1163
|
+
this.cleanupPendingRequest();
|
|
1164
|
+
if (this.currentMeta) {
|
|
1165
|
+
this.receptor.emitError(error.message, "runtime_error", this.currentMeta);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
handleListenerExit(reason) {
|
|
1169
|
+
logger7.debug("SDK listener exited", { reason });
|
|
1170
|
+
this.cleanupPendingRequest();
|
|
1171
|
+
}
|
|
1172
|
+
handleTimeout(meta) {
|
|
1173
|
+
this.wasInterrupted = true;
|
|
1174
|
+
this.queryLifecycle.interrupt();
|
|
1175
|
+
this.receptor.emitError(`Request timeout after ${this.config.timeout ?? DEFAULT_TIMEOUT}ms`, "timeout", meta);
|
|
1176
|
+
}
|
|
1177
|
+
cleanupPendingRequest() {
|
|
1178
|
+
if (this.pendingSubscription) {
|
|
1179
|
+
this.pendingSubscription.unsubscribe();
|
|
1180
|
+
this.pendingSubscription = null;
|
|
1181
|
+
}
|
|
1182
|
+
if (this.pendingRequest$) {
|
|
1183
|
+
this.pendingRequest$.complete();
|
|
1184
|
+
this.pendingRequest$ = null;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
completePendingRequest() {
|
|
1188
|
+
if (this.pendingRequest$) {
|
|
1189
|
+
this.pendingRequest$.complete();
|
|
1190
|
+
this.pendingRequest$ = null;
|
|
1191
|
+
}
|
|
1192
|
+
if (this.pendingSubscription) {
|
|
1193
|
+
this.pendingSubscription.unsubscribe();
|
|
1194
|
+
this.pendingSubscription = null;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
dispose() {
|
|
1198
|
+
logger7.debug("Disposing ClaudeEffector", { agentId: this.config.agentId });
|
|
1199
|
+
this.cleanupPendingRequest();
|
|
1200
|
+
this.queryLifecycle.dispose();
|
|
1201
|
+
logger7.debug("ClaudeEffector disposed", { agentId: this.config.agentId });
|
|
1079
1202
|
}
|
|
1080
1203
|
}
|
|
1081
1204
|
|
|
@@ -1097,7 +1220,7 @@ class ClaudeEnvironment {
|
|
|
1097
1220
|
}
|
|
1098
1221
|
}
|
|
1099
1222
|
// src/internal/RuntimeAgent.ts
|
|
1100
|
-
var
|
|
1223
|
+
var logger8 = createLogger8("runtime/RuntimeAgent");
|
|
1101
1224
|
|
|
1102
1225
|
class BusPresenter {
|
|
1103
1226
|
producer;
|
|
@@ -1140,7 +1263,7 @@ class BusPresenter {
|
|
|
1140
1263
|
this.producer.emit(systemEvent);
|
|
1141
1264
|
if (category === "message") {
|
|
1142
1265
|
this.session.addMessage(data).catch((err) => {
|
|
1143
|
-
|
|
1266
|
+
logger8.error("Failed to persist message", { error: err, messageType: output.type });
|
|
1144
1267
|
});
|
|
1145
1268
|
}
|
|
1146
1269
|
}
|
|
@@ -1203,7 +1326,7 @@ class RuntimeAgent {
|
|
|
1203
1326
|
});
|
|
1204
1327
|
this.environment.receptor.connect(config.bus.asProducer());
|
|
1205
1328
|
this.environment.effector.connect(config.bus.asConsumer());
|
|
1206
|
-
|
|
1329
|
+
logger8.info("ClaudeEnvironment created for agent", {
|
|
1207
1330
|
agentId: this.agentId,
|
|
1208
1331
|
imageId: this.imageId,
|
|
1209
1332
|
cwd: config.sandbox.workdir.path,
|
|
@@ -1230,26 +1353,26 @@ class RuntimeAgent {
|
|
|
1230
1353
|
this.driver = new BusDriver(config.bus.asConsumer(), {
|
|
1231
1354
|
agentId: this.agentId,
|
|
1232
1355
|
onStreamEvent: (event) => {
|
|
1233
|
-
|
|
1356
|
+
logger8.debug("BusDriver → Engine.handleStreamEvent", { type: event.type });
|
|
1234
1357
|
this.engine.handleStreamEvent(event);
|
|
1235
1358
|
},
|
|
1236
1359
|
onStreamComplete: (reason) => {
|
|
1237
|
-
|
|
1360
|
+
logger8.debug("Stream completed", { reason, agentId: this.agentId });
|
|
1238
1361
|
}
|
|
1239
1362
|
});
|
|
1240
|
-
|
|
1363
|
+
logger8.debug("RuntimeAgent created", {
|
|
1241
1364
|
agentId: this.agentId,
|
|
1242
1365
|
imageId: this.imageId
|
|
1243
1366
|
});
|
|
1244
1367
|
}
|
|
1245
1368
|
saveSessionId(sdkSessionId) {
|
|
1246
|
-
|
|
1369
|
+
logger8.info("Saving SDK session ID to image metadata", {
|
|
1247
1370
|
agentId: this.agentId,
|
|
1248
1371
|
imageId: this.imageId,
|
|
1249
1372
|
sdkSessionId
|
|
1250
1373
|
});
|
|
1251
1374
|
this.imageRepository.updateMetadata(this.imageId, { claudeSdkSessionId: sdkSessionId }).catch((err) => {
|
|
1252
|
-
|
|
1375
|
+
logger8.error("Failed to save SDK session ID", { error: err, imageId: this.imageId });
|
|
1253
1376
|
});
|
|
1254
1377
|
}
|
|
1255
1378
|
get lifecycle() {
|
|
@@ -1257,7 +1380,7 @@ class RuntimeAgent {
|
|
|
1257
1380
|
}
|
|
1258
1381
|
async receive(content, requestId) {
|
|
1259
1382
|
const contentPreview = typeof content === "string" ? content.substring(0, 50) : `[${content.length} parts]`;
|
|
1260
|
-
|
|
1383
|
+
logger8.debug("RuntimeAgent.receive called", {
|
|
1261
1384
|
agentId: this.agentId,
|
|
1262
1385
|
contentPreview,
|
|
1263
1386
|
requestId
|
|
@@ -1266,10 +1389,10 @@ class RuntimeAgent {
|
|
|
1266
1389
|
throw new Error(`Cannot send message to ${this._lifecycle} agent`);
|
|
1267
1390
|
}
|
|
1268
1391
|
await this.interactor.receive(content, requestId || `req_${Date.now()}`);
|
|
1269
|
-
|
|
1392
|
+
logger8.debug("RuntimeAgent.receive completed", { agentId: this.agentId });
|
|
1270
1393
|
}
|
|
1271
1394
|
interrupt(requestId) {
|
|
1272
|
-
|
|
1395
|
+
logger8.debug("RuntimeAgent.interrupt called", { agentId: this.agentId, requestId });
|
|
1273
1396
|
this.interactor.interrupt(requestId);
|
|
1274
1397
|
this.producer.emit({
|
|
1275
1398
|
type: "interrupted",
|
|
@@ -1448,8 +1571,8 @@ class RuntimeSandbox {
|
|
|
1448
1571
|
async cleanup() {}
|
|
1449
1572
|
}
|
|
1450
1573
|
// src/internal/RuntimeImage.ts
|
|
1451
|
-
import { createLogger as
|
|
1452
|
-
var
|
|
1574
|
+
import { createLogger as createLogger9 } from "@agentxjs/common";
|
|
1575
|
+
var logger9 = createLogger9("runtime/RuntimeImage");
|
|
1453
1576
|
|
|
1454
1577
|
class RuntimeImage {
|
|
1455
1578
|
record;
|
|
@@ -1508,7 +1631,7 @@ class RuntimeImage {
|
|
|
1508
1631
|
createdAt: now,
|
|
1509
1632
|
updatedAt: now
|
|
1510
1633
|
});
|
|
1511
|
-
|
|
1634
|
+
logger9.info("Image created", {
|
|
1512
1635
|
imageId,
|
|
1513
1636
|
sessionId,
|
|
1514
1637
|
containerId: config.containerId,
|
|
@@ -1519,10 +1642,10 @@ class RuntimeImage {
|
|
|
1519
1642
|
static async load(imageId, context) {
|
|
1520
1643
|
const record = await context.imageRepository.findImageById(imageId);
|
|
1521
1644
|
if (!record) {
|
|
1522
|
-
|
|
1645
|
+
logger9.debug("Image not found", { imageId });
|
|
1523
1646
|
return null;
|
|
1524
1647
|
}
|
|
1525
|
-
|
|
1648
|
+
logger9.debug("Image loaded", { imageId, name: record.name });
|
|
1526
1649
|
return new RuntimeImage(record, context);
|
|
1527
1650
|
}
|
|
1528
1651
|
static async listByContainer(containerId, context) {
|
|
@@ -1543,13 +1666,13 @@ class RuntimeImage {
|
|
|
1543
1666
|
updatedAt: now
|
|
1544
1667
|
};
|
|
1545
1668
|
await this.context.imageRepository.saveImage(updatedRecord);
|
|
1546
|
-
|
|
1669
|
+
logger9.info("Image updated", { imageId: this.imageId, updates });
|
|
1547
1670
|
return new RuntimeImage(updatedRecord, this.context);
|
|
1548
1671
|
}
|
|
1549
1672
|
async delete() {
|
|
1550
1673
|
await this.context.sessionRepository.deleteSession(this.sessionId);
|
|
1551
1674
|
await this.context.imageRepository.deleteImage(this.imageId);
|
|
1552
|
-
|
|
1675
|
+
logger9.info("Image deleted", { imageId: this.imageId, sessionId: this.sessionId });
|
|
1553
1676
|
}
|
|
1554
1677
|
toRecord() {
|
|
1555
1678
|
return { ...this.record };
|
|
@@ -1566,8 +1689,8 @@ class RuntimeImage {
|
|
|
1566
1689
|
}
|
|
1567
1690
|
}
|
|
1568
1691
|
// src/internal/RuntimeContainer.ts
|
|
1569
|
-
import { createLogger as
|
|
1570
|
-
var
|
|
1692
|
+
import { createLogger as createLogger10 } from "@agentxjs/common";
|
|
1693
|
+
var logger10 = createLogger10("runtime/RuntimeContainer");
|
|
1571
1694
|
|
|
1572
1695
|
class RuntimeContainer {
|
|
1573
1696
|
containerId;
|
|
@@ -1603,14 +1726,14 @@ class RuntimeContainer {
|
|
|
1603
1726
|
containerId
|
|
1604
1727
|
}
|
|
1605
1728
|
});
|
|
1606
|
-
|
|
1729
|
+
logger10.info("Container created", { containerId });
|
|
1607
1730
|
return container;
|
|
1608
1731
|
}
|
|
1609
1732
|
static async load(containerId, context) {
|
|
1610
1733
|
const record = await context.persistence.containers.findContainerById(containerId);
|
|
1611
1734
|
if (!record)
|
|
1612
1735
|
return null;
|
|
1613
|
-
|
|
1736
|
+
logger10.info("Container loaded", { containerId });
|
|
1614
1737
|
return new RuntimeContainer(containerId, record.createdAt, context);
|
|
1615
1738
|
}
|
|
1616
1739
|
async runImage(image) {
|
|
@@ -1618,7 +1741,7 @@ class RuntimeContainer {
|
|
|
1618
1741
|
if (existingAgentId) {
|
|
1619
1742
|
const existingAgent = this.agents.get(existingAgentId);
|
|
1620
1743
|
if (existingAgent) {
|
|
1621
|
-
|
|
1744
|
+
logger10.info("Reusing existing agent for image", {
|
|
1622
1745
|
containerId: this.containerId,
|
|
1623
1746
|
imageId: image.imageId,
|
|
1624
1747
|
agentId: existingAgentId
|
|
@@ -1673,7 +1796,7 @@ class RuntimeContainer {
|
|
|
1673
1796
|
agentId
|
|
1674
1797
|
}
|
|
1675
1798
|
});
|
|
1676
|
-
|
|
1799
|
+
logger10.info("Agent created for image", {
|
|
1677
1800
|
containerId: this.containerId,
|
|
1678
1801
|
imageId: image.imageId,
|
|
1679
1802
|
agentId
|
|
@@ -1683,17 +1806,17 @@ class RuntimeContainer {
|
|
|
1683
1806
|
async stopImage(imageId) {
|
|
1684
1807
|
const agentId = this.imageToAgent.get(imageId);
|
|
1685
1808
|
if (!agentId) {
|
|
1686
|
-
|
|
1809
|
+
logger10.debug("Image not running, nothing to stop", {
|
|
1687
1810
|
imageId,
|
|
1688
1811
|
containerId: this.containerId
|
|
1689
1812
|
});
|
|
1690
1813
|
return false;
|
|
1691
1814
|
}
|
|
1692
|
-
|
|
1815
|
+
logger10.info("Stopping image", { imageId, agentId, containerId: this.containerId });
|
|
1693
1816
|
const success = await this.destroyAgent(agentId);
|
|
1694
1817
|
if (success) {
|
|
1695
1818
|
this.imageToAgent.delete(imageId);
|
|
1696
|
-
|
|
1819
|
+
logger10.info("Image stopped", { imageId, agentId, containerId: this.containerId });
|
|
1697
1820
|
}
|
|
1698
1821
|
return success;
|
|
1699
1822
|
}
|
|
@@ -1742,7 +1865,7 @@ class RuntimeContainer {
|
|
|
1742
1865
|
agentId
|
|
1743
1866
|
}
|
|
1744
1867
|
});
|
|
1745
|
-
|
|
1868
|
+
logger10.info("Agent destroyed", { containerId: this.containerId, agentId });
|
|
1746
1869
|
return true;
|
|
1747
1870
|
}
|
|
1748
1871
|
async destroyAllAgents() {
|
|
@@ -1769,7 +1892,7 @@ class RuntimeContainer {
|
|
|
1769
1892
|
}
|
|
1770
1893
|
});
|
|
1771
1894
|
this.context.onDisposed?.(this.containerId);
|
|
1772
|
-
|
|
1895
|
+
logger10.info("Container disposed", { containerId: this.containerId, agentCount });
|
|
1773
1896
|
}
|
|
1774
1897
|
generateAgentId() {
|
|
1775
1898
|
const timestamp = Date.now().toString(36);
|
|
@@ -1778,8 +1901,8 @@ class RuntimeContainer {
|
|
|
1778
1901
|
}
|
|
1779
1902
|
}
|
|
1780
1903
|
// src/internal/BaseEventHandler.ts
|
|
1781
|
-
import { createLogger as
|
|
1782
|
-
var
|
|
1904
|
+
import { createLogger as createLogger11 } from "@agentxjs/common";
|
|
1905
|
+
var logger11 = createLogger11("runtime/BaseEventHandler");
|
|
1783
1906
|
|
|
1784
1907
|
class BaseEventHandler {
|
|
1785
1908
|
bus;
|
|
@@ -1806,7 +1929,7 @@ class BaseEventHandler {
|
|
|
1806
1929
|
handleError(err, context) {
|
|
1807
1930
|
const message = err instanceof Error ? err.message : String(err);
|
|
1808
1931
|
const stack = err instanceof Error ? err.stack : undefined;
|
|
1809
|
-
|
|
1932
|
+
logger11.error(`Error in ${context.operation || "handler"}`, {
|
|
1810
1933
|
message,
|
|
1811
1934
|
requestId: context.requestId,
|
|
1812
1935
|
details: context.details
|
|
@@ -1833,7 +1956,7 @@ class BaseEventHandler {
|
|
|
1833
1956
|
try {
|
|
1834
1957
|
context.onError(err);
|
|
1835
1958
|
} catch (callbackErr) {
|
|
1836
|
-
|
|
1959
|
+
logger11.error("Error in onError callback", { error: callbackErr });
|
|
1837
1960
|
}
|
|
1838
1961
|
}
|
|
1839
1962
|
}
|
|
@@ -1845,13 +1968,13 @@ class BaseEventHandler {
|
|
|
1845
1968
|
unsubscribe();
|
|
1846
1969
|
}
|
|
1847
1970
|
this.unsubscribes = [];
|
|
1848
|
-
|
|
1971
|
+
logger11.debug(`${this.constructor.name} disposed`);
|
|
1849
1972
|
}
|
|
1850
1973
|
}
|
|
1851
1974
|
|
|
1852
1975
|
// src/internal/CommandHandler.ts
|
|
1853
|
-
import { createLogger as
|
|
1854
|
-
var
|
|
1976
|
+
import { createLogger as createLogger12 } from "@agentxjs/common";
|
|
1977
|
+
var logger12 = createLogger12("runtime/CommandHandler");
|
|
1855
1978
|
function createResponse(type, data) {
|
|
1856
1979
|
return {
|
|
1857
1980
|
type,
|
|
@@ -1885,12 +2008,12 @@ class CommandHandler extends BaseEventHandler {
|
|
|
1885
2008
|
super(bus);
|
|
1886
2009
|
this.ops = operations;
|
|
1887
2010
|
this.bindHandlers();
|
|
1888
|
-
|
|
2011
|
+
logger12.debug("CommandHandler created");
|
|
1889
2012
|
}
|
|
1890
2013
|
emitError(operation, err, requestId, context) {
|
|
1891
2014
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1892
2015
|
const stack = err instanceof Error ? err.stack : undefined;
|
|
1893
|
-
|
|
2016
|
+
logger12.error(operation, {
|
|
1894
2017
|
requestId,
|
|
1895
2018
|
...context,
|
|
1896
2019
|
error: errorMessage,
|
|
@@ -1916,11 +2039,11 @@ class CommandHandler extends BaseEventHandler {
|
|
|
1916
2039
|
this.subscribe(this.bus.onCommand("image_get_request", (event) => this.handleImageGet(event)));
|
|
1917
2040
|
this.subscribe(this.bus.onCommand("image_delete_request", (event) => this.handleImageDelete(event)));
|
|
1918
2041
|
this.subscribe(this.bus.onCommand("image_messages_request", (event) => this.handleImageMessages(event)));
|
|
1919
|
-
|
|
2042
|
+
logger12.debug("Command handlers bound");
|
|
1920
2043
|
}
|
|
1921
2044
|
async handleContainerCreate(event) {
|
|
1922
2045
|
const { requestId, containerId } = event.data;
|
|
1923
|
-
|
|
2046
|
+
logger12.debug("Handling container_create_request", { requestId, containerId });
|
|
1924
2047
|
try {
|
|
1925
2048
|
await this.ops.createContainer(containerId);
|
|
1926
2049
|
this.bus.emit(createResponse("container_create_response", {
|
|
@@ -1938,7 +2061,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
1938
2061
|
}
|
|
1939
2062
|
handleContainerGet(event) {
|
|
1940
2063
|
const { requestId, containerId } = event.data;
|
|
1941
|
-
|
|
2064
|
+
logger12.debug("Handling container_get_request", { requestId, containerId });
|
|
1942
2065
|
const container = this.ops.getContainer(containerId);
|
|
1943
2066
|
this.bus.emit(createResponse("container_get_response", {
|
|
1944
2067
|
requestId,
|
|
@@ -1948,7 +2071,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
1948
2071
|
}
|
|
1949
2072
|
handleContainerList(event) {
|
|
1950
2073
|
const { requestId } = event.data;
|
|
1951
|
-
|
|
2074
|
+
logger12.debug("Handling container_list_request", { requestId });
|
|
1952
2075
|
const containers = this.ops.listContainers();
|
|
1953
2076
|
this.bus.emit(createResponse("container_list_response", {
|
|
1954
2077
|
requestId,
|
|
@@ -1957,7 +2080,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
1957
2080
|
}
|
|
1958
2081
|
handleAgentGet(event) {
|
|
1959
2082
|
const { requestId, agentId } = event.data;
|
|
1960
|
-
|
|
2083
|
+
logger12.debug("Handling agent_get_request", { requestId, agentId });
|
|
1961
2084
|
const agent = this.ops.getAgent(agentId);
|
|
1962
2085
|
this.bus.emit(createResponse("agent_get_response", {
|
|
1963
2086
|
requestId,
|
|
@@ -1968,7 +2091,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
1968
2091
|
}
|
|
1969
2092
|
handleAgentList(event) {
|
|
1970
2093
|
const { requestId, containerId } = event.data;
|
|
1971
|
-
|
|
2094
|
+
logger12.debug("Handling agent_list_request", { requestId, containerId });
|
|
1972
2095
|
const agents = this.ops.listAgents(containerId);
|
|
1973
2096
|
this.bus.emit(createResponse("agent_list_response", {
|
|
1974
2097
|
requestId,
|
|
@@ -1981,7 +2104,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
1981
2104
|
}
|
|
1982
2105
|
async handleAgentDestroy(event) {
|
|
1983
2106
|
const { requestId, agentId } = event.data;
|
|
1984
|
-
|
|
2107
|
+
logger12.debug("Handling agent_destroy_request", { requestId, agentId });
|
|
1985
2108
|
try {
|
|
1986
2109
|
const success = await this.ops.destroyAgent(agentId);
|
|
1987
2110
|
this.bus.emit(createResponse("agent_destroy_response", {
|
|
@@ -2001,7 +2124,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2001
2124
|
}
|
|
2002
2125
|
async handleAgentDestroyAll(event) {
|
|
2003
2126
|
const { requestId, containerId } = event.data;
|
|
2004
|
-
|
|
2127
|
+
logger12.debug("Handling agent_destroy_all_request", { requestId, containerId });
|
|
2005
2128
|
try {
|
|
2006
2129
|
await this.ops.destroyAllAgents(containerId);
|
|
2007
2130
|
this.bus.emit(createResponse("agent_destroy_all_response", {
|
|
@@ -2019,7 +2142,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2019
2142
|
}
|
|
2020
2143
|
async handleMessageSend(event) {
|
|
2021
2144
|
const { requestId, imageId, agentId, content } = event.data;
|
|
2022
|
-
|
|
2145
|
+
logger12.debug("Handling message_send_request", { requestId, imageId, agentId });
|
|
2023
2146
|
try {
|
|
2024
2147
|
const result = await this.ops.receiveMessage(imageId, agentId, content, requestId);
|
|
2025
2148
|
this.bus.emit(createResponse("message_send_response", {
|
|
@@ -2039,7 +2162,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2039
2162
|
}
|
|
2040
2163
|
handleAgentInterrupt(event) {
|
|
2041
2164
|
const { requestId, imageId, agentId } = event.data;
|
|
2042
|
-
|
|
2165
|
+
logger12.debug("Handling agent_interrupt_request", { requestId, imageId, agentId });
|
|
2043
2166
|
try {
|
|
2044
2167
|
const result = this.ops.interruptAgent(imageId, agentId, requestId);
|
|
2045
2168
|
this.bus.emit(createResponse("agent_interrupt_response", {
|
|
@@ -2059,7 +2182,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2059
2182
|
}
|
|
2060
2183
|
async handleImageCreate(event) {
|
|
2061
2184
|
const { requestId, containerId, config } = event.data;
|
|
2062
|
-
|
|
2185
|
+
logger12.debug("Handling image_create_request", { requestId, containerId });
|
|
2063
2186
|
try {
|
|
2064
2187
|
const record = await this.ops.createImage(containerId, config);
|
|
2065
2188
|
this.bus.emit(createResponse("image_create_response", {
|
|
@@ -2077,7 +2200,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2077
2200
|
}
|
|
2078
2201
|
async handleImageRun(event) {
|
|
2079
2202
|
const { requestId, imageId } = event.data;
|
|
2080
|
-
|
|
2203
|
+
logger12.debug("Handling image_run_request", { requestId, imageId });
|
|
2081
2204
|
try {
|
|
2082
2205
|
const result = await this.ops.runImage(imageId);
|
|
2083
2206
|
this.bus.emit(createResponse("image_run_response", {
|
|
@@ -2099,7 +2222,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2099
2222
|
}
|
|
2100
2223
|
async handleImageStop(event) {
|
|
2101
2224
|
const { requestId, imageId } = event.data;
|
|
2102
|
-
|
|
2225
|
+
logger12.debug("Handling image_stop_request", { requestId, imageId });
|
|
2103
2226
|
try {
|
|
2104
2227
|
await this.ops.stopImage(imageId);
|
|
2105
2228
|
this.bus.emit(createResponse("image_stop_response", {
|
|
@@ -2117,7 +2240,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2117
2240
|
}
|
|
2118
2241
|
async handleImageUpdate(event) {
|
|
2119
2242
|
const { requestId, imageId, updates } = event.data;
|
|
2120
|
-
|
|
2243
|
+
logger12.debug("Handling image_update_request", { requestId, imageId });
|
|
2121
2244
|
try {
|
|
2122
2245
|
const record = await this.ops.updateImage(imageId, updates);
|
|
2123
2246
|
this.bus.emit(createResponse("image_update_response", {
|
|
@@ -2135,7 +2258,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2135
2258
|
}
|
|
2136
2259
|
async handleImageList(event) {
|
|
2137
2260
|
const { requestId, containerId } = event.data;
|
|
2138
|
-
|
|
2261
|
+
logger12.debug("Handling image_list_request", { requestId, containerId });
|
|
2139
2262
|
try {
|
|
2140
2263
|
const images = await this.ops.listImages(containerId);
|
|
2141
2264
|
this.bus.emit(createResponse("image_list_response", {
|
|
@@ -2153,7 +2276,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2153
2276
|
}
|
|
2154
2277
|
async handleImageGet(event) {
|
|
2155
2278
|
const { requestId, imageId } = event.data;
|
|
2156
|
-
|
|
2279
|
+
logger12.debug("Handling image_get_request", { requestId, imageId });
|
|
2157
2280
|
try {
|
|
2158
2281
|
const image = await this.ops.getImage(imageId);
|
|
2159
2282
|
this.bus.emit(createResponse("image_get_response", {
|
|
@@ -2170,7 +2293,7 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2170
2293
|
}
|
|
2171
2294
|
async handleImageDelete(event) {
|
|
2172
2295
|
const { requestId, imageId } = event.data;
|
|
2173
|
-
|
|
2296
|
+
logger12.debug("Handling image_delete_request", { requestId, imageId });
|
|
2174
2297
|
try {
|
|
2175
2298
|
await this.ops.deleteImage(imageId);
|
|
2176
2299
|
this.bus.emit(createResponse("image_delete_response", {
|
|
@@ -2188,16 +2311,16 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2188
2311
|
}
|
|
2189
2312
|
async handleImageMessages(event) {
|
|
2190
2313
|
const { requestId, imageId } = event.data;
|
|
2191
|
-
|
|
2314
|
+
logger12.info("Handling image_messages_request", { requestId, imageId });
|
|
2192
2315
|
try {
|
|
2193
2316
|
const messages = await this.ops.getImageMessages(imageId);
|
|
2194
|
-
|
|
2317
|
+
logger12.info("Got messages for image", { imageId, count: messages.length });
|
|
2195
2318
|
this.bus.emit(createResponse("image_messages_response", {
|
|
2196
2319
|
requestId,
|
|
2197
2320
|
imageId,
|
|
2198
2321
|
messages
|
|
2199
2322
|
}));
|
|
2200
|
-
|
|
2323
|
+
logger12.info("Emitted image_messages_response", { requestId, imageId });
|
|
2201
2324
|
} catch (err) {
|
|
2202
2325
|
this.emitError("Failed to get image messages", err, requestId, { imageId });
|
|
2203
2326
|
this.bus.emit(createResponse("image_messages_response", {
|
|
@@ -2210,8 +2333,8 @@ class CommandHandler extends BaseEventHandler {
|
|
|
2210
2333
|
}
|
|
2211
2334
|
}
|
|
2212
2335
|
// src/RuntimeImpl.ts
|
|
2213
|
-
import { createLogger as
|
|
2214
|
-
var
|
|
2336
|
+
import { createLogger as createLogger13 } from "@agentxjs/common";
|
|
2337
|
+
var logger13 = createLogger13("runtime/RuntimeImpl");
|
|
2215
2338
|
|
|
2216
2339
|
class RuntimeImpl {
|
|
2217
2340
|
persistence;
|
|
@@ -2223,21 +2346,21 @@ class RuntimeImpl {
|
|
|
2223
2346
|
defaultAgent;
|
|
2224
2347
|
containerRegistry = new Map;
|
|
2225
2348
|
constructor(config) {
|
|
2226
|
-
|
|
2349
|
+
logger13.info("RuntimeImpl constructor start");
|
|
2227
2350
|
this.persistence = config.persistence;
|
|
2228
2351
|
this.llmProvider = config.llmProvider;
|
|
2229
2352
|
this.basePath = config.basePath;
|
|
2230
2353
|
this.defaultAgent = config.defaultAgent;
|
|
2231
|
-
|
|
2354
|
+
logger13.info("Creating SystemBus");
|
|
2232
2355
|
this.bus = new SystemBusImpl;
|
|
2233
2356
|
this.llmConfig = this.llmProvider.provide();
|
|
2234
|
-
|
|
2357
|
+
logger13.info("LLM config loaded", {
|
|
2235
2358
|
hasApiKey: !!this.llmConfig.apiKey,
|
|
2236
2359
|
model: this.llmConfig.model
|
|
2237
2360
|
});
|
|
2238
|
-
|
|
2361
|
+
logger13.info("Creating CommandHandler");
|
|
2239
2362
|
this.commandHandler = new CommandHandler(this.bus, this.createRuntimeOperations());
|
|
2240
|
-
|
|
2363
|
+
logger13.info("RuntimeImpl constructor done");
|
|
2241
2364
|
}
|
|
2242
2365
|
emit(event) {
|
|
2243
2366
|
this.bus.emit(event);
|
|
@@ -2260,8 +2383,8 @@ class RuntimeImpl {
|
|
|
2260
2383
|
emitCommand(type, data) {
|
|
2261
2384
|
this.bus.emitCommand(type, data);
|
|
2262
2385
|
}
|
|
2263
|
-
request(type, data,
|
|
2264
|
-
return this.bus.request(type, data,
|
|
2386
|
+
request(type, data, timeout2) {
|
|
2387
|
+
return this.bus.request(type, data, timeout2);
|
|
2265
2388
|
}
|
|
2266
2389
|
asConsumer() {
|
|
2267
2390
|
return this.bus.asConsumer();
|
|
@@ -2317,7 +2440,7 @@ class RuntimeImpl {
|
|
|
2317
2440
|
},
|
|
2318
2441
|
receiveMessage: async (imageId, agentId, content, requestId) => {
|
|
2319
2442
|
if (imageId) {
|
|
2320
|
-
|
|
2443
|
+
logger13.debug("Receiving message by imageId", {
|
|
2321
2444
|
imageId,
|
|
2322
2445
|
contentLength: content.length,
|
|
2323
2446
|
requestId
|
|
@@ -2327,7 +2450,7 @@ class RuntimeImpl {
|
|
|
2327
2450
|
throw new Error(`Image not found: ${imageId}`);
|
|
2328
2451
|
const container = await this.getOrCreateContainer(record.containerId);
|
|
2329
2452
|
const { agent, reused } = await container.runImage(record);
|
|
2330
|
-
|
|
2453
|
+
logger13.info("Message routed to agent", {
|
|
2331
2454
|
imageId,
|
|
2332
2455
|
agentId: agent.agentId,
|
|
2333
2456
|
reused,
|
|
@@ -2337,7 +2460,7 @@ class RuntimeImpl {
|
|
|
2337
2460
|
return { agentId: agent.agentId, imageId };
|
|
2338
2461
|
}
|
|
2339
2462
|
if (agentId) {
|
|
2340
|
-
|
|
2463
|
+
logger13.debug("Receiving message by agentId (legacy)", {
|
|
2341
2464
|
agentId,
|
|
2342
2465
|
contentLength: content.length,
|
|
2343
2466
|
requestId
|
|
@@ -2355,12 +2478,12 @@ class RuntimeImpl {
|
|
|
2355
2478
|
if (imageId) {
|
|
2356
2479
|
const foundAgentId = this.findAgentIdForImage(imageId);
|
|
2357
2480
|
if (!foundAgentId) {
|
|
2358
|
-
|
|
2481
|
+
logger13.debug("Image is offline, nothing to interrupt", { imageId });
|
|
2359
2482
|
return { imageId, agentId: undefined };
|
|
2360
2483
|
}
|
|
2361
2484
|
const agent = this.findAgent(foundAgentId);
|
|
2362
2485
|
if (agent) {
|
|
2363
|
-
|
|
2486
|
+
logger13.info("Interrupting agent by imageId", {
|
|
2364
2487
|
imageId,
|
|
2365
2488
|
agentId: foundAgentId,
|
|
2366
2489
|
requestId
|
|
@@ -2373,7 +2496,7 @@ class RuntimeImpl {
|
|
|
2373
2496
|
const agent = this.findAgent(agentId);
|
|
2374
2497
|
if (!agent)
|
|
2375
2498
|
throw new Error(`Agent not found: ${agentId}`);
|
|
2376
|
-
|
|
2499
|
+
logger13.info("Interrupting agent by agentId (legacy)", { agentId, requestId });
|
|
2377
2500
|
agent.interrupt(requestId);
|
|
2378
2501
|
const foundImageId = this.findImageIdForAgent(agentId);
|
|
2379
2502
|
return { agentId, imageId: foundImageId };
|
|
@@ -2381,7 +2504,7 @@ class RuntimeImpl {
|
|
|
2381
2504
|
throw new Error("Either imageId or agentId must be provided");
|
|
2382
2505
|
},
|
|
2383
2506
|
createImage: async (containerId, config) => {
|
|
2384
|
-
|
|
2507
|
+
logger13.debug("Creating image", { containerId, name: config.name });
|
|
2385
2508
|
await this.getOrCreateContainer(containerId);
|
|
2386
2509
|
const mergedConfig = {
|
|
2387
2510
|
containerId,
|
|
@@ -2390,35 +2513,35 @@ class RuntimeImpl {
|
|
|
2390
2513
|
systemPrompt: config.systemPrompt ?? this.defaultAgent?.systemPrompt,
|
|
2391
2514
|
mcpServers: config.mcpServers ?? this.defaultAgent?.mcpServers
|
|
2392
2515
|
};
|
|
2393
|
-
|
|
2516
|
+
logger13.debug("Merged config for image creation", {
|
|
2394
2517
|
containerId,
|
|
2395
2518
|
name: mergedConfig.name,
|
|
2396
2519
|
hasSystemPrompt: !!mergedConfig.systemPrompt,
|
|
2397
2520
|
mcpServers: mergedConfig.mcpServers ? Object.keys(mergedConfig.mcpServers) : []
|
|
2398
2521
|
});
|
|
2399
2522
|
const image = await RuntimeImage.create(mergedConfig, this.createImageContext());
|
|
2400
|
-
|
|
2523
|
+
logger13.info("Image created via RuntimeOps", { imageId: image.imageId, containerId });
|
|
2401
2524
|
return this.toImageListItemResult(image.toRecord(), false);
|
|
2402
2525
|
},
|
|
2403
2526
|
runImage: async (imageId) => {
|
|
2404
|
-
|
|
2527
|
+
logger13.debug("Running image", { imageId });
|
|
2405
2528
|
const record = await this.persistence.images.findImageById(imageId);
|
|
2406
2529
|
if (!record)
|
|
2407
2530
|
throw new Error(`Image not found: ${imageId}`);
|
|
2408
2531
|
const container = await this.getOrCreateContainer(record.containerId);
|
|
2409
2532
|
const { agent, reused } = await container.runImage(record);
|
|
2410
|
-
|
|
2533
|
+
logger13.info("Image running", { imageId, agentId: agent.agentId, reused });
|
|
2411
2534
|
return { imageId, agentId: agent.agentId, reused };
|
|
2412
2535
|
},
|
|
2413
2536
|
stopImage: async (imageId) => {
|
|
2414
|
-
|
|
2537
|
+
logger13.debug("Stopping image", { imageId });
|
|
2415
2538
|
const record = await this.persistence.images.findImageById(imageId);
|
|
2416
2539
|
if (!record)
|
|
2417
2540
|
throw new Error(`Image not found: ${imageId}`);
|
|
2418
2541
|
const container = this.containerRegistry.get(record.containerId);
|
|
2419
2542
|
if (container) {
|
|
2420
2543
|
await container.stopImage(imageId);
|
|
2421
|
-
|
|
2544
|
+
logger13.info("Image stopped via RuntimeOps", { imageId });
|
|
2422
2545
|
}
|
|
2423
2546
|
},
|
|
2424
2547
|
updateImage: async (imageId, updates) => {
|
|
@@ -2444,10 +2567,10 @@ class RuntimeImpl {
|
|
|
2444
2567
|
return this.toImageListItemResult(record, online);
|
|
2445
2568
|
},
|
|
2446
2569
|
deleteImage: async (imageId) => {
|
|
2447
|
-
|
|
2570
|
+
logger13.debug("Deleting image", { imageId });
|
|
2448
2571
|
const agentId = this.findAgentIdForImage(imageId);
|
|
2449
2572
|
if (agentId) {
|
|
2450
|
-
|
|
2573
|
+
logger13.debug("Stopping running agent before delete", { imageId, agentId });
|
|
2451
2574
|
for (const container of this.containerRegistry.values()) {
|
|
2452
2575
|
if (container.getAgent(agentId)) {
|
|
2453
2576
|
await container.destroyAgent(agentId);
|
|
@@ -2458,17 +2581,17 @@ class RuntimeImpl {
|
|
|
2458
2581
|
const image = await RuntimeImage.load(imageId, this.createImageContext());
|
|
2459
2582
|
if (image) {
|
|
2460
2583
|
await image.delete();
|
|
2461
|
-
|
|
2584
|
+
logger13.info("Image deleted via RuntimeOps", { imageId });
|
|
2462
2585
|
}
|
|
2463
2586
|
},
|
|
2464
2587
|
getImageMessages: async (imageId) => {
|
|
2465
|
-
|
|
2588
|
+
logger13.debug("Getting messages for image", { imageId });
|
|
2466
2589
|
const image = await RuntimeImage.load(imageId, this.createImageContext());
|
|
2467
2590
|
if (!image) {
|
|
2468
2591
|
throw new Error(`Image not found: ${imageId}`);
|
|
2469
2592
|
}
|
|
2470
2593
|
const messages = await image.getMessages();
|
|
2471
|
-
|
|
2594
|
+
logger13.debug("Got messages from storage", { imageId, count: messages.length });
|
|
2472
2595
|
return messages;
|
|
2473
2596
|
}
|
|
2474
2597
|
};
|
|
@@ -2551,14 +2674,14 @@ class RuntimeImpl {
|
|
|
2551
2674
|
};
|
|
2552
2675
|
}
|
|
2553
2676
|
async dispose() {
|
|
2554
|
-
|
|
2677
|
+
logger13.info("Disposing RuntimeImpl");
|
|
2555
2678
|
this.commandHandler.dispose();
|
|
2556
2679
|
for (const container of this.containerRegistry.values()) {
|
|
2557
2680
|
await container.dispose();
|
|
2558
2681
|
}
|
|
2559
2682
|
this.bus.destroy();
|
|
2560
2683
|
this.containerRegistry.clear();
|
|
2561
|
-
|
|
2684
|
+
logger13.info("RuntimeImpl disposed");
|
|
2562
2685
|
}
|
|
2563
2686
|
}
|
|
2564
2687
|
|
|
@@ -2576,4 +2699,4 @@ export {
|
|
|
2576
2699
|
RuntimeEnvironment
|
|
2577
2700
|
};
|
|
2578
2701
|
|
|
2579
|
-
//# debugId=
|
|
2702
|
+
//# debugId=C63126293F6B51AD64756E2164756E21
|