ai-project-manage-cli 4.0.16 → 4.0.18

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.
Files changed (2) hide show
  1. package/dist/index.js +170 -103
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -154,6 +154,16 @@ var requestConfig = {
154
154
  path: "/requirement-artifacts/delete"
155
155
  })
156
156
  },
157
+ theater: {
158
+ reportMemberAgentProgress: defineEndpoint({
159
+ method: "POST",
160
+ path: "/theater/sessions/report-member-agent-progress"
161
+ }),
162
+ submitMemberResponse: defineEndpoint({
163
+ method: "POST",
164
+ path: "/theater/sessions/submit-member-response"
165
+ })
166
+ },
157
167
  spaceWorkflow: {
158
168
  aiStartNode: defineEndpoint({
159
169
  method: "POST",
@@ -459,6 +469,10 @@ var EventSession = class {
459
469
  return { type: "status", status: event.status, message: event.message };
460
470
  }
461
471
  }
472
+ /** 合并所有 assistant 片段,供剧场成员回传等场景使用 */
473
+ getAssistantText() {
474
+ return this.events.filter((e) => e.type === "assistant").map((e) => String(e.content ?? "")).join("\n").trim();
475
+ }
462
476
  writeToFile(cwd, requirementId, agentId) {
463
477
  const sessionsDir = resolve2(
464
478
  cwd,
@@ -768,6 +782,158 @@ async function runPull(requirementId, workspaceDir) {
768
782
  }
769
783
 
770
784
  // src/commands/connect.ts
785
+ async function createAgentForJob(payload) {
786
+ const options = {
787
+ apiKey: payload.apiKey,
788
+ model: { id: payload.model ?? "default" },
789
+ local: { cwd: payload.cwd }
790
+ };
791
+ if (payload.agentId) {
792
+ return Agent.resume(payload.agentId, options);
793
+ }
794
+ return Agent.create(options);
795
+ }
796
+ async function runAgentStream(payload, session, agent) {
797
+ const run = await agent.send(payload.prompt);
798
+ let failed = false;
799
+ let failReason = "";
800
+ for await (const event of run.stream()) {
801
+ if (event.type === "status") {
802
+ console.log(`[Status]`, event.message || event.status);
803
+ if (event.status === "ERROR") {
804
+ failed = true;
805
+ failReason = event.message?.trim() ?? "";
806
+ console.error("[apm] Agent \u6267\u884C\u5931\u8D25:", failReason || "(\u65E0\u5931\u8D25\u539F\u56E0)");
807
+ break;
808
+ }
809
+ continue;
810
+ }
811
+ if (event.type === "assistant") {
812
+ const output = event.message.content[0].text;
813
+ console.log(`[Output]`, output);
814
+ session.addEvent(event);
815
+ continue;
816
+ }
817
+ if (event.type === "thinking") {
818
+ console.log(`[Thinking]`, event.text);
819
+ continue;
820
+ }
821
+ if (event.type === "tool_call") {
822
+ if (event.status === "completed" || event.status === "error") {
823
+ console.log(`[ToolCall(${event.call_id}) Result]`);
824
+ }
825
+ session.addEvent(event);
826
+ continue;
827
+ }
828
+ if (event.type === "task") {
829
+ console.log(`[Task:${event.status}]`);
830
+ session.addEvent(event);
831
+ continue;
832
+ }
833
+ if (event.type === "request") {
834
+ console.log(JSON.stringify(event, null, 2));
835
+ session.addEvent(event);
836
+ continue;
837
+ }
838
+ console.log("\u672A\u77E5\u4E8B\u4EF6:", JSON.stringify(event, null, 2));
839
+ }
840
+ return { agentId: run.agentId, failed, failReason };
841
+ }
842
+ async function handleTheaterJob(api, payload) {
843
+ const sessionId = payload.theaterSessionId.trim();
844
+ const memberKey = payload.memberKey.trim();
845
+ if (!sessionId) {
846
+ throw new Error("THEATER_JOB \u7F3A\u5C11 theaterSessionId");
847
+ }
848
+ if (!memberKey) {
849
+ throw new Error("THEATER_JOB \u7F3A\u5C11 memberKey");
850
+ }
851
+ console.log("[apm] \u5267\u573A\u4F1A\u8BDD:", sessionId, "\u6210\u5458:", memberKey);
852
+ await api.theater.reportMemberAgentProgress({
853
+ sessionId,
854
+ memberKey,
855
+ status: "IN_PROGRESS",
856
+ logId: payload.logId?.trim() || void 0
857
+ });
858
+ const eventSession = new EventSession(payload.prompt);
859
+ const agent = await createAgentForJob(payload);
860
+ const { agentId, failed, failReason } = await runAgentStream(
861
+ payload,
862
+ eventSession,
863
+ agent
864
+ );
865
+ const assistantText = eventSession.getAssistantText();
866
+ const content = failed ? failReason || assistantText || "\u672A\u77E5\u9519\u8BEF" : assistantText || "[Agent \u672A\u4EA7\u751F\u6587\u672C\u8F93\u51FA]";
867
+ const result = await api.theater.submitMemberResponse({
868
+ sessionId,
869
+ memberKey,
870
+ content,
871
+ agentId,
872
+ agentStatus: failed ? "FAILED" : "SUCCESS",
873
+ logId: payload.logId?.trim() || void 0
874
+ });
875
+ console.log(
876
+ "[apm] \u5267\u573A\u6210\u5458\u56DE\u590D\u5DF2\u63D0\u4EA4",
877
+ failed ? "(\u542B\u5931\u8D25\u8BF4\u660E)" : "",
878
+ result.clearedPending ? "\xB7 \u5DF2\u6E05\u9664\u5F85\u56DE\u590D" : ""
879
+ );
880
+ if (result.canAdvance) {
881
+ console.log("[apm] \u53EF\u624B\u52A8\u63A8\u8FDB\u4E3B\u6301\u8F6E\u6B21\uFF08autoPlay \u5173\u95ED\uFF09");
882
+ }
883
+ }
884
+ async function handleWorkflowJob(api, payload) {
885
+ const apmRoot = join6(payload.cwd, ".apm");
886
+ console.log("[apm] ROOT:", apmRoot);
887
+ console.log("[apm] workflow node:", payload.nodeId);
888
+ try {
889
+ await runPull(payload.requirementId, apmRoot);
890
+ } catch (pullErr) {
891
+ console.error("[apm] apm pull \u5931\u8D25:", pullErr);
892
+ throw pullErr;
893
+ }
894
+ const agent = await createAgentForJob(payload);
895
+ await api.cliRequirements.updateDevStatus({
896
+ requirementId: payload.requirementId,
897
+ status: "WORKING"
898
+ });
899
+ await api.spaceWorkflow.aiStartNode({
900
+ requirementId: payload.requirementId,
901
+ nodeId: payload.nodeId,
902
+ agentId: agent.agentId
903
+ });
904
+ const session = new EventSession(payload.prompt);
905
+ const { agentId, failed, failReason } = await runAgentStream(
906
+ payload,
907
+ session,
908
+ agent
909
+ );
910
+ await api.cliRequirements.updateDevStatus({
911
+ requirementId: payload.requirementId,
912
+ status: "IDLE"
913
+ });
914
+ session.writeToFile(payload.cwd, payload.requirementId, agentId);
915
+ if (failed) {
916
+ const failResult = await api.spaceWorkflow.aiFailNode({
917
+ requirementId: payload.requirementId,
918
+ nodeId: payload.nodeId,
919
+ error: failReason
920
+ });
921
+ console.log("[apm] \u5DE5\u4F5C\u6D41\u8282\u70B9\u72B6\u6001:", failResult.nodeStatus);
922
+ return;
923
+ }
924
+ console.log("[Done]");
925
+ try {
926
+ await runUploadArtifact(payload.requirementId, apmRoot);
927
+ } catch (pullErr) {
928
+ console.error("[apm] apm upload-artifact \u5931\u8D25:", pullErr);
929
+ throw pullErr;
930
+ }
931
+ const confirmResult = await api.spaceWorkflow.aiConfirmNode({
932
+ requirementId: payload.requirementId,
933
+ nodeId: payload.nodeId
934
+ });
935
+ console.log("[apm] \u5DE5\u4F5C\u6D41\u8282\u70B9\u72B6\u6001:", confirmResult.nodeStatus);
936
+ }
771
937
  function runConnect(opts) {
772
938
  void (async () => {
773
939
  const cfg = await ensureApmConfig();
@@ -806,113 +972,14 @@ function runConnect(opts) {
806
972
  const text = typeof data === "string" ? data : data.toString();
807
973
  try {
808
974
  const msg = JSON.parse(text);
809
- if (msg.type !== "JOB") {
975
+ if (msg.type === "THEATER_JOB") {
976
+ await handleTheaterJob(api, msg.payload);
810
977
  return;
811
978
  }
812
- const payload = msg.payload;
813
- const apmRoot = join6(payload.cwd, ".apm");
814
- console.log("[apm] ROOT:", apmRoot);
815
- console.log("[apm] workflow node:", payload.nodeId);
816
- try {
817
- await runPull(payload.requirementId, apmRoot);
818
- } catch (pullErr) {
819
- console.error("[apm] apm pull \u5931\u8D25:", pullErr);
820
- throw pullErr;
821
- }
822
- const agent = await (async () => {
823
- const options = {
824
- apiKey: payload.apiKey,
825
- model: { id: payload.model ?? "default" },
826
- local: { cwd: payload.cwd }
827
- };
828
- if (payload.agentId) {
829
- return Agent.resume(payload.agentId, options);
830
- }
831
- return Agent.create(options);
832
- })();
833
- await api.cliRequirements.updateDevStatus({
834
- requirementId: payload.requirementId,
835
- status: "WORKING"
836
- });
837
- await api.spaceWorkflow.aiStartNode({
838
- requirementId: payload.requirementId,
839
- nodeId: payload.nodeId,
840
- agentId: agent.agentId
841
- });
842
- const session = new EventSession(payload.prompt);
843
- const run = await agent.send(payload.prompt);
844
- let agentRunFailed = false;
845
- let agentFailReason = "";
846
- for await (const event of run.stream()) {
847
- if (event.type === "status") {
848
- console.log(`[Status]`, event.message || event.status);
849
- if (event.status === "ERROR") {
850
- agentRunFailed = true;
851
- agentFailReason = event.message?.trim() ?? "";
852
- console.error(
853
- "[apm] Agent \u6267\u884C\u5931\u8D25:",
854
- agentFailReason || "(\u65E0\u5931\u8D25\u539F\u56E0)"
855
- );
856
- break;
857
- }
858
- continue;
859
- }
860
- if (event.type === "assistant") {
861
- const output = event.message.content[0].text;
862
- console.log(`[Output]`, output);
863
- session.addEvent(event);
864
- continue;
865
- }
866
- if (event.type === "thinking") {
867
- const thinking = event.text;
868
- console.log(`[Thinking]`, thinking);
869
- continue;
870
- }
871
- if (event.type === "tool_call") {
872
- if (event.status === "completed" || event.status === "error") {
873
- console.log(`[ToolCall(${event.call_id}) Result]`);
874
- }
875
- session.addEvent(event);
876
- continue;
877
- }
878
- if (event.type === "task") {
879
- console.log(`[Task:${event.status}]`);
880
- session.addEvent(event);
881
- continue;
882
- }
883
- if (event.type === "request") {
884
- console.log(JSON.stringify(event, null, 2));
885
- session.addEvent(event);
886
- continue;
887
- }
888
- console.log("\u672A\u77E5\u4E8B\u4EF6:", JSON.stringify(event, null, 2));
889
- }
890
- await api.cliRequirements.updateDevStatus({
891
- requirementId: payload.requirementId,
892
- status: "IDLE"
893
- });
894
- session.writeToFile(payload.cwd, payload.requirementId, run.agentId);
895
- if (agentRunFailed) {
896
- const failResult = await api.spaceWorkflow.aiFailNode({
897
- requirementId: payload.requirementId,
898
- nodeId: payload.nodeId,
899
- error: agentFailReason
900
- });
901
- console.log("[apm] \u5DE5\u4F5C\u6D41\u8282\u70B9\u72B6\u6001:", failResult.nodeStatus);
979
+ if (msg.type === "JOB") {
980
+ await handleWorkflowJob(api, msg.payload);
902
981
  return;
903
982
  }
904
- console.log("[Done]");
905
- try {
906
- await runUploadArtifact(payload.requirementId, apmRoot);
907
- } catch (pullErr) {
908
- console.error("[apm] apm upload-artifact \u5931\u8D25:", pullErr);
909
- throw pullErr;
910
- }
911
- const confirmResult = await api.spaceWorkflow.aiConfirmNode({
912
- requirementId: payload.requirementId,
913
- nodeId: payload.nodeId
914
- });
915
- console.log("[apm] \u5DE5\u4F5C\u6D41\u8282\u70B9\u72B6\u6001:", confirmResult.nodeStatus);
916
983
  } catch (err) {
917
984
  console.error(
918
985
  "[apm] \u65E0\u6CD5\u89E3\u6790 WebSocket \u6D88\u606F:",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "4.0.16",
3
+ "version": "4.0.18",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,