wopee-mcp 1.29.0 → 1.30.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/build/tools/shared/artifactContent.js +24 -0
- package/build/tools/shared/gql-queries.js +1 -0
- package/build/tools/shared/handlers.js +2 -2
- package/build/tools/shared/helpers.js +11 -0
- package/build/tools/wopee_dispatch_agent/format.js +20 -0
- package/build/tools/wopee_dispatch_agent/index.js +1 -17
- package/package.json +1 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strip pretty-printing from `tests.json` before it enters the model's context.
|
|
3
|
+
*
|
|
4
|
+
* The api commits the USER_STORIES artifact indented so the diff of a test-case
|
|
5
|
+
* edit is reviewable in a GitHub PR (autonomous-testing/backlog#4252). That
|
|
6
|
+
* formatting is for humans reading a diff — `fetchArtifact` hands the file
|
|
7
|
+
* straight to the model, where the extra whitespace is pure token cost and buys
|
|
8
|
+
* nothing. `fetch_project_summary` pulls this artifact for every suite in a
|
|
9
|
+
* project, so the cost is multiplied.
|
|
10
|
+
*
|
|
11
|
+
* Fails open: content that does not parse is returned untouched. A broken
|
|
12
|
+
* artifact is still worth showing the model — it can say so.
|
|
13
|
+
*
|
|
14
|
+
* Kept free of enum imports so `node --test` (strip-only TS) can cover it; the
|
|
15
|
+
* artifact-type gate lives in `_compactArtifactContentForModel`.
|
|
16
|
+
*/
|
|
17
|
+
export function compactUserStoriesContent(content) {
|
|
18
|
+
try {
|
|
19
|
+
return JSON.stringify(JSON.parse(content));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return content;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -2,7 +2,7 @@ import { FetchArtifactInputSchema, UpdateArtifactInputSchema, GenerateAIDataInpu
|
|
|
2
2
|
import { FetchArtifact, UpdateArtifact } from "./gql-queries.js";
|
|
3
3
|
import { createFetchArtifactInput, createUpdateArtifactInput, createGenerateAIDataInput, } from "./factories.js";
|
|
4
4
|
import { requestClient } from "../../utils/requestClient.js";
|
|
5
|
-
import { _convertToArtifactType, _parseError, _parseGenerateArtifactType, } from "./helpers.js";
|
|
5
|
+
import { _compactArtifactContentForModel, _convertToArtifactType, _parseError, _parseGenerateArtifactType, } from "./helpers.js";
|
|
6
6
|
export async function fetchArtifact(input) {
|
|
7
7
|
try {
|
|
8
8
|
const { type, suiteUuid, identifier } = input;
|
|
@@ -28,7 +28,7 @@ export async function fetchArtifact(input) {
|
|
|
28
28
|
content: [
|
|
29
29
|
{
|
|
30
30
|
type: "text",
|
|
31
|
-
text: result.fetchArtifact.content,
|
|
31
|
+
text: _compactArtifactContentForModel(type, result.fetchArtifact.content),
|
|
32
32
|
},
|
|
33
33
|
],
|
|
34
34
|
};
|
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { GenerateAppContext, GenerateGeneralUserStories, GenerateReusableTestCases, GenerateReusableTestCaseSteps, GenerateTestCases, GenerateTestCaseSteps, GenerateUserStoriesWithTestCases, } from "./gql-queries.js";
|
|
3
3
|
import { ArtifactType, GenerateArtifactType } from "./types.js";
|
|
4
4
|
import { RequestError } from "../../utils/requestClient.js";
|
|
5
|
+
import { compactUserStoriesContent } from "./artifactContent.js";
|
|
5
6
|
export function _convertToArtifactType(type) {
|
|
6
7
|
switch (type) {
|
|
7
8
|
case GenerateArtifactType.APP_CONTEXT:
|
|
@@ -95,3 +96,13 @@ export function _parseError(error) {
|
|
|
95
96
|
],
|
|
96
97
|
};
|
|
97
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Only USER_STORIES is JSON: APP_CONTEXT / GENERAL_USER_STORIES are markdown and
|
|
101
|
+
* PLAYWRIGHT_CODE is TypeScript, where collapsing whitespace would corrupt the
|
|
102
|
+
* file. See `compactUserStoriesContent` for why the artifact is compacted at all.
|
|
103
|
+
*/
|
|
104
|
+
export function _compactArtifactContentForModel(type, content) {
|
|
105
|
+
if (type !== ArtifactType.USER_STORIES)
|
|
106
|
+
return content;
|
|
107
|
+
return compactUserStoriesContent(content);
|
|
108
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function formatDispatchSuccess(testCases, input) {
|
|
2
|
+
const lines = [
|
|
3
|
+
"DISPATCH SUCCESSFUL — tests are now RUNNING (not yet completed).",
|
|
4
|
+
"",
|
|
5
|
+
"Tracking:",
|
|
6
|
+
`- Suite UUID: ${testCases[0]?.suiteUuid ?? input.suiteUuid}`,
|
|
7
|
+
`- Analysis Suite UUID: ${testCases[0]?.analysisSuiteUuid ?? "N/A"}`,
|
|
8
|
+
`- Analysis Identifier: ${testCases[0]?.analysisIdentifier ?? input.analysisIdentifier}`,
|
|
9
|
+
"",
|
|
10
|
+
"Test cases dispatched:",
|
|
11
|
+
];
|
|
12
|
+
// Each row's uuid and run name are the handles for tracking THIS dispatch (backlog#4382).
|
|
13
|
+
// The run name is the GitHub Actions title verbatim and is unique per dispatch, so a caller
|
|
14
|
+
// no longer has to guess which of several identically-named runs is its own.
|
|
15
|
+
for (const tc of testCases) {
|
|
16
|
+
lines.push(`- ${tc.userStoryId}:${tc.testCaseId} → executionStatus: ${tc.executionStatus}`, ` executedTestCaseUuid: ${tc.uuid}`, ...(tc.runName ? [` runName: ${tc.runName}`] : []));
|
|
17
|
+
}
|
|
18
|
+
lines.push("", "IMPORTANT: These tests are RUNNING asynchronously. Do NOT report them as passed or failed.", "Tell the user their tests are running and results will be available shortly (typically 1-3 minutes).", "You will receive a follow-up notification in chat when tests complete with full results.");
|
|
19
|
+
return lines.join("\n");
|
|
20
|
+
}
|
|
@@ -3,25 +3,9 @@ import { ToolName } from "../shared/types.js";
|
|
|
3
3
|
import { _parseError } from "../shared/helpers.js";
|
|
4
4
|
import { createDispatchAgentInput } from "./factory.js";
|
|
5
5
|
import { DispatchAgent } from "../shared/gql-queries.js";
|
|
6
|
+
import { formatDispatchSuccess } from "./format.js";
|
|
6
7
|
import { requestClient } from "../../utils/requestClient.js";
|
|
7
8
|
import { withRetry } from "../../utils/withRetry.js";
|
|
8
|
-
function formatDispatchSuccess(testCases, input) {
|
|
9
|
-
const lines = [
|
|
10
|
-
"DISPATCH SUCCESSFUL — tests are now RUNNING (not yet completed).",
|
|
11
|
-
"",
|
|
12
|
-
"Tracking:",
|
|
13
|
-
`- Suite UUID: ${testCases[0]?.suiteUuid ?? input.suiteUuid}`,
|
|
14
|
-
`- Analysis Suite UUID: ${testCases[0]?.analysisSuiteUuid ?? "N/A"}`,
|
|
15
|
-
`- Analysis Identifier: ${testCases[0]?.analysisIdentifier ?? input.analysisIdentifier}`,
|
|
16
|
-
"",
|
|
17
|
-
"Test cases dispatched:",
|
|
18
|
-
];
|
|
19
|
-
for (const tc of testCases) {
|
|
20
|
-
lines.push(`- ${tc.userStoryId}:${tc.testCaseId} → executionStatus: ${tc.executionStatus}`);
|
|
21
|
-
}
|
|
22
|
-
lines.push("", "IMPORTANT: These tests are RUNNING asynchronously. Do NOT report them as passed or failed.", "Tell the user their tests are running and results will be available shortly (typically 1-3 minutes).", "You will receive a follow-up notification in chat when tests complete with full results.");
|
|
23
|
-
return lines.join("\n");
|
|
24
|
-
}
|
|
25
9
|
export const wopeeDispatchAgent = {
|
|
26
10
|
name: ToolName.WOPEE_DISPATCH_AGENT,
|
|
27
11
|
config: {
|
package/package.json
CHANGED