@zhin.js/host-http 1.1.10 → 1.1.11
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.
|
@@ -66,6 +66,7 @@ export interface ConsoleAgentSessionTree {
|
|
|
66
66
|
resolveActiveSessionId(sessionKey: string): Promise<string | null>;
|
|
67
67
|
getActiveLeafMessageId(sessionId: string): Promise<number | null>;
|
|
68
68
|
listBranchPoints(sessionId: string): Promise<readonly unknown[]>;
|
|
69
|
+
readBranchMessage?(sessionId: string, messageId: number): Promise<string | null>;
|
|
69
70
|
switchActiveLeaf(sessionId: string, messageId: number): Promise<boolean>;
|
|
70
71
|
jumpToBranchIndex(sessionId: string, index: number): Promise<{
|
|
71
72
|
ok: boolean;
|
|
@@ -676,13 +676,22 @@ function registerAgentSessionRoutes(route, base, ctx) {
|
|
|
676
676
|
error: 'Agent session tree runtime 未就绪(新 Runtime 需经 acquireAgentRuntime 装配 sessionTree)',
|
|
677
677
|
});
|
|
678
678
|
};
|
|
679
|
-
// HttpHost 无 `:param` 路由,用前缀路由匹配 `<sessionKey>/tree|leaf`。
|
|
679
|
+
// HttpHost 无 `:param` 路由,用前缀路由匹配 `<sessionKey>/tree|message|leaf`。
|
|
680
680
|
route('GET', `${base}/agent/sessions/*`, async (_request, response, url) => {
|
|
681
|
-
const
|
|
681
|
+
const messageAction = parseSessionAction(url.pathname, prefix, 'message');
|
|
682
|
+
if (messageAction)
|
|
683
|
+
response.setHeader('Cache-Control', 'no-store');
|
|
684
|
+
const parsed = messageAction ?? parseSessionAction(url.pathname, prefix, 'tree');
|
|
682
685
|
if (!parsed) {
|
|
683
686
|
writeJson(response, 404, { success: false, error: 'Not found' });
|
|
684
687
|
return;
|
|
685
688
|
}
|
|
689
|
+
const messageId = Number(url.searchParams.get('messageId'));
|
|
690
|
+
const expectedSessionId = url.searchParams.get('sessionId');
|
|
691
|
+
if (messageAction && (!Number.isSafeInteger(messageId) || messageId < 1 || !expectedSessionId)) {
|
|
692
|
+
writeJson(response, 400, { success: false, error: '需要 sessionId 和正安全整数 messageId' });
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
686
695
|
const lease = acquireSessionTree();
|
|
687
696
|
if (!lease) {
|
|
688
697
|
unavailable(response);
|
|
@@ -690,7 +699,28 @@ function registerAgentSessionRoutes(route, base, ctx) {
|
|
|
690
699
|
}
|
|
691
700
|
const runtime = lease.tree;
|
|
692
701
|
try {
|
|
702
|
+
if (messageAction && !runtime.readBranchMessage) {
|
|
703
|
+
writeJson(response, 501, { success: false, error: '当前 Agent runtime 不支持读取完整消息' });
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
693
706
|
const sessionId = await runtime.resolveActiveSessionId(parsed.sessionKey);
|
|
707
|
+
if (messageAction) {
|
|
708
|
+
if (!sessionId) {
|
|
709
|
+
writeJson(response, 404, { success: false, error: '未找到活跃会话' });
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
if (sessionId !== expectedSessionId) {
|
|
713
|
+
writeJson(response, 409, { success: false, error: '会话已变化,请重新读取会话列表' });
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
const text = await runtime.readBranchMessage(sessionId, messageId);
|
|
717
|
+
if (text === null) {
|
|
718
|
+
writeJson(response, 404, { success: false, error: '未找到此会话的用户消息' });
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
writeJson(response, 200, { success: true, data: { messageId, text } });
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
694
724
|
if (!sessionId) {
|
|
695
725
|
if (!isRuntimeImSessionKey(parsed.sessionKey)) {
|
|
696
726
|
writeJson(response, 404, {
|
|
@@ -738,7 +768,7 @@ function registerAgentSessionRoutes(route, base, ctx) {
|
|
|
738
768
|
finally {
|
|
739
769
|
lease.release();
|
|
740
770
|
}
|
|
741
|
-
}, { summary: 'Get agent session tree', tags: ['console', 'agent'] });
|
|
771
|
+
}, { summary: 'Get agent session tree or message', tags: ['console', 'agent'] });
|
|
742
772
|
route('POST', `${base}/agent/sessions/*`, async (request, response, url, authScope) => {
|
|
743
773
|
const parsed = parseSessionAction(url.pathname, prefix, 'leaf');
|
|
744
774
|
if (!parsed) {
|
package/package.json
CHANGED
|
@@ -71,6 +71,7 @@ export interface ConsoleAgentSessionTree {
|
|
|
71
71
|
resolveActiveSessionId(sessionKey: string): Promise<string | null>;
|
|
72
72
|
getActiveLeafMessageId(sessionId: string): Promise<number | null>;
|
|
73
73
|
listBranchPoints(sessionId: string): Promise<readonly unknown[]>;
|
|
74
|
+
readBranchMessage?(sessionId: string, messageId: number): Promise<string | null>;
|
|
74
75
|
switchActiveLeaf(sessionId: string, messageId: number): Promise<boolean>;
|
|
75
76
|
jumpToBranchIndex(
|
|
76
77
|
sessionId: string,
|
|
@@ -872,13 +873,21 @@ function registerAgentSessionRoutes(
|
|
|
872
873
|
});
|
|
873
874
|
};
|
|
874
875
|
|
|
875
|
-
// HttpHost 无 `:param` 路由,用前缀路由匹配 `<sessionKey>/tree|leaf`。
|
|
876
|
+
// HttpHost 无 `:param` 路由,用前缀路由匹配 `<sessionKey>/tree|message|leaf`。
|
|
876
877
|
route('GET', `${base}/agent/sessions/*`, async (_request, response, url) => {
|
|
877
|
-
const
|
|
878
|
+
const messageAction = parseSessionAction(url.pathname, prefix, 'message');
|
|
879
|
+
if (messageAction) response.setHeader('Cache-Control', 'no-store');
|
|
880
|
+
const parsed = messageAction ?? parseSessionAction(url.pathname, prefix, 'tree');
|
|
878
881
|
if (!parsed) {
|
|
879
882
|
writeJson(response, 404, { success: false, error: 'Not found' });
|
|
880
883
|
return;
|
|
881
884
|
}
|
|
885
|
+
const messageId = Number(url.searchParams.get('messageId'));
|
|
886
|
+
const expectedSessionId = url.searchParams.get('sessionId');
|
|
887
|
+
if (messageAction && (!Number.isSafeInteger(messageId) || messageId < 1 || !expectedSessionId)) {
|
|
888
|
+
writeJson(response, 400, { success: false, error: '需要 sessionId 和正安全整数 messageId' });
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
882
891
|
const lease = acquireSessionTree();
|
|
883
892
|
if (!lease) {
|
|
884
893
|
unavailable(response);
|
|
@@ -886,7 +895,28 @@ function registerAgentSessionRoutes(
|
|
|
886
895
|
}
|
|
887
896
|
const runtime = lease.tree;
|
|
888
897
|
try {
|
|
898
|
+
if (messageAction && !runtime.readBranchMessage) {
|
|
899
|
+
writeJson(response, 501, { success: false, error: '当前 Agent runtime 不支持读取完整消息' });
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
889
902
|
const sessionId = await runtime.resolveActiveSessionId(parsed.sessionKey);
|
|
903
|
+
if (messageAction) {
|
|
904
|
+
if (!sessionId) {
|
|
905
|
+
writeJson(response, 404, { success: false, error: '未找到活跃会话' });
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
if (sessionId !== expectedSessionId) {
|
|
909
|
+
writeJson(response, 409, { success: false, error: '会话已变化,请重新读取会话列表' });
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
const text = await runtime.readBranchMessage!(sessionId, messageId);
|
|
913
|
+
if (text === null) {
|
|
914
|
+
writeJson(response, 404, { success: false, error: '未找到此会话的用户消息' });
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
writeJson(response, 200, { success: true, data: { messageId, text } });
|
|
918
|
+
return;
|
|
919
|
+
}
|
|
890
920
|
if (!sessionId) {
|
|
891
921
|
if (!isRuntimeImSessionKey(parsed.sessionKey)) {
|
|
892
922
|
writeJson(response, 404, {
|
|
@@ -934,7 +964,7 @@ function registerAgentSessionRoutes(
|
|
|
934
964
|
} finally {
|
|
935
965
|
lease.release();
|
|
936
966
|
}
|
|
937
|
-
}, { summary: 'Get agent session tree', tags: ['console', 'agent'] });
|
|
967
|
+
}, { summary: 'Get agent session tree or message', tags: ['console', 'agent'] });
|
|
938
968
|
|
|
939
969
|
route('POST', `${base}/agent/sessions/*`, async (request, response, url, authScope) => {
|
|
940
970
|
const parsed = parseSessionAction(url.pathname, prefix, 'leaf');
|
|
@@ -1038,7 +1068,7 @@ function isRuntimeImSessionKey(value: string): boolean {
|
|
|
1038
1068
|
function parseSessionAction(
|
|
1039
1069
|
pathname: string,
|
|
1040
1070
|
prefix: string,
|
|
1041
|
-
action: 'tree' | 'leaf',
|
|
1071
|
+
action: 'tree' | 'message' | 'leaf',
|
|
1042
1072
|
): { sessionKey: string } | null {
|
|
1043
1073
|
if (!pathname.startsWith(prefix)) return null;
|
|
1044
1074
|
const rest = pathname.slice(prefix.length).replace(/\/+$/u, '');
|