@xoxoai/checkmate 0.4.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/LICENSE +21 -0
- package/README.md +244 -0
- package/dist/ai/client.d.ts +49 -0
- package/dist/ai/client.d.ts.map +1 -0
- package/dist/ai/client.js +244 -0
- package/dist/ai/client.js.map +1 -0
- package/dist/ai/message-handler.d.ts +11 -0
- package/dist/ai/message-handler.d.ts.map +1 -0
- package/dist/ai/message-handler.js +33 -0
- package/dist/ai/message-handler.js.map +1 -0
- package/dist/ai/message-history.d.ts +19 -0
- package/dist/ai/message-history.d.ts.map +1 -0
- package/dist/ai/message-history.js +48 -0
- package/dist/ai/message-history.js.map +1 -0
- package/dist/ai/prompts.d.ts +4 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +24 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/ai/rate-limit-policy.d.ts +7 -0
- package/dist/ai/rate-limit-policy.d.ts.map +1 -0
- package/dist/ai/rate-limit-policy.js +17 -0
- package/dist/ai/rate-limit-policy.js.map +1 -0
- package/dist/ai/response-processor.d.ts +20 -0
- package/dist/ai/response-processor.d.ts.map +1 -0
- package/dist/ai/response-processor.js +62 -0
- package/dist/ai/response-processor.js.map +1 -0
- package/dist/ai/token-pricing.d.ts +13 -0
- package/dist/ai/token-pricing.d.ts.map +1 -0
- package/dist/ai/token-pricing.js +348 -0
- package/dist/ai/token-pricing.js.map +1 -0
- package/dist/ai/token-tracker.d.ts +33 -0
- package/dist/ai/token-tracker.d.ts.map +1 -0
- package/dist/ai/token-tracker.js +138 -0
- package/dist/ai/token-tracker.js.map +1 -0
- package/dist/ai/tool-response-handler.d.ts +21 -0
- package/dist/ai/tool-response-handler.d.ts.map +1 -0
- package/dist/ai/tool-response-handler.js +54 -0
- package/dist/ai/tool-response-handler.js.map +1 -0
- package/dist/config/runtime-config.d.ts +21 -0
- package/dist/config/runtime-config.d.ts.map +1 -0
- package/dist/config/runtime-config.js +98 -0
- package/dist/config/runtime-config.js.map +1 -0
- package/dist/core.d.ts +8 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +4 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/salesforce/authenticator.d.ts +27 -0
- package/dist/integrations/salesforce/authenticator.d.ts.map +1 -0
- package/dist/integrations/salesforce/authenticator.js +27 -0
- package/dist/integrations/salesforce/authenticator.js.map +1 -0
- package/dist/integrations/salesforce/cli-handler.d.ts +14 -0
- package/dist/integrations/salesforce/cli-handler.d.ts.map +1 -0
- package/dist/integrations/salesforce/cli-handler.js +50 -0
- package/dist/integrations/salesforce/cli-handler.js.map +1 -0
- package/dist/logging/index.d.ts +2 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +4 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.d.ts +5 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +15 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/playwright.d.ts +102 -0
- package/dist/playwright.d.ts.map +1 -0
- package/dist/playwright.js +116 -0
- package/dist/playwright.js.map +1 -0
- package/dist/runtime/extension.d.ts +274 -0
- package/dist/runtime/extension.d.ts.map +1 -0
- package/dist/runtime/extension.js +171 -0
- package/dist/runtime/extension.js.map +1 -0
- package/dist/runtime/runner.d.ts +94 -0
- package/dist/runtime/runner.d.ts.map +1 -0
- package/dist/runtime/runner.js +86 -0
- package/dist/runtime/runner.js.map +1 -0
- package/dist/runtime/step-execution.d.ts +17 -0
- package/dist/runtime/step-execution.d.ts.map +1 -0
- package/dist/runtime/step-execution.js +49 -0
- package/dist/runtime/step-execution.js.map +1 -0
- package/dist/runtime/types.d.ts +79 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +2 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/salesforce.d.ts +71 -0
- package/dist/salesforce.d.ts.map +1 -0
- package/dist/salesforce.js +73 -0
- package/dist/salesforce.js.map +1 -0
- package/dist/tools/browser/screenshot-service.d.ts +10 -0
- package/dist/tools/browser/screenshot-service.d.ts.map +1 -0
- package/dist/tools/browser/screenshot-service.js +23 -0
- package/dist/tools/browser/screenshot-service.js.map +1 -0
- package/dist/tools/browser/snapshot-filter/index.d.ts +4 -0
- package/dist/tools/browser/snapshot-filter/index.d.ts.map +1 -0
- package/dist/tools/browser/snapshot-filter/index.js +4 -0
- package/dist/tools/browser/snapshot-filter/index.js.map +1 -0
- package/dist/tools/browser/snapshot-filter/semantic-scorer.d.ts +15 -0
- package/dist/tools/browser/snapshot-filter/semantic-scorer.d.ts.map +1 -0
- package/dist/tools/browser/snapshot-filter/semantic-scorer.js +99 -0
- package/dist/tools/browser/snapshot-filter/semantic-scorer.js.map +1 -0
- package/dist/tools/browser/snapshot-filter/snapshot-filter.d.ts +4 -0
- package/dist/tools/browser/snapshot-filter/snapshot-filter.d.ts.map +1 -0
- package/dist/tools/browser/snapshot-filter/snapshot-filter.js +57 -0
- package/dist/tools/browser/snapshot-filter/snapshot-filter.js.map +1 -0
- package/dist/tools/browser/snapshot-filter/tree-reconstructor.d.ts +3 -0
- package/dist/tools/browser/snapshot-filter/tree-reconstructor.d.ts.map +1 -0
- package/dist/tools/browser/snapshot-filter/tree-reconstructor.js +85 -0
- package/dist/tools/browser/snapshot-filter/tree-reconstructor.js.map +1 -0
- package/dist/tools/browser/snapshot-service.d.ts +19 -0
- package/dist/tools/browser/snapshot-service.d.ts.map +1 -0
- package/dist/tools/browser/snapshot-service.js +67 -0
- package/dist/tools/browser/snapshot-service.js.map +1 -0
- package/dist/tools/browser/tool.d.ts +34 -0
- package/dist/tools/browser/tool.d.ts.map +1 -0
- package/dist/tools/browser/tool.js +226 -0
- package/dist/tools/browser/tool.js.map +1 -0
- package/dist/tools/browser/transient-state-tracker.d.ts +16 -0
- package/dist/tools/browser/transient-state-tracker.d.ts.map +1 -0
- package/dist/tools/browser/transient-state-tracker.js +266 -0
- package/dist/tools/browser/transient-state-tracker.js.map +1 -0
- package/dist/tools/define-agent-tool.d.ts +45 -0
- package/dist/tools/define-agent-tool.d.ts.map +1 -0
- package/dist/tools/define-agent-tool.js +55 -0
- package/dist/tools/define-agent-tool.js.map +1 -0
- package/dist/tools/dispatcher.d.ts +11 -0
- package/dist/tools/dispatcher.d.ts.map +1 -0
- package/dist/tools/dispatcher.js +49 -0
- package/dist/tools/dispatcher.js.map +1 -0
- package/dist/tools/loop-detector.d.ts +27 -0
- package/dist/tools/loop-detector.d.ts.map +1 -0
- package/dist/tools/loop-detector.js +76 -0
- package/dist/tools/loop-detector.js.map +1 -0
- package/dist/tools/registry.d.ts +21 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +46 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/salesforce/login-tool.d.ts +7 -0
- package/dist/tools/salesforce/login-tool.d.ts.map +1 -0
- package/dist/tools/salesforce/login-tool.js +25 -0
- package/dist/tools/salesforce/login-tool.js.map +1 -0
- package/dist/tools/step/result-tool.d.ts +7 -0
- package/dist/tools/step/result-tool.d.ts.map +1 -0
- package/dist/tools/step/result-tool.js +32 -0
- package/dist/tools/step/result-tool.js.map +1 -0
- package/dist/tools/tool-contract.d.ts +3 -0
- package/dist/tools/tool-contract.d.ts.map +1 -0
- package/dist/tools/tool-contract.js +2 -0
- package/dist/tools/tool-contract.js.map +1 -0
- package/dist/tools/types.d.ts +139 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +4 -0
- package/dist/tools/types.js.map +1 -0
- package/docs/EXTENSIONS.md +233 -0
- package/docs/GUIDE.md +467 -0
- package/docs/ROADMAP.md +47 -0
- package/package.json +106 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getToolName } from './types';
|
|
2
|
+
export class ToolRegistry {
|
|
3
|
+
runtimeConfig;
|
|
4
|
+
tools = [];
|
|
5
|
+
toolsByName = new Map();
|
|
6
|
+
constructor(runtimeConfig) {
|
|
7
|
+
this.runtimeConfig = runtimeConfig;
|
|
8
|
+
}
|
|
9
|
+
register(tool) {
|
|
10
|
+
const tools = Array.isArray(tool) ? tool : [tool];
|
|
11
|
+
for (const registeredTool of tools) {
|
|
12
|
+
const toolName = getToolName(registeredTool);
|
|
13
|
+
if (this.toolsByName.has(toolName)) {
|
|
14
|
+
throw new Error(`Duplicate tool registration for '${toolName}'`);
|
|
15
|
+
}
|
|
16
|
+
this.tools.push(registeredTool);
|
|
17
|
+
this.toolsByName.set(toolName, registeredTool);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
getRuntimeConfig() {
|
|
21
|
+
return this.runtimeConfig;
|
|
22
|
+
}
|
|
23
|
+
resolve(toolName) {
|
|
24
|
+
return this.toolsByName.get(toolName);
|
|
25
|
+
}
|
|
26
|
+
async getTools() {
|
|
27
|
+
const allowedNames = this.runtimeConfig.getAllowedFunctionNames();
|
|
28
|
+
const definitions = this.tools.map((tool) => this.toOpenAiTool(tool));
|
|
29
|
+
if (allowedNames.length === 0) {
|
|
30
|
+
return definitions;
|
|
31
|
+
}
|
|
32
|
+
return definitions.filter((tool) => allowedNames.includes(tool.function.name));
|
|
33
|
+
}
|
|
34
|
+
toOpenAiTool(tool) {
|
|
35
|
+
return {
|
|
36
|
+
type: 'function',
|
|
37
|
+
function: {
|
|
38
|
+
name: tool.definition.name,
|
|
39
|
+
description: tool.definition.description,
|
|
40
|
+
parameters: tool.definition.parameters,
|
|
41
|
+
strict: tool.definition.strict,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,WAAW,EAAE,MAAM,SAAS,CAAA;AAShD,MAAM,OAAO,YAAY;IAIK;IAHZ,KAAK,GAAgB,EAAE,CAAA;IACvB,WAAW,GAAG,IAAI,GAAG,EAAqB,CAAA;IAE3D,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAE7D,QAAQ,CAAC,IAA6B;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QAEjD,KAAK,MAAM,cAAc,IAAI,KAAK,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,CAAC,CAAA;YAC5C,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,oCAAoC,QAAQ,GAAG,CAAC,CAAA;YACjE,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YAC/B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;QAC/C,CAAC;IACF,CAAC;IAED,gBAAgB;QACf,OAAO,IAAI,CAAC,aAAa,CAAA;IAC1B,CAAC;IAED,OAAO,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,QAAQ;QACb,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,uBAAuB,EAAE,CAAA;QACjE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;QAErE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,WAAW,CAAA;QACnB,CAAC;QAED,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/E,CAAC;IAEO,YAAY,CAAC,IAAe;QACnC,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE;gBACT,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI;gBAC1B,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW;gBACxC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU;gBACtC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;aAC9B;SACD,CAAA;IACF,CAAC;CACD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BrowserToolRuntime } from '../browser/tool';
|
|
2
|
+
import { AgentTool } from '../types';
|
|
3
|
+
export declare const SalesforceLoginTool: {
|
|
4
|
+
readonly TOOL_LOGIN_TO_SALESFORCE_ORG: "login_to_salesforce_org";
|
|
5
|
+
};
|
|
6
|
+
export declare function createSalesforceTools(browserRuntime: BrowserToolRuntime): AgentTool[];
|
|
7
|
+
//# sourceMappingURL=login-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-tool.d.ts","sourceRoot":"","sources":["../../../src/tools/salesforce/login-tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAIpC,eAAO,MAAM,mBAAmB;;CAEtB,CAAA;AAEV,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,kBAAkB,GAAG,SAAS,EAAE,CAoBrF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { defineAgentTool } from '../define-agent-tool';
|
|
3
|
+
import { SalesforceAuthenticator } from '../../integrations/salesforce/authenticator';
|
|
4
|
+
import { SalesforceCliHandler } from '../../integrations/salesforce/cli-handler';
|
|
5
|
+
export const SalesforceLoginTool = {
|
|
6
|
+
TOOL_LOGIN_TO_SALESFORCE_ORG: 'login_to_salesforce_org',
|
|
7
|
+
};
|
|
8
|
+
export function createSalesforceTools(browserRuntime) {
|
|
9
|
+
return [
|
|
10
|
+
defineAgentTool({
|
|
11
|
+
name: SalesforceLoginTool.TOOL_LOGIN_TO_SALESFORCE_ORG,
|
|
12
|
+
description: 'Login to a Salesforce org in a browser. Do not use if Salesforce org is opened and logged in. You do not need to specify credentials, the tool will handle it for you.',
|
|
13
|
+
schema: z
|
|
14
|
+
.object({
|
|
15
|
+
goal: z.string().describe('The goal or purpose of logging into the Salesforce org'),
|
|
16
|
+
})
|
|
17
|
+
.strict(),
|
|
18
|
+
handler: async (_args, context) => {
|
|
19
|
+
const frontDoorUrl = await new SalesforceAuthenticator(new SalesforceCliHandler()).ready.then((authenticator) => authenticator.getFrontDoorUrl());
|
|
20
|
+
return browserRuntime.navigateToUrl(frontDoorUrl, context.step);
|
|
21
|
+
},
|
|
22
|
+
}),
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=login-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-tool.js","sourceRoot":"","sources":["../../../src/tools/salesforce/login-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAE1B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAEhF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IAClC,4BAA4B,EAAE,yBAAyB;CAC9C,CAAA;AAEV,MAAM,UAAU,qBAAqB,CAAC,cAAkC;IACvE,OAAO;QACN,eAAe,CAAC;YACf,IAAI,EAAE,mBAAmB,CAAC,4BAA4B;YACtD,WAAW,EACV,wKAAwK;YACzK,MAAM,EAAE,CAAC;iBACP,MAAM,CAAC;gBACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;aACnF,CAAC;iBACD,MAAM,EAAE;YACV,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;gBACjC,MAAM,YAAY,GAAG,MAAM,IAAI,uBAAuB,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAC5F,CAAC,aAAa,EAAE,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,CAClD,CAAA;gBAED,OAAO,cAAc,CAAC,aAAa,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAChE,CAAC;SACD,CAAC;KACF,CAAA;AACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AgentTool } from '../types';
|
|
2
|
+
export declare const StepResultTool: {
|
|
3
|
+
readonly TOOL_FAIL_TEST_STEP: "fail_test_step";
|
|
4
|
+
readonly TOOL_PASS_TEST_STEP: "pass_test_step";
|
|
5
|
+
};
|
|
6
|
+
export declare function createStepResultTools(): AgentTool[];
|
|
7
|
+
//# sourceMappingURL=result-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-tool.d.ts","sourceRoot":"","sources":["../../../src/tools/step/result-tool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEpC,eAAO,MAAM,cAAc;;;CAGjB,CAAA;AAQV,wBAAgB,qBAAqB,IAAI,SAAS,EAAE,CAmBnD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { defineAgentTool } from '../define-agent-tool';
|
|
3
|
+
export const StepResultTool = {
|
|
4
|
+
TOOL_FAIL_TEST_STEP: 'fail_test_step',
|
|
5
|
+
TOOL_PASS_TEST_STEP: 'pass_test_step',
|
|
6
|
+
};
|
|
7
|
+
const stepResultSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
actualResult: z.string().describe('The actual result of the test step'),
|
|
10
|
+
})
|
|
11
|
+
.strict();
|
|
12
|
+
export function createStepResultTools() {
|
|
13
|
+
return [
|
|
14
|
+
defineAgentTool({
|
|
15
|
+
name: StepResultTool.TOOL_FAIL_TEST_STEP,
|
|
16
|
+
description: 'Fail the test step with the actual result',
|
|
17
|
+
schema: stepResultSchema,
|
|
18
|
+
handler: ({ actualResult }, context) => {
|
|
19
|
+
context.resolveStepResult({ passed: false, actual: actualResult });
|
|
20
|
+
},
|
|
21
|
+
}),
|
|
22
|
+
defineAgentTool({
|
|
23
|
+
name: StepResultTool.TOOL_PASS_TEST_STEP,
|
|
24
|
+
description: 'Pass the test step with the actual result',
|
|
25
|
+
schema: stepResultSchema,
|
|
26
|
+
handler: ({ actualResult }, context) => {
|
|
27
|
+
context.resolveStepResult({ passed: true, actual: actualResult });
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=result-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-tool.js","sourceRoot":"","sources":["../../../src/tools/step/result-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAGtD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,mBAAmB,EAAE,gBAAgB;IACrC,mBAAmB,EAAE,gBAAgB;CAC5B,CAAA;AAEV,MAAM,gBAAgB,GAAG,CAAC;KACxB,MAAM,CAAC;IACP,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CACvE,CAAC;KACD,MAAM,EAAE,CAAA;AAEV,MAAM,UAAU,qBAAqB;IACpC,OAAO;QACN,eAAe,CAAC;YACf,IAAI,EAAE,cAAc,CAAC,mBAAmB;YACxC,WAAW,EAAE,2CAA2C;YACxD,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,EAAE;gBACtC,OAAO,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAA;YACnE,CAAC;SACD,CAAC;QACF,eAAe,CAAC;YACf,IAAI,EAAE,cAAc,CAAC,mBAAmB;YACxC,WAAW,EAAE,2CAA2C;YACxD,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,EAAE;gBACtC,OAAO,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAA;YAClE,CAAC;SACD,CAAC;KACF,CAAA;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-contract.d.ts","sourceRoot":"","sources":["../../src/tools/tool-contract.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,QAAQ,GACR,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-contract.js","sourceRoot":"","sources":["../../src/tools/tool-contract.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { ResolveStepResult, Step } from '../runtime/types';
|
|
2
|
+
/**
|
|
3
|
+
* Normalized tool call emitted by the model.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* const call: ToolCall = {
|
|
8
|
+
* name: 'browser_click_or_hover',
|
|
9
|
+
* arguments: { ref: 'e123', hover: false },
|
|
10
|
+
* }
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export type ToolCall = {
|
|
14
|
+
/**
|
|
15
|
+
* Tool name requested by the model.
|
|
16
|
+
*/
|
|
17
|
+
name: string;
|
|
18
|
+
/**
|
|
19
|
+
* Parsed tool arguments.
|
|
20
|
+
*/
|
|
21
|
+
arguments?: unknown;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Serializable tool definition used by Checkmate.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const definition: AgentToolDefinition = {
|
|
29
|
+
* name: 'check_api_health',
|
|
30
|
+
* description: 'Check whether the API is healthy',
|
|
31
|
+
* parameters: { type: 'object', properties: { url: { type: 'string' } } },
|
|
32
|
+
* strict: true,
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export type AgentToolDefinition = {
|
|
37
|
+
/**
|
|
38
|
+
* Stable tool name.
|
|
39
|
+
*/
|
|
40
|
+
name: string;
|
|
41
|
+
/**
|
|
42
|
+
* Short tool description shown to the model.
|
|
43
|
+
*/
|
|
44
|
+
description: string;
|
|
45
|
+
/**
|
|
46
|
+
* JSON schema for the tool parameters.
|
|
47
|
+
*/
|
|
48
|
+
parameters: Record<string, unknown>;
|
|
49
|
+
/**
|
|
50
|
+
* Whether the tool arguments should be validated strictly.
|
|
51
|
+
*/
|
|
52
|
+
strict: boolean;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Structured tool response returned to the model.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* const response: AgentToolResponse = {
|
|
60
|
+
* response: 'Clicked the Submit button.',
|
|
61
|
+
* status: 'success',
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export type AgentToolResponse = {
|
|
66
|
+
/**
|
|
67
|
+
* Human-readable result returned to the model.
|
|
68
|
+
*/
|
|
69
|
+
response: string;
|
|
70
|
+
/**
|
|
71
|
+
* Optional fresh snapshot to append after tool execution.
|
|
72
|
+
*/
|
|
73
|
+
snapshot?: string | null;
|
|
74
|
+
/**
|
|
75
|
+
* Outcome status used in tool execution summaries.
|
|
76
|
+
*/
|
|
77
|
+
status?: 'success' | 'error';
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Any valid value a tool can return.
|
|
81
|
+
*
|
|
82
|
+
* Tools may return a structured response, a plain string, or nothing.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* const result: AgentToolResult = {
|
|
87
|
+
* response: 'API health is good',
|
|
88
|
+
* status: 'success',
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export type AgentToolResult = AgentToolResponse | string | void;
|
|
93
|
+
/**
|
|
94
|
+
* Context passed to every tool execution.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const handler = async (_args: unknown, context: AgentToolContext) => {
|
|
99
|
+
* context.resolveStepResult({ passed: true, actual: context.step.expect })
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export type AgentToolContext = {
|
|
104
|
+
/**
|
|
105
|
+
* Step currently being executed.
|
|
106
|
+
*/
|
|
107
|
+
step: Step;
|
|
108
|
+
/**
|
|
109
|
+
* Callback used to finish the step.
|
|
110
|
+
*/
|
|
111
|
+
resolveStepResult: ResolveStepResult;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Tool contract used by the runner loop.
|
|
115
|
+
*
|
|
116
|
+
* Most users should create tools with `defineTool()` instead of building this object manually.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* const tool: AgentTool = defineTool({
|
|
121
|
+
* name: 'check_api_health',
|
|
122
|
+
* description: 'Check whether the API is healthy',
|
|
123
|
+
* schema: z.object({ url: z.string() }).strict(),
|
|
124
|
+
* handler: async ({ url }) => `API health is good for ${url}`,
|
|
125
|
+
* })
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export type AgentTool = {
|
|
129
|
+
/**
|
|
130
|
+
* Tool definition exposed to the model.
|
|
131
|
+
*/
|
|
132
|
+
definition: AgentToolDefinition;
|
|
133
|
+
/**
|
|
134
|
+
* Tool implementation.
|
|
135
|
+
*/
|
|
136
|
+
execute: (args: unknown, context: AgentToolContext) => Promise<AgentToolResult> | AgentToolResult;
|
|
137
|
+
};
|
|
138
|
+
export declare function getToolName(tool: AgentTool): string;
|
|
139
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAE1D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG;IACjC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAEnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAA;CACf,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC/B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;CAC5B,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAAA;AAE/D;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC9B;;OAEG;IACH,IAAI,EAAE,IAAI,CAAA;IAEV;;OAEG;IACH,iBAAiB,EAAE,iBAAiB,CAAA;CACpC,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,SAAS,GAAG;IACvB;;OAEG;IACH,UAAU,EAAE,mBAAmB,CAAA;IAE/B;;OAEG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAA;CACjG,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAwJA,MAAM,UAAU,WAAW,CAAC,IAAe;IAC1C,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAA;AAC5B,CAAC"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# **_checkmate_** extensions
|
|
2
|
+
|
|
3
|
+
This guide is about how to adapt **_checkmate_** to your own domain.
|
|
4
|
+
|
|
5
|
+
Use it when you want to:
|
|
6
|
+
|
|
7
|
+
- add a new tool
|
|
8
|
+
- add a new extension
|
|
9
|
+
- compose your own runner
|
|
10
|
+
- build on top of `web()` or `salesforce()`
|
|
11
|
+
|
|
12
|
+
## Core Idea
|
|
13
|
+
|
|
14
|
+
`@xoxoai/checkmate/core` stays generic.
|
|
15
|
+
|
|
16
|
+
The runner owns:
|
|
17
|
+
|
|
18
|
+
- the model loop
|
|
19
|
+
- retries
|
|
20
|
+
- pass/fail resolution
|
|
21
|
+
- tool dispatch
|
|
22
|
+
|
|
23
|
+
Extensions add domain-specific behavior such as:
|
|
24
|
+
|
|
25
|
+
- tools
|
|
26
|
+
- system instructions
|
|
27
|
+
- initial step context
|
|
28
|
+
- post-tool context
|
|
29
|
+
- shared capabilities for other extensions
|
|
30
|
+
- teardown logic
|
|
31
|
+
|
|
32
|
+
That is how `web()` and `salesforce()` work, and it is the same model you use for your own extensions.
|
|
33
|
+
|
|
34
|
+
## Tool vs Extension
|
|
35
|
+
|
|
36
|
+
Use `defineTool()` when you need one new action the model can call.
|
|
37
|
+
|
|
38
|
+
Use `defineExtension()` when you need to bundle tools with runtime behavior such as instructions, setup, or extra context.
|
|
39
|
+
|
|
40
|
+
Use `createRunner()` when you want to compose your own runtime from built-in and custom extensions.
|
|
41
|
+
|
|
42
|
+
## Your First Tool
|
|
43
|
+
|
|
44
|
+
A tool is the smallest unit of behavior.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { defineTool } from '@xoxoai/checkmate/core'
|
|
48
|
+
import { z } from 'zod/v4'
|
|
49
|
+
|
|
50
|
+
export const apiHealthTool = defineTool({
|
|
51
|
+
name: 'check_api_health',
|
|
52
|
+
description: 'Check whether the API is healthy',
|
|
53
|
+
schema: z.object({ url: z.string().url() }).strict(),
|
|
54
|
+
handler: async ({ url }) => {
|
|
55
|
+
return {
|
|
56
|
+
response: `API health is good for ${url}`,
|
|
57
|
+
status: 'success',
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Good tools are:
|
|
64
|
+
|
|
65
|
+
- single-purpose
|
|
66
|
+
- concrete
|
|
67
|
+
- easy to describe in one sentence
|
|
68
|
+
- safe to call multiple times
|
|
69
|
+
|
|
70
|
+
## Your First Extension
|
|
71
|
+
|
|
72
|
+
An extension can be as small as a name, one tool, and one instruction.
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { createRunner, defineExtension } from '@xoxoai/checkmate/core'
|
|
76
|
+
import { web } from '@xoxoai/checkmate/playwright'
|
|
77
|
+
import { apiHealthTool } from './api-health-tool'
|
|
78
|
+
|
|
79
|
+
export const apiHealth = defineExtension({
|
|
80
|
+
name: 'api-health',
|
|
81
|
+
tools: [apiHealthTool],
|
|
82
|
+
instructions: ['Use check_api_health before relying on API-driven UI state.'],
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const ai = createRunner({
|
|
86
|
+
extensions: [web({ page }), apiHealth],
|
|
87
|
+
})
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
This already gives you a reusable building block that can be shared across projects.
|
|
91
|
+
|
|
92
|
+
## Extension Hooks
|
|
93
|
+
|
|
94
|
+
Extensions can do more than register tools.
|
|
95
|
+
|
|
96
|
+
`defineExtension()` supports these hooks:
|
|
97
|
+
|
|
98
|
+
- `tools`: register one or more tools
|
|
99
|
+
- `instructions`: append system-level guidance for the model
|
|
100
|
+
- `setup(api)`: register capabilities, tools, hooks, or teardown logic
|
|
101
|
+
- `buildInitialMessages(context)`: add step-specific context before the first model call
|
|
102
|
+
- `handleToolResponses(context)`: append fresh context after tools run
|
|
103
|
+
- `teardown()`: clean up extension-owned resources
|
|
104
|
+
|
|
105
|
+
Example:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { defineExtension } from '@xoxoai/checkmate/core'
|
|
109
|
+
|
|
110
|
+
export const releaseGuard = defineExtension({
|
|
111
|
+
name: 'release-guard',
|
|
112
|
+
instructions: ['Prefer visible release labels over inferred version numbers.'],
|
|
113
|
+
buildInitialMessages: async ({ step }) => [
|
|
114
|
+
{
|
|
115
|
+
role: 'user',
|
|
116
|
+
content: `Current release check target: ${step.expect}`,
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
})
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Setup API
|
|
123
|
+
|
|
124
|
+
Inside `setup(api)`, you can compose richer behavior.
|
|
125
|
+
|
|
126
|
+
Available methods:
|
|
127
|
+
|
|
128
|
+
- `addTool()`
|
|
129
|
+
- `addInstruction()`
|
|
130
|
+
- `addInitialMessages()`
|
|
131
|
+
- `addToolResponsesHook()`
|
|
132
|
+
- `setCapability()`
|
|
133
|
+
- `getCapability()`
|
|
134
|
+
- `onTeardown()`
|
|
135
|
+
|
|
136
|
+
This is the main escape hatch for advanced integrations.
|
|
137
|
+
|
|
138
|
+
## Capabilities and Composition
|
|
139
|
+
|
|
140
|
+
Capabilities let one extension publish something another extension can use without hard-coding the relationship into the core runner.
|
|
141
|
+
|
|
142
|
+
That is how the Salesforce extension builds on the web extension.
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { defineExtension } from '@xoxoai/checkmate/core'
|
|
148
|
+
import { Page } from '@playwright/test'
|
|
149
|
+
import { PlaywrightCapability } from '@xoxoai/checkmate/playwright'
|
|
150
|
+
|
|
151
|
+
export const auditTrail = defineExtension({
|
|
152
|
+
name: 'audit-trail',
|
|
153
|
+
setup(api) {
|
|
154
|
+
const page = api.getCapability<Page>(PlaywrightCapability.PAGE)
|
|
155
|
+
|
|
156
|
+
api.addInstruction(`Current page starts at: ${page.url()}`)
|
|
157
|
+
},
|
|
158
|
+
})
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Prefer capabilities when one extension depends on another extension's runtime objects.
|
|
162
|
+
|
|
163
|
+
## Extending Built-In Extensions
|
|
164
|
+
|
|
165
|
+
Built-in extensions are composable too.
|
|
166
|
+
|
|
167
|
+
You do not need to rewrite `web()` or `salesforce()` to adapt them.
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { web } from '@xoxoai/checkmate/playwright'
|
|
171
|
+
|
|
172
|
+
const companyWeb = web({ page }).extend({
|
|
173
|
+
instructions: ['Prefer visible labels over generated ids.'],
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
You can also add tools or hooks on top of the built-in extension:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const companyWeb = web({ page }).extend({
|
|
181
|
+
tools: [apiHealthTool],
|
|
182
|
+
instructions: ['Check API health before asserting UI state.'],
|
|
183
|
+
})
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
This is usually better than cloning the built-in extension from scratch.
|
|
187
|
+
|
|
188
|
+
## Building a Custom Runner
|
|
189
|
+
|
|
190
|
+
Once you have extensions, create a runner helper that matches your domain.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { createRunner } from '@xoxoai/checkmate/core'
|
|
194
|
+
import { Page } from '@playwright/test'
|
|
195
|
+
import { web } from '@xoxoai/checkmate/playwright'
|
|
196
|
+
import { salesforce } from '@xoxoai/checkmate/salesforce'
|
|
197
|
+
import { apiHealth } from './api-health-extension'
|
|
198
|
+
|
|
199
|
+
export function createAcmeRunner(page: Page) {
|
|
200
|
+
return createRunner({
|
|
201
|
+
extensions: [web({ page }), salesforce(), apiHealth],
|
|
202
|
+
})
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
This keeps test code simple while letting your runtime evolve in one place.
|
|
207
|
+
|
|
208
|
+
## Design Guidelines
|
|
209
|
+
|
|
210
|
+
Keep extensions readable and honest.
|
|
211
|
+
|
|
212
|
+
- Keep tools focused on one action.
|
|
213
|
+
- Keep domain behavior out of the core runner.
|
|
214
|
+
- Prefer extension composition over copying built-ins.
|
|
215
|
+
- Prefer capabilities over direct imports between unrelated extensions.
|
|
216
|
+
- Keep instructions concrete and short.
|
|
217
|
+
- Add initial or post-tool context only when the model truly needs it.
|
|
218
|
+
- Return clear tool responses that help the model decide the next step.
|
|
219
|
+
|
|
220
|
+
## Recommended Progression
|
|
221
|
+
|
|
222
|
+
Most teams should build in this order:
|
|
223
|
+
|
|
224
|
+
1. Start with `@xoxoai/checkmate/playwright`.
|
|
225
|
+
2. Add one custom tool with `defineTool()`.
|
|
226
|
+
3. Group related tools into an extension with `defineExtension()`.
|
|
227
|
+
4. Compose a project-specific runner with `createRunner()`.
|
|
228
|
+
5. Extend built-ins only when you need custom runtime behavior.
|
|
229
|
+
|
|
230
|
+
## See Also
|
|
231
|
+
|
|
232
|
+
- [GUIDE](./GUIDE.md)
|
|
233
|
+
- [README](../README.md)
|