@a5c-ai/tasks-adapter 5.1.1-staging.52898ebfc24f
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/README.md +125 -0
- package/dist/auth/forge-interface.d.ts +67 -0
- package/dist/auth/forge-interface.d.ts.map +1 -0
- package/dist/auth/forge-interface.js +69 -0
- package/dist/auth/github-app.d.ts +64 -0
- package/dist/auth/github-app.d.ts.map +1 -0
- package/dist/auth/github-app.js +141 -0
- package/dist/auth/github-oauth.d.ts +27 -0
- package/dist/auth/github-oauth.d.ts.map +1 -0
- package/dist/auth/github-oauth.js +89 -0
- package/dist/auth/index.d.ts +8 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +14 -0
- package/dist/auth/jwt.d.ts +24 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +43 -0
- package/dist/auth/middleware.d.ts +22 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +36 -0
- package/dist/auth/ssh-keys.d.ts +21 -0
- package/dist/auth/ssh-keys.d.ts.map +1 -0
- package/dist/auth/ssh-keys.js +59 -0
- package/dist/auth/types.d.ts +165 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +53 -0
- package/dist/backend.d.ts +248 -0
- package/dist/backend.d.ts.map +1 -0
- package/dist/backend.js +40 -0
- package/dist/backends/adapters.d.ts +99 -0
- package/dist/backends/adapters.d.ts.map +1 -0
- package/dist/backends/adapters.js +308 -0
- package/dist/backends/external-tracker.d.ts +133 -0
- package/dist/backends/external-tracker.d.ts.map +1 -0
- package/dist/backends/external-tracker.js +731 -0
- package/dist/backends/git-native.d.ts +69 -0
- package/dist/backends/git-native.d.ts.map +1 -0
- package/dist/backends/git-native.js +797 -0
- package/dist/backends/github-issues.d.ts +78 -0
- package/dist/backends/github-issues.d.ts.map +1 -0
- package/dist/backends/github-issues.js +806 -0
- package/dist/backends/index.d.ts +52 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +151 -0
- package/dist/backends/server.d.ts +42 -0
- package/dist/backends/server.d.ts.map +1 -0
- package/dist/backends/server.js +305 -0
- package/dist/cli/auth-store.d.ts +49 -0
- package/dist/cli/auth-store.d.ts.map +1 -0
- package/dist/cli/auth-store.js +150 -0
- package/dist/cli/client-config.d.ts +10 -0
- package/dist/cli/client-config.d.ts.map +1 -0
- package/dist/cli/client-config.js +87 -0
- package/dist/cli/commands/ask.d.ts +3 -0
- package/dist/cli/commands/ask.d.ts.map +1 -0
- package/dist/cli/commands/ask.js +171 -0
- package/dist/cli/commands/auth.d.ts +3 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +510 -0
- package/dist/cli/commands/breakpoints.d.ts +3 -0
- package/dist/cli/commands/breakpoints.d.ts.map +1 -0
- package/dist/cli/commands/breakpoints.js +311 -0
- package/dist/cli/commands/responder-loop.d.ts +3 -0
- package/dist/cli/commands/responder-loop.d.ts.map +1 -0
- package/dist/cli/commands/responder-loop.js +78 -0
- package/dist/cli/commands/responders.d.ts +3 -0
- package/dist/cli/commands/responders.d.ts.map +1 -0
- package/dist/cli/commands/responders.js +157 -0
- package/dist/cli/commands/rules.d.ts +3 -0
- package/dist/cli/commands/rules.d.ts.map +1 -0
- package/dist/cli/commands/rules.js +105 -0
- package/dist/cli/commands/server.d.ts +3 -0
- package/dist/cli/commands/server.d.ts.map +1 -0
- package/dist/cli/commands/server.js +34 -0
- package/dist/cli/commands/tasks.d.ts +3 -0
- package/dist/cli/commands/tasks.d.ts.map +1 -0
- package/dist/cli/commands/tasks.js +281 -0
- package/dist/cli/commands/templates.d.ts +3 -0
- package/dist/cli/commands/templates.d.ts.map +1 -0
- package/dist/cli/commands/templates.js +100 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +9 -0
- package/dist/cli/output.d.ts +26 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +143 -0
- package/dist/cli/program.d.ts +6 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +38 -0
- package/dist/cli/tasks-adapter.d.ts +3 -0
- package/dist/cli/tasks-adapter.d.ts.map +1 -0
- package/dist/cli/tasks-adapter.js +4 -0
- package/dist/client/answer-poller.d.ts +52 -0
- package/dist/client/answer-poller.d.ts.map +1 -0
- package/dist/client/answer-poller.js +200 -0
- package/dist/client/auth-client.d.ts +200 -0
- package/dist/client/auth-client.d.ts.map +1 -0
- package/dist/client/auth-client.js +309 -0
- package/dist/client/breakpoint-router.d.ts +45 -0
- package/dist/client/breakpoint-router.d.ts.map +1 -0
- package/dist/client/breakpoint-router.js +45 -0
- package/dist/client/index.d.ts +17 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +16 -0
- package/dist/client/profile-validator.d.ts +34 -0
- package/dist/client/profile-validator.d.ts.map +1 -0
- package/dist/client/profile-validator.js +89 -0
- package/dist/client/responder-client.d.ts +39 -0
- package/dist/client/responder-client.d.ts.map +1 -0
- package/dist/client/responder-client.js +72 -0
- package/dist/client/responder-matcher.d.ts +49 -0
- package/dist/client/responder-matcher.d.ts.map +1 -0
- package/dist/client/responder-matcher.js +226 -0
- package/dist/client/server-client.d.ts +124 -0
- package/dist/client/server-client.d.ts.map +1 -0
- package/dist/client/server-client.js +266 -0
- package/dist/client/timeout-manager.d.ts +47 -0
- package/dist/client/timeout-manager.d.ts.map +1 -0
- package/dist/client/timeout-manager.js +77 -0
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +93 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +2 -0
- package/dist/harness/interaction-provider.d.ts +71 -0
- package/dist/harness/interaction-provider.d.ts.map +1 -0
- package/dist/harness/interaction-provider.js +124 -0
- package/dist/harness/routing-rules.d.ts +7 -0
- package/dist/harness/routing-rules.d.ts.map +1 -0
- package/dist/harness/routing-rules.js +37 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/mcp/backend-resolver.d.ts +43 -0
- package/dist/mcp/backend-resolver.d.ts.map +1 -0
- package/dist/mcp/backend-resolver.js +111 -0
- package/dist/mcp/http-transport.d.ts +37 -0
- package/dist/mcp/http-transport.d.ts.map +1 -0
- package/dist/mcp/http-transport.js +103 -0
- package/dist/mcp/index.d.ts +16 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +12 -0
- package/dist/mcp/server.d.ts +20 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +259 -0
- package/dist/mcp/tools/answer-breakpoint.d.ts +32 -0
- package/dist/mcp/tools/answer-breakpoint.d.ts.map +1 -0
- package/dist/mcp/tools/answer-breakpoint.js +45 -0
- package/dist/mcp/tools/ask-breakpoint.d.ts +58 -0
- package/dist/mcp/tools/ask-breakpoint.d.ts.map +1 -0
- package/dist/mcp/tools/ask-breakpoint.js +78 -0
- package/dist/mcp/tools/check-status.d.ts +16 -0
- package/dist/mcp/tools/check-status.d.ts.map +1 -0
- package/dist/mcp/tools/check-status.js +18 -0
- package/dist/mcp/tools/claim-breakpoint.d.ts +18 -0
- package/dist/mcp/tools/claim-breakpoint.d.ts.map +1 -0
- package/dist/mcp/tools/claim-breakpoint.js +28 -0
- package/dist/mcp/tools/list-breakpoints.d.ts +16 -0
- package/dist/mcp/tools/list-breakpoints.d.ts.map +1 -0
- package/dist/mcp/tools/list-breakpoints.js +14 -0
- package/dist/mcp/tools/list-responders.d.ts +18 -0
- package/dist/mcp/tools/list-responders.d.ts.map +1 -0
- package/dist/mcp/tools/list-responders.js +37 -0
- package/dist/mcp/tools/native-tasks.d.ts +270 -0
- package/dist/mcp/tools/native-tasks.d.ts.map +1 -0
- package/dist/mcp/tools/native-tasks.js +481 -0
- package/dist/mcp/tools/poll-breakpoints.d.ts +18 -0
- package/dist/mcp/tools/poll-breakpoints.d.ts.map +1 -0
- package/dist/mcp/tools/poll-breakpoints.js +36 -0
- package/dist/mcp/tools/verify-answer.d.ts +16 -0
- package/dist/mcp/tools/verify-answer.d.ts.map +1 -0
- package/dist/mcp/tools/verify-answer.js +38 -0
- package/dist/proven/index.d.ts +5 -0
- package/dist/proven/index.d.ts.map +1 -0
- package/dist/proven/index.js +3 -0
- package/dist/proven/keys.d.ts +33 -0
- package/dist/proven/keys.d.ts.map +1 -0
- package/dist/proven/keys.js +117 -0
- package/dist/proven/sign.d.ts +16 -0
- package/dist/proven/sign.d.ts.map +1 -0
- package/dist/proven/sign.js +60 -0
- package/dist/proven/types.d.ts +26 -0
- package/dist/proven/types.d.ts.map +1 -0
- package/dist/proven/types.js +5 -0
- package/dist/proven/verify.d.ts +6 -0
- package/dist/proven/verify.d.ts.map +1 -0
- package/dist/proven/verify.js +58 -0
- package/dist/responders/types.d.ts +38 -0
- package/dist/responders/types.d.ts.map +1 -0
- package/dist/responders/types.js +1 -0
- package/dist/router.d.ts +51 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +200 -0
- package/dist/types.d.ts +7711 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +479 -0
- package/package.json +96 -0
- package/responder/README.md +42 -0
- package/responder/backend-responder.json +9 -0
- package/responder/devops-responder.json +9 -0
- package/responder/frontend-responder.json +9 -0
- package/responder/schema.json +89 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { DEFAULT_POLL_INTERVAL_MS } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Client used by responders to receive, claim, and answer breakpoints.
|
|
4
|
+
*/
|
|
5
|
+
export class ResponderClient {
|
|
6
|
+
client;
|
|
7
|
+
responderId;
|
|
8
|
+
pollingTimer = null;
|
|
9
|
+
constructor(client, responderId) {
|
|
10
|
+
this.client = client;
|
|
11
|
+
this.responderId = responderId;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Fetch all pending breakpoints routed to this responder.
|
|
15
|
+
*/
|
|
16
|
+
async fetchPendingBreakpoints() {
|
|
17
|
+
return this.client.listPendingBreakpoints(this.responderId);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Claim a breakpoint so no other responder can answer it.
|
|
21
|
+
*/
|
|
22
|
+
async claimBreakpoint(breakpointId) {
|
|
23
|
+
return this.client.claimBreakpoint(breakpointId, this.responderId);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Submit an answer to a claimed breakpoint.
|
|
27
|
+
*/
|
|
28
|
+
async submitAnswer(breakpointId, text, confidence = 80, references = []) {
|
|
29
|
+
return this.client.submitAnswer(breakpointId, {
|
|
30
|
+
responderId: this.responderId,
|
|
31
|
+
responderName: this.responderId, // Server should resolve the actual name
|
|
32
|
+
text,
|
|
33
|
+
confidence,
|
|
34
|
+
references,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Start a polling loop that periodically checks for new pending breakpoints
|
|
39
|
+
* and invokes the callback when breakpoints are found.
|
|
40
|
+
*
|
|
41
|
+
* Returns a function to stop the loop.
|
|
42
|
+
*/
|
|
43
|
+
startPollingLoop(callback, intervalMs = DEFAULT_POLL_INTERVAL_MS) {
|
|
44
|
+
// Stop any existing loop
|
|
45
|
+
this.stopPollingLoop();
|
|
46
|
+
const poll = async () => {
|
|
47
|
+
try {
|
|
48
|
+
const breakpoints = await this.fetchPendingBreakpoints();
|
|
49
|
+
if (breakpoints.length > 0) {
|
|
50
|
+
await callback(breakpoints);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
// Log polling errors but continue the loop
|
|
55
|
+
console.error("Responder polling error:", err);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// Run immediately, then on interval
|
|
59
|
+
void poll();
|
|
60
|
+
this.pollingTimer = setInterval(() => void poll(), intervalMs);
|
|
61
|
+
return () => this.stopPollingLoop();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Stop the current polling loop if running.
|
|
65
|
+
*/
|
|
66
|
+
stopPollingLoop() {
|
|
67
|
+
if (this.pollingTimer !== null) {
|
|
68
|
+
clearInterval(this.pollingTimer);
|
|
69
|
+
this.pollingTimer = null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { RepoConfigResolutionOptions } from "../config.js";
|
|
2
|
+
import type { ResponderProfile, BreakpointContext } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* A responder profile augmented with a relevance score.
|
|
5
|
+
*/
|
|
6
|
+
export interface ScoredResponder {
|
|
7
|
+
responder: ResponderProfile;
|
|
8
|
+
score: number;
|
|
9
|
+
matchedDomains: string[];
|
|
10
|
+
matchedTopics: string[];
|
|
11
|
+
matchedKeywords: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface ResponderMatcherOptions extends RepoConfigResolutionOptions {
|
|
14
|
+
responders?: ResponderProfile[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Loads responder profiles from disk and matches them to breakpoints
|
|
18
|
+
* based on domain, tag, and keyword overlap.
|
|
19
|
+
*/
|
|
20
|
+
export declare class ResponderMatcher {
|
|
21
|
+
private responders;
|
|
22
|
+
private loaded;
|
|
23
|
+
private readonly options;
|
|
24
|
+
constructor(options?: string | ResponderMatcherOptions);
|
|
25
|
+
/**
|
|
26
|
+
* Read all .json / .yaml files from the responder directory,
|
|
27
|
+
* parse them, and validate against the ResponderProfile schema.
|
|
28
|
+
* Invalid files are silently skipped (logged to stderr).
|
|
29
|
+
*/
|
|
30
|
+
loadResponders(): Promise<ResponderProfile[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Return all loaded responders.
|
|
33
|
+
*/
|
|
34
|
+
getResponders(): ResponderProfile[];
|
|
35
|
+
/**
|
|
36
|
+
* Score and rank responders by relevance to a breakpoint.
|
|
37
|
+
*
|
|
38
|
+
* Scoring algorithm:
|
|
39
|
+
* - For each domain of each responder:
|
|
40
|
+
* - +3 per domain keyword match
|
|
41
|
+
* - For each tag of each responder:
|
|
42
|
+
* - +2 per tag match
|
|
43
|
+
* - Responders with availability=false receive a 0 score
|
|
44
|
+
*
|
|
45
|
+
* Returns responders sorted by descending score (only those with score > 0).
|
|
46
|
+
*/
|
|
47
|
+
matchResponders(breakpointText: string, context?: BreakpointContext, requiredDomains?: string[]): ScoredResponder[];
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=responder-matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responder-matcher.d.ts","sourceRoot":"","sources":["../../src/client/responder-matcher.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAwB,SAAQ,2BAA2B;IAC1E,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;gBAEtC,OAAO,GAAE,MAAM,GAAG,uBAA4B;IAU1D;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAmDnD;;OAEG;IACH,aAAa,IAAI,gBAAgB,EAAE;IAInC;;;;;;;;;;;OAWG;IACH,eAAe,CACb,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,iBAAiB,EAC3B,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,eAAe,EAAE;CAuErB"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { join, extname } from "node:path";
|
|
3
|
+
import { resolveResponderDirectory } from "../config.js";
|
|
4
|
+
import { ResponderProfileSchema } from "../types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Loads responder profiles from disk and matches them to breakpoints
|
|
7
|
+
* based on domain, tag, and keyword overlap.
|
|
8
|
+
*/
|
|
9
|
+
export class ResponderMatcher {
|
|
10
|
+
responders = [];
|
|
11
|
+
loaded = false;
|
|
12
|
+
options;
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
this.options = typeof options === "string"
|
|
15
|
+
? { responderDir: options }
|
|
16
|
+
: options;
|
|
17
|
+
if (this.options.responders) {
|
|
18
|
+
this.responders = [...this.options.responders];
|
|
19
|
+
this.loaded = true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Read all .json / .yaml files from the responder directory,
|
|
24
|
+
* parse them, and validate against the ResponderProfile schema.
|
|
25
|
+
* Invalid files are silently skipped (logged to stderr).
|
|
26
|
+
*/
|
|
27
|
+
async loadResponders() {
|
|
28
|
+
if (this.options.responders) {
|
|
29
|
+
return [...this.responders];
|
|
30
|
+
}
|
|
31
|
+
this.responders = [];
|
|
32
|
+
const responderDir = resolveResponderDirectory(this.options);
|
|
33
|
+
let entries;
|
|
34
|
+
try {
|
|
35
|
+
entries = await readdir(responderDir);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Directory does not exist or is not readable
|
|
39
|
+
this.loaded = true;
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
const validExtensions = new Set([".json", ".yaml", ".yml"]);
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
const ext = extname(entry).toLowerCase();
|
|
45
|
+
if (!validExtensions.has(ext))
|
|
46
|
+
continue;
|
|
47
|
+
const filePath = join(responderDir, entry);
|
|
48
|
+
try {
|
|
49
|
+
const raw = await readFile(filePath, "utf-8");
|
|
50
|
+
let parsed;
|
|
51
|
+
if (ext === ".json") {
|
|
52
|
+
parsed = JSON.parse(raw);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Simple YAML-subset parser: supports flat and nested objects
|
|
56
|
+
// produced by common responder profile generators.
|
|
57
|
+
parsed = parseSimpleYaml(raw);
|
|
58
|
+
}
|
|
59
|
+
const result = ResponderProfileSchema.safeParse(parsed);
|
|
60
|
+
if (result.success) {
|
|
61
|
+
this.responders.push(result.data);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.error(`Invalid responder profile in ${filePath}: ${result.error.message}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.error(`Failed to read responder file ${filePath}:`, err);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
this.loaded = true;
|
|
72
|
+
return [...this.responders];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Return all loaded responders.
|
|
76
|
+
*/
|
|
77
|
+
getResponders() {
|
|
78
|
+
return [...this.responders];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Score and rank responders by relevance to a breakpoint.
|
|
82
|
+
*
|
|
83
|
+
* Scoring algorithm:
|
|
84
|
+
* - For each domain of each responder:
|
|
85
|
+
* - +3 per domain keyword match
|
|
86
|
+
* - For each tag of each responder:
|
|
87
|
+
* - +2 per tag match
|
|
88
|
+
* - Responders with availability=false receive a 0 score
|
|
89
|
+
*
|
|
90
|
+
* Returns responders sorted by descending score (only those with score > 0).
|
|
91
|
+
*/
|
|
92
|
+
matchResponders(breakpointText, context, requiredDomains) {
|
|
93
|
+
if (!this.loaded) {
|
|
94
|
+
throw new Error("Responders not loaded. Call loadResponders() first.");
|
|
95
|
+
}
|
|
96
|
+
// Build a set of tokens from the breakpoint and its context.
|
|
97
|
+
const tokens = tokenize(breakpointText);
|
|
98
|
+
if (context) {
|
|
99
|
+
for (const tag of context.tags) {
|
|
100
|
+
for (const t of tokenize(tag))
|
|
101
|
+
tokens.add(t);
|
|
102
|
+
}
|
|
103
|
+
for (const t of tokenize(context.description))
|
|
104
|
+
tokens.add(t);
|
|
105
|
+
}
|
|
106
|
+
const requiredSet = requiredDomains
|
|
107
|
+
? new Set(requiredDomains.map((d) => d.toLowerCase()))
|
|
108
|
+
: undefined;
|
|
109
|
+
const scored = [];
|
|
110
|
+
for (const responder of this.responders) {
|
|
111
|
+
// Skip unavailable responders
|
|
112
|
+
if (!responder.availability)
|
|
113
|
+
continue;
|
|
114
|
+
let totalScore = 0;
|
|
115
|
+
const matchedDomains = new Set();
|
|
116
|
+
const matchedTopics = new Set();
|
|
117
|
+
const matchedKeywords = new Set();
|
|
118
|
+
for (const domain of responder.domains) {
|
|
119
|
+
const domainLower = domain.toLowerCase();
|
|
120
|
+
// If required domains specified, only consider matching domains
|
|
121
|
+
if (requiredSet && !requiredSet.has(domainLower))
|
|
122
|
+
continue;
|
|
123
|
+
// Domain match: check if any token matches domain words
|
|
124
|
+
for (const domainToken of tokenize(domain)) {
|
|
125
|
+
if (tokens.has(domainToken)) {
|
|
126
|
+
totalScore += 3;
|
|
127
|
+
matchedDomains.add(domain);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Tag matches
|
|
132
|
+
for (const tag of responder.tags) {
|
|
133
|
+
const tagTokens = tokenize(tag);
|
|
134
|
+
for (const tt of tagTokens) {
|
|
135
|
+
if (tokens.has(tt)) {
|
|
136
|
+
totalScore += 2;
|
|
137
|
+
matchedTopics.add(tag);
|
|
138
|
+
break; // count each tag once
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (totalScore > 0) {
|
|
143
|
+
scored.push({
|
|
144
|
+
responder,
|
|
145
|
+
score: totalScore,
|
|
146
|
+
matchedDomains: [...matchedDomains],
|
|
147
|
+
matchedTopics: [...matchedTopics],
|
|
148
|
+
matchedKeywords: [...matchedKeywords],
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Sort descending by score
|
|
153
|
+
scored.sort((a, b) => b.score - a.score);
|
|
154
|
+
return scored;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// -- Helpers ------------------------------------------------------------------
|
|
158
|
+
/**
|
|
159
|
+
* Tokenize a string into a set of lowercase words (3+ chars).
|
|
160
|
+
*/
|
|
161
|
+
function tokenize(text) {
|
|
162
|
+
const words = text
|
|
163
|
+
.toLowerCase()
|
|
164
|
+
.split(/[\s\-_/,.;:!?()[\]{}'"]+/)
|
|
165
|
+
.filter((w) => w.length >= 3);
|
|
166
|
+
return new Set(words);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Minimal YAML-like parser that handles the subset of YAML used
|
|
170
|
+
* in responder profile files. Supports simple key: value pairs,
|
|
171
|
+
* arrays (- item), and nested objects via indentation.
|
|
172
|
+
*
|
|
173
|
+
* For production use, replace with the `yaml` package.
|
|
174
|
+
*/
|
|
175
|
+
function parseSimpleYaml(text) {
|
|
176
|
+
const lines = text.split("\n");
|
|
177
|
+
const root = {};
|
|
178
|
+
let currentArray = null;
|
|
179
|
+
for (const rawLine of lines) {
|
|
180
|
+
const line = rawLine.replace(/\r$/, "");
|
|
181
|
+
// Skip comments and blank lines
|
|
182
|
+
if (/^\s*#/.test(line) || /^\s*$/.test(line))
|
|
183
|
+
continue;
|
|
184
|
+
// Array item
|
|
185
|
+
const arrayMatch = /^\s+-\s+(.*)$/.exec(line);
|
|
186
|
+
if (arrayMatch && currentArray) {
|
|
187
|
+
let val = arrayMatch[1].trim();
|
|
188
|
+
// Try to parse as number/boolean
|
|
189
|
+
val = coerceYamlValue(val);
|
|
190
|
+
currentArray.push(val);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
// Key: value
|
|
194
|
+
const kvMatch = /^(\w[\w\s]*):\s*(.*)$/.exec(line);
|
|
195
|
+
if (kvMatch) {
|
|
196
|
+
const key = kvMatch[1].trim();
|
|
197
|
+
const rawVal = kvMatch[2].trim();
|
|
198
|
+
if (rawVal === "" || rawVal === "|" || rawVal === ">") {
|
|
199
|
+
// Start of array or nested object - will be filled by subsequent lines
|
|
200
|
+
currentArray = [];
|
|
201
|
+
root[key] = currentArray;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
root[key] = coerceYamlValue(rawVal);
|
|
205
|
+
currentArray = null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return root;
|
|
210
|
+
}
|
|
211
|
+
function coerceYamlValue(val) {
|
|
212
|
+
if (val === "true")
|
|
213
|
+
return true;
|
|
214
|
+
if (val === "false")
|
|
215
|
+
return false;
|
|
216
|
+
if (val === "null")
|
|
217
|
+
return null;
|
|
218
|
+
const num = Number(val);
|
|
219
|
+
if (!isNaN(num) && val !== "")
|
|
220
|
+
return num;
|
|
221
|
+
// Strip surrounding quotes
|
|
222
|
+
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
|
|
223
|
+
return val.slice(1, -1);
|
|
224
|
+
}
|
|
225
|
+
return val;
|
|
226
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { Breakpoint, BreakpointAnswer, BreakpointBrowserSession, BreakpointSessionView, ResponderProfile } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Error thrown when the server returns a non-OK response.
|
|
4
|
+
*/
|
|
5
|
+
export declare class ServerError extends Error {
|
|
6
|
+
readonly status: number;
|
|
7
|
+
readonly statusText: string;
|
|
8
|
+
readonly body?: string | undefined;
|
|
9
|
+
constructor(status: number, statusText: string, body?: string | undefined);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Lightweight wrapper around an SSE connection using fetch + ReadableStream.
|
|
13
|
+
* Provides an EventSource-like interface without requiring the EventSource API.
|
|
14
|
+
*/
|
|
15
|
+
export interface SSEStream {
|
|
16
|
+
/** Register a handler for a named event type. */
|
|
17
|
+
on(event: string, handler: (data: string) => void): void;
|
|
18
|
+
/** Register a handler for errors. */
|
|
19
|
+
onError(handler: (error: Error) => void): void;
|
|
20
|
+
/** Close the underlying connection. */
|
|
21
|
+
close(): void;
|
|
22
|
+
}
|
|
23
|
+
export interface ServerClientOptions {
|
|
24
|
+
baseUrl?: string;
|
|
25
|
+
defaultHeaders?: Record<string, string>;
|
|
26
|
+
}
|
|
27
|
+
export declare const DEFAULT_BMUX_SERVER_URL = "https://tasks-adapter.a5c.ai/api/v1";
|
|
28
|
+
/**
|
|
29
|
+
* HTTP client for communicating with the Breakpoints Adapter server.
|
|
30
|
+
*/
|
|
31
|
+
export declare class ServerClient {
|
|
32
|
+
readonly baseUrl: string;
|
|
33
|
+
private readonly defaultHeaders;
|
|
34
|
+
constructor(options?: string | ServerClientOptions);
|
|
35
|
+
/**
|
|
36
|
+
* Submit a new breakpoint to the server.
|
|
37
|
+
*/
|
|
38
|
+
submitBreakpoint(breakpoint: {
|
|
39
|
+
text: string;
|
|
40
|
+
context: Breakpoint["context"];
|
|
41
|
+
routing: Breakpoint["routing"];
|
|
42
|
+
projectId: string;
|
|
43
|
+
repoId: string;
|
|
44
|
+
}): Promise<Breakpoint>;
|
|
45
|
+
/**
|
|
46
|
+
* Retrieve a breakpoint by its ID.
|
|
47
|
+
*/
|
|
48
|
+
getBreakpoint(breakpointId: string): Promise<Breakpoint>;
|
|
49
|
+
createBrowserSession(breakpointId: string, options?: {
|
|
50
|
+
mode?: "same-user" | "responder";
|
|
51
|
+
responderId?: string;
|
|
52
|
+
responderName?: string;
|
|
53
|
+
}): Promise<BreakpointBrowserSession>;
|
|
54
|
+
getBreakpointSession(authToken: string): Promise<BreakpointSessionView>;
|
|
55
|
+
submitSessionAnswer(authToken: string, answer: {
|
|
56
|
+
text: string;
|
|
57
|
+
confidence?: number;
|
|
58
|
+
references?: string[];
|
|
59
|
+
followUpQuestions?: string[];
|
|
60
|
+
decisionMemory?: {
|
|
61
|
+
applicabilityContext: string;
|
|
62
|
+
reasoning: string;
|
|
63
|
+
};
|
|
64
|
+
}): Promise<BreakpointAnswer>;
|
|
65
|
+
/**
|
|
66
|
+
* Open an SSE stream for real-time updates on a breakpoint.
|
|
67
|
+
*/
|
|
68
|
+
getBreakpointStream(breakpointId: string, signal?: AbortSignal): SSEStream;
|
|
69
|
+
/**
|
|
70
|
+
* List responder profiles, optionally scoped to a project or repo.
|
|
71
|
+
*/
|
|
72
|
+
listResponders(filters?: {
|
|
73
|
+
projectId?: string;
|
|
74
|
+
repoId?: string;
|
|
75
|
+
}): Promise<ResponderProfile[]>;
|
|
76
|
+
/**
|
|
77
|
+
* List pending breakpoints for a specific responder.
|
|
78
|
+
*/
|
|
79
|
+
listPendingBreakpoints(responderId: string, filters?: {
|
|
80
|
+
projectId?: string;
|
|
81
|
+
repoId?: string;
|
|
82
|
+
status?: string;
|
|
83
|
+
}): Promise<Breakpoint[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Claim a breakpoint as a responder.
|
|
86
|
+
*/
|
|
87
|
+
claimBreakpoint(breakpointId: string, responderId: string): Promise<Breakpoint>;
|
|
88
|
+
/**
|
|
89
|
+
* Submit an answer for a breakpoint.
|
|
90
|
+
*/
|
|
91
|
+
submitAnswer(breakpointId: string, answer: {
|
|
92
|
+
responderId: string;
|
|
93
|
+
responderName: string;
|
|
94
|
+
text: string;
|
|
95
|
+
confidence?: number;
|
|
96
|
+
references?: string[];
|
|
97
|
+
followUpQuestions?: string[];
|
|
98
|
+
decisionMemory?: {
|
|
99
|
+
applicabilityContext: string;
|
|
100
|
+
reasoning: string;
|
|
101
|
+
};
|
|
102
|
+
}): Promise<BreakpointAnswer>;
|
|
103
|
+
/**
|
|
104
|
+
* Cancel (delete) a breakpoint.
|
|
105
|
+
*/
|
|
106
|
+
cancelBreakpoint(breakpointId: string): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Check server health.
|
|
109
|
+
*/
|
|
110
|
+
healthCheck(): Promise<{
|
|
111
|
+
status: string;
|
|
112
|
+
}>;
|
|
113
|
+
/** @internal Exposed for composition by AuthClient. */
|
|
114
|
+
get<T>(path: string, extraHeaders?: Record<string, string>): Promise<T>;
|
|
115
|
+
/** @internal Exposed for composition by AuthClient. */
|
|
116
|
+
post<T>(path: string, body: unknown, extraHeaders?: Record<string, string>): Promise<T>;
|
|
117
|
+
/** @internal Exposed for composition by AuthClient. */
|
|
118
|
+
put<T>(path: string, body: unknown, extraHeaders?: Record<string, string>): Promise<T>;
|
|
119
|
+
/** @internal Exposed for composition by AuthClient. */
|
|
120
|
+
delete<T>(path: string, extraHeaders?: Record<string, string>): Promise<T>;
|
|
121
|
+
private request;
|
|
122
|
+
protected resolveUrl(path: string): string;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=server-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-client.d.ts","sourceRoot":"","sources":["../../src/client/server-client.ts"],"names":[],"mappings":"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"}
|