ai-project-manage-cli 4.0.17 → 4.0.19
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 +213 -38
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -155,6 +155,10 @@ var requestConfig = {
|
|
|
155
155
|
})
|
|
156
156
|
},
|
|
157
157
|
theater: {
|
|
158
|
+
reportMemberAgentProgress: defineEndpoint({
|
|
159
|
+
method: "POST",
|
|
160
|
+
path: "/theater/sessions/report-member-agent-progress"
|
|
161
|
+
}),
|
|
158
162
|
submitMemberResponse: defineEndpoint({
|
|
159
163
|
method: "POST",
|
|
160
164
|
path: "/theater/sessions/submit-member-response"
|
|
@@ -370,7 +374,7 @@ async function runComment(requirementId, file, options) {
|
|
|
370
374
|
}
|
|
371
375
|
|
|
372
376
|
// src/commands/connect.ts
|
|
373
|
-
import { randomUUID } from "crypto";
|
|
377
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
374
378
|
import WebSocket from "ws";
|
|
375
379
|
import { Agent } from "@cursor/sdk";
|
|
376
380
|
import { join as join6 } from "path";
|
|
@@ -777,11 +781,149 @@ async function runPull(requirementId, workspaceDir) {
|
|
|
777
781
|
return WORKITEMS_DIR;
|
|
778
782
|
}
|
|
779
783
|
|
|
784
|
+
// src/theater-job-report.ts
|
|
785
|
+
import { randomUUID } from "crypto";
|
|
786
|
+
function extractErrorMessage(err) {
|
|
787
|
+
if (err instanceof Error && err.message.trim()) {
|
|
788
|
+
return err.message.trim();
|
|
789
|
+
}
|
|
790
|
+
if (typeof err === "string" && err.trim()) {
|
|
791
|
+
return err.trim();
|
|
792
|
+
}
|
|
793
|
+
if (typeof err === "object" && err && "message" in err) {
|
|
794
|
+
const msg = err.message;
|
|
795
|
+
if (typeof msg === "string" && msg.trim()) return msg.trim();
|
|
796
|
+
if (Array.isArray(msg)) return msg.map(String).join("\uFF1B");
|
|
797
|
+
}
|
|
798
|
+
return "\u672A\u77E5\u9519\u8BEF";
|
|
799
|
+
}
|
|
800
|
+
function isUnauthorizedMessage(msg) {
|
|
801
|
+
return msg.includes("\u672A\u767B\u5F55") || /401/.test(msg);
|
|
802
|
+
}
|
|
803
|
+
function sendTheaterReportWs(ws, payload) {
|
|
804
|
+
return new Promise((resolve5, reject) => {
|
|
805
|
+
const msg_id = randomUUID();
|
|
806
|
+
const timer = setTimeout(() => {
|
|
807
|
+
ws.off("message", onMessage);
|
|
808
|
+
reject(new Error("WebSocket \u4E0A\u62A5\u8D85\u65F6"));
|
|
809
|
+
}, 3e4);
|
|
810
|
+
const onMessage = (data) => {
|
|
811
|
+
const text = typeof data === "string" ? data : data.toString();
|
|
812
|
+
let frame;
|
|
813
|
+
try {
|
|
814
|
+
frame = JSON.parse(text);
|
|
815
|
+
} catch {
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
if (frame.msg_id !== msg_id) return;
|
|
819
|
+
clearTimeout(timer);
|
|
820
|
+
ws.off("message", onMessage);
|
|
821
|
+
if (frame.type === "ERROR") {
|
|
822
|
+
reject(
|
|
823
|
+
new Error(frame.payload?.message?.trim() || "WebSocket \u4E0A\u62A5\u5931\u8D25")
|
|
824
|
+
);
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
if (frame.type === "ACK") {
|
|
828
|
+
resolve5();
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
ws.on("message", onMessage);
|
|
833
|
+
ws.send(
|
|
834
|
+
JSON.stringify({
|
|
835
|
+
type: "THEATER_REPORT",
|
|
836
|
+
msg_id,
|
|
837
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
838
|
+
payload
|
|
839
|
+
})
|
|
840
|
+
);
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
async function reportTheaterProgress(api, ws, params) {
|
|
844
|
+
const body = {
|
|
845
|
+
sessionId: params.sessionId,
|
|
846
|
+
memberKey: params.memberKey,
|
|
847
|
+
status: "IN_PROGRESS",
|
|
848
|
+
logId: params.logId
|
|
849
|
+
};
|
|
850
|
+
try {
|
|
851
|
+
await api.theater.reportMemberAgentProgress(body);
|
|
852
|
+
} catch (err) {
|
|
853
|
+
const msg = extractErrorMessage(err);
|
|
854
|
+
if (!isUnauthorizedMessage(msg)) throw err;
|
|
855
|
+
await sendTheaterReportWs(ws, { action: "progress", ...body });
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
async function submitTheaterResult(api, ws, params) {
|
|
859
|
+
const body = {
|
|
860
|
+
sessionId: params.sessionId,
|
|
861
|
+
memberKey: params.memberKey,
|
|
862
|
+
content: params.content,
|
|
863
|
+
agentId: params.agentId ?? "",
|
|
864
|
+
agentStatus: params.agentStatus,
|
|
865
|
+
logId: params.logId
|
|
866
|
+
};
|
|
867
|
+
try {
|
|
868
|
+
await api.theater.submitMemberResponse(body);
|
|
869
|
+
} catch (err) {
|
|
870
|
+
const msg = extractErrorMessage(err);
|
|
871
|
+
if (!isUnauthorizedMessage(msg)) throw err;
|
|
872
|
+
await sendTheaterReportWs(ws, {
|
|
873
|
+
action: "submit",
|
|
874
|
+
sessionId: params.sessionId,
|
|
875
|
+
memberKey: params.memberKey,
|
|
876
|
+
content: params.content,
|
|
877
|
+
agentId: params.agentId,
|
|
878
|
+
agentStatus: params.agentStatus,
|
|
879
|
+
logId: params.logId
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
async function submitTheaterFailure(api, ws, params) {
|
|
884
|
+
const content = `[${params.stage}] ${params.error}`;
|
|
885
|
+
try {
|
|
886
|
+
await submitTheaterResult(api, ws, {
|
|
887
|
+
sessionId: params.sessionId,
|
|
888
|
+
memberKey: params.memberKey,
|
|
889
|
+
content,
|
|
890
|
+
agentId: params.agentId,
|
|
891
|
+
agentStatus: "FAILED",
|
|
892
|
+
logId: params.logId
|
|
893
|
+
});
|
|
894
|
+
return true;
|
|
895
|
+
} catch (submitErr) {
|
|
896
|
+
console.error(
|
|
897
|
+
"[apm] \u65E0\u6CD5\u5C06\u5931\u8D25\u72B6\u6001\u5199\u5165\u5267\u573A\u4F1A\u8BDD:",
|
|
898
|
+
extractErrorMessage(submitErr)
|
|
899
|
+
);
|
|
900
|
+
return false;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
function logTheaterJobError(stage, err, meta) {
|
|
904
|
+
const msg = extractErrorMessage(err);
|
|
905
|
+
const ctx = [
|
|
906
|
+
meta?.sessionId ? `session=${meta.sessionId}` : "",
|
|
907
|
+
meta?.memberKey ? `member=${meta.memberKey}` : ""
|
|
908
|
+
].filter(Boolean).join(" ");
|
|
909
|
+
console.error(
|
|
910
|
+
`[apm] \u5267\u573A THEATER_JOB \u5931\u8D25 \xB7 \u9636\u6BB5=${stage}${ctx ? ` \xB7 ${ctx}` : ""} \xB7 ${msg}`
|
|
911
|
+
);
|
|
912
|
+
if (isUnauthorizedMessage(msg)) {
|
|
913
|
+
console.error("[apm] \u63D0\u793A: \u8BF7\u6267\u884C apm login \u91CD\u65B0\u767B\u5F55\u540E\u518D\u8BD5");
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
780
917
|
// src/commands/connect.ts
|
|
918
|
+
var DEFAULT_AGENT_MODEL_ID = "default";
|
|
919
|
+
function resolveAgentModelId(model) {
|
|
920
|
+
const id = model?.trim();
|
|
921
|
+
return id || DEFAULT_AGENT_MODEL_ID;
|
|
922
|
+
}
|
|
781
923
|
async function createAgentForJob(payload) {
|
|
782
924
|
const options = {
|
|
783
925
|
apiKey: payload.apiKey,
|
|
784
|
-
model: { id: payload.model
|
|
926
|
+
model: { id: resolveAgentModelId(payload.model) },
|
|
785
927
|
local: { cwd: payload.cwd }
|
|
786
928
|
};
|
|
787
929
|
if (payload.agentId) {
|
|
@@ -835,9 +977,10 @@ async function runAgentStream(payload, session, agent) {
|
|
|
835
977
|
}
|
|
836
978
|
return { agentId: run.agentId, failed, failReason };
|
|
837
979
|
}
|
|
838
|
-
async function handleTheaterJob(api, payload) {
|
|
980
|
+
async function handleTheaterJob(api, ws, payload) {
|
|
839
981
|
const sessionId = payload.theaterSessionId.trim();
|
|
840
982
|
const memberKey = payload.memberKey.trim();
|
|
983
|
+
const logId = payload.logId?.trim() || void 0;
|
|
841
984
|
if (!sessionId) {
|
|
842
985
|
throw new Error("THEATER_JOB \u7F3A\u5C11 theaterSessionId");
|
|
843
986
|
}
|
|
@@ -845,29 +988,53 @@ async function handleTheaterJob(api, payload) {
|
|
|
845
988
|
throw new Error("THEATER_JOB \u7F3A\u5C11 memberKey");
|
|
846
989
|
}
|
|
847
990
|
console.log("[apm] \u5267\u573A\u4F1A\u8BDD:", sessionId, "\u6210\u5458:", memberKey);
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
991
|
+
let agentId = payload.agentId?.trim() || void 0;
|
|
992
|
+
try {
|
|
993
|
+
await reportTheaterProgress(api, ws, { sessionId, memberKey, logId });
|
|
994
|
+
} catch (err) {
|
|
995
|
+
logTheaterJobError("\u4E0A\u62A5\u6267\u884C\u8FDB\u5EA6", err, { sessionId, memberKey });
|
|
996
|
+
await submitTheaterFailure(api, ws, {
|
|
997
|
+
sessionId,
|
|
998
|
+
memberKey,
|
|
999
|
+
logId,
|
|
1000
|
+
agentId,
|
|
1001
|
+
stage: "\u4E0A\u62A5\u8FDB\u5EA6",
|
|
1002
|
+
error: extractErrorMessage(err)
|
|
1003
|
+
});
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
try {
|
|
1007
|
+
const eventSession = new EventSession(payload.prompt);
|
|
1008
|
+
const agent = await createAgentForJob(payload);
|
|
1009
|
+
const runResult = await runAgentStream(payload, eventSession, agent);
|
|
1010
|
+
agentId = runResult.agentId;
|
|
1011
|
+
const assistantText = eventSession.getAssistantText();
|
|
1012
|
+
const content = runResult.failed ? runResult.failReason || assistantText || "\u672A\u77E5\u9519\u8BEF" : assistantText || "[Agent \u672A\u4EA7\u751F\u6587\u672C\u8F93\u51FA]";
|
|
1013
|
+
await submitTheaterResult(api, ws, {
|
|
1014
|
+
sessionId,
|
|
1015
|
+
memberKey,
|
|
1016
|
+
content,
|
|
1017
|
+
agentId,
|
|
1018
|
+
agentStatus: runResult.failed ? "FAILED" : "SUCCESS",
|
|
1019
|
+
logId
|
|
1020
|
+
});
|
|
1021
|
+
console.log(
|
|
1022
|
+
"[apm] \u5267\u573A\u6210\u5458\u56DE\u590D\u5DF2\u63D0\u4EA4",
|
|
1023
|
+
runResult.failed ? "(\u6267\u884C\u5931\u8D25)" : ""
|
|
1024
|
+
);
|
|
1025
|
+
} catch (err) {
|
|
1026
|
+
logTheaterJobError("\u6267\u884C\u6216\u63D0\u4EA4\u56DE\u590D", err, { sessionId, memberKey });
|
|
1027
|
+
const reported = await submitTheaterFailure(api, ws, {
|
|
1028
|
+
sessionId,
|
|
1029
|
+
memberKey,
|
|
1030
|
+
logId,
|
|
1031
|
+
agentId,
|
|
1032
|
+
stage: "\u6267\u884C\u4EFB\u52A1",
|
|
1033
|
+
error: extractErrorMessage(err)
|
|
1034
|
+
});
|
|
1035
|
+
if (reported) {
|
|
1036
|
+
console.error("[apm] \u5DF2\u5C06\u5931\u8D25\u539F\u56E0\u5199\u5165\u5267\u573A\u4F1A\u8BDD\uFF0C\u53EF\u5728\u7F51\u9875\u67E5\u770B");
|
|
1037
|
+
}
|
|
871
1038
|
}
|
|
872
1039
|
}
|
|
873
1040
|
async function handleWorkflowJob(api, payload) {
|
|
@@ -947,7 +1114,7 @@ function runConnect(opts) {
|
|
|
947
1114
|
const sendHeartbeat = () => {
|
|
948
1115
|
const frame = {
|
|
949
1116
|
type: "HEARTBEAT",
|
|
950
|
-
msg_id:
|
|
1117
|
+
msg_id: randomUUID2(),
|
|
951
1118
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
952
1119
|
payload: {}
|
|
953
1120
|
};
|
|
@@ -959,22 +1126,31 @@ function runConnect(opts) {
|
|
|
959
1126
|
});
|
|
960
1127
|
ws.on("message", async (data) => {
|
|
961
1128
|
const text = typeof data === "string" ? data : data.toString();
|
|
1129
|
+
let msg;
|
|
962
1130
|
try {
|
|
963
|
-
|
|
964
|
-
if (msg.type === "THEATER_JOB") {
|
|
965
|
-
await handleTheaterJob(api, msg.payload);
|
|
966
|
-
return;
|
|
967
|
-
}
|
|
968
|
-
if (msg.type === "JOB") {
|
|
969
|
-
await handleWorkflowJob(api, msg.payload);
|
|
970
|
-
return;
|
|
971
|
-
}
|
|
1131
|
+
msg = JSON.parse(text);
|
|
972
1132
|
} catch (err) {
|
|
973
1133
|
console.error(
|
|
974
1134
|
"[apm] \u65E0\u6CD5\u89E3\u6790 WebSocket \u6D88\u606F:",
|
|
975
1135
|
text,
|
|
976
1136
|
err.message
|
|
977
1137
|
);
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
try {
|
|
1141
|
+
const jobType = msg.type;
|
|
1142
|
+
if (jobType === "THEATER_JOB") {
|
|
1143
|
+
await handleTheaterJob(api, ws, msg.payload);
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
if (jobType === "JOB") {
|
|
1147
|
+
await handleWorkflowJob(api, msg.payload);
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
} catch (err) {
|
|
1151
|
+
const jobType = msg.type;
|
|
1152
|
+
const label = jobType === "THEATER_JOB" ? "\u5267\u573A THEATER_JOB" : jobType === "JOB" ? "\u5DE5\u4F5C\u6D41 JOB" : String(jobType);
|
|
1153
|
+
console.error(`[apm] ${label} \u5904\u7406\u5931\u8D25:`, extractErrorMessage(err));
|
|
978
1154
|
}
|
|
979
1155
|
});
|
|
980
1156
|
ws.on("error", (err) => {
|
|
@@ -2033,7 +2209,7 @@ function loadApmDotEnvIfPresent() {
|
|
|
2033
2209
|
|
|
2034
2210
|
// src/commands/deploy/internal/minio.ts
|
|
2035
2211
|
import { statSync as statSync5 } from "node:fs";
|
|
2036
|
-
import { readdir } from "node:fs/promises";
|
|
2212
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2037
2213
|
import path6 from "node:path";
|
|
2038
2214
|
import * as Minio from "minio";
|
|
2039
2215
|
var DEFAULT_MAX_FILE_SIZE_MB = 50;
|
|
@@ -2083,7 +2259,6 @@ async function collectFiles(root) {
|
|
|
2083
2259
|
return out;
|
|
2084
2260
|
}
|
|
2085
2261
|
async function readArtifactFile(absPath) {
|
|
2086
|
-
const { readFile } = await import("node:fs/promises");
|
|
2087
2262
|
return readFile(absPath);
|
|
2088
2263
|
}
|
|
2089
2264
|
function toMB(bytes) {
|