@cursor/july 0.1.6 → 0.1.8
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/bin/agent-serve.js +73 -19
- package/dist/channels/slack/channel-watch.d.ts +6 -1
- package/dist/channels/slack/channel-watch.d.ts.map +1 -1
- package/dist/channels/slack/channel-watch.js +22 -1
- package/dist/channels/slack/cursor-account.d.ts +4 -0
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +12 -2
- package/dist/channels/slack/defaults.d.ts +10 -5
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +39 -17
- package/dist/channels/slack/dispatch.d.ts +18 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +141 -38
- package/dist/channels/slack/inbound.d.ts +13 -3
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +17 -9
- package/dist/channels/slack/index.d.ts +4 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +4 -0
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +1 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +3 -0
- package/dist/channels/slack/nudge-carrier.d.ts +19 -0
- package/dist/channels/slack/nudge-carrier.d.ts.map +1 -0
- package/dist/channels/slack/nudge-carrier.js +166 -0
- package/dist/channels/slack/nudge-store.d.ts +61 -0
- package/dist/channels/slack/nudge-store.d.ts.map +1 -0
- package/dist/channels/slack/nudge-store.js +266 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +74 -25
- package/dist/channels/slack/stop.d.ts +14 -0
- package/dist/channels/slack/stop.d.ts.map +1 -0
- package/dist/channels/slack/stop.js +22 -0
- package/dist/channels/slack/thread-context.d.ts +81 -0
- package/dist/channels/slack/thread-context.d.ts.map +1 -0
- package/dist/channels/slack/thread-context.js +470 -0
- package/dist/channels/slack/types.d.ts +27 -0
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.DMboGKUD.js → app.BP8mAVMW.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DevOabKJ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DkEqEnJU.js → VPLocalSearchBox.1FXIZbz8.js} +1 -1
- package/dist/docs/assets/chunks/{theme.ASugdMNm.js → theme.Dm1R02v9.js} +2 -2
- package/dist/docs/assets/example-agents_index.md.CwtWu5ix.js +2 -0
- package/dist/docs/assets/{example-agents_index.md.CRqJlnIf.lean.js → example-agents_index.md.CwtWu5ix.lean.js} +1 -1
- package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.js +10 -0
- package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.lean.js +1 -0
- package/dist/docs/assets/{guides_slack.md.CCwqHvSV.js → guides_slack.md.FWale6Ip.js} +4 -3
- package/dist/docs/assets/{guides_slack.md.CCwqHvSV.lean.js → guides_slack.md.FWale6Ip.lean.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.DdjWabnN.js → reference_sessions.md.DLd6mvbv.js} +2 -2
- package/dist/docs/assets/{reference_sessions.md.DdjWabnN.lean.js → reference_sessions.md.DLd6mvbv.lean.js} +1 -1
- package/dist/docs/assets/{storage.md.CVnInNiN.js → storage.md.Cu3MwM2a.js} +3 -2
- package/dist/docs/assets/{storage.md.CVnInNiN.lean.js → storage.md.Cu3MwM2a.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +4 -4
- package/dist/docs/evals.html +4 -4
- package/dist/docs/example-agents/approval-buddy.html +4 -4
- package/dist/docs/example-agents/benny.html +5 -5
- package/dist/docs/example-agents/bugbot.html +5 -5
- package/dist/docs/example-agents/codebase-wiki.html +4 -4
- package/dist/docs/example-agents/codeowners-review.html +4 -4
- package/dist/docs/example-agents/concierge.html +4 -4
- package/dist/docs/example-agents/fsd.html +4 -4
- package/dist/docs/example-agents/index.html +6 -6
- package/dist/docs/example-agents/knowledge-base.html +4 -4
- package/dist/docs/example-agents/oncall.html +34 -0
- package/dist/docs/example-agents/security-reviewer.html +4 -4
- package/dist/docs/example-agents/slack-agent.html +4 -4
- package/dist/docs/example-agents/weather-agent.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/slack.html +7 -6
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +4 -4
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +4 -4
- package/dist/docs/reference/connections.html +4 -4
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +4 -4
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +5 -5
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +4 -4
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +7 -6
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/evals.d.ts +2 -2
- package/dist/internal/cli-ax.d.ts +23 -10
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +358 -55
- package/dist/internal/cli-mcp.d.ts +64 -0
- package/dist/internal/cli-mcp.d.ts.map +1 -0
- package/dist/internal/cli-mcp.js +570 -0
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +2 -0
- package/dist/internal/eval-run-store.d.ts +2 -0
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +4 -4
- package/dist/internal/evals-client.d.ts +96 -0
- package/dist/internal/evals-client.d.ts.map +1 -0
- package/dist/internal/evals-client.js +262 -0
- package/dist/internal/host-kv.d.ts +17 -0
- package/dist/internal/host-kv.d.ts.map +1 -0
- package/dist/internal/host-kv.js +77 -0
- package/dist/internal/init-project.js +3 -3
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +19 -2
- package/dist/internal/session-engine.d.ts +42 -7
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +247 -51
- package/dist/internal/storage-coordinator.d.ts +18 -1
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +43 -0
- package/dist/playground/assets/index-Bpr4Th4M.js +319 -0
- package/dist/playground/index.html +1 -1
- package/dist/storage-backends/file-kv.d.ts +42 -0
- package/dist/storage-backends/file-kv.d.ts.map +1 -0
- package/dist/storage-backends/file-kv.js +190 -0
- package/dist/storage-backends/postgres-kv.d.ts +77 -0
- package/dist/storage-backends/postgres-kv.d.ts.map +1 -0
- package/dist/storage-backends/postgres-kv.js +180 -0
- package/dist/storage.d.ts +10 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +10 -1
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/example-agents/index.md +14 -9
- package/docs/example-agents/oncall.md +216 -0
- package/docs/guides/slack.md +11 -2
- package/docs/reference/sessions.md +13 -4
- package/docs/storage.md +27 -0
- package/package.json +15 -1
- package/skills/framework-map/SKILL.md +6 -4
- package/src/bin/agent-serve.ts +79 -18
- package/src/channels/slack/channel-watch.ts +28 -1
- package/src/channels/slack/cursor-account.ts +20 -0
- package/src/channels/slack/defaults.ts +51 -20
- package/src/channels/slack/dispatch.ts +215 -40
- package/src/channels/slack/inbound.ts +30 -10
- package/src/channels/slack/index.ts +4 -0
- package/src/channels/slack/live-delivery.ts +1 -0
- package/src/channels/slack/manifest.ts +3 -0
- package/src/channels/slack/nudge-carrier.ts +182 -0
- package/src/channels/slack/nudge-store.ts +308 -0
- package/src/channels/slack/slack-channel.ts +106 -31
- package/src/channels/slack/stop.ts +25 -0
- package/src/channels/slack/thread-context.ts +572 -0
- package/src/channels/slack/types.ts +27 -0
- package/src/evals.ts +2 -2
- package/src/internal/cli-ax.ts +466 -75
- package/src/internal/cli-mcp.ts +708 -0
- package/src/internal/distribution.ts +2 -0
- package/src/internal/eval-run-store.ts +5 -0
- package/src/internal/evals-client.ts +431 -0
- package/src/internal/host-kv.ts +85 -0
- package/src/internal/init-project.ts +3 -3
- package/src/internal/server.ts +43 -0
- package/src/internal/session-engine.ts +351 -50
- package/src/internal/storage-coordinator.ts +41 -0
- package/src/storage-backends/file-kv.ts +221 -0
- package/src/storage-backends/postgres-kv.ts +248 -0
- package/src/storage.ts +11 -1
- package/src/types.ts +83 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.O6eP7QZr.js +0 -1
- package/dist/docs/assets/example-agents_index.md.CRqJlnIf.js +0 -2
- package/dist/playground/assets/index-mux9aj5P.js +0 -319
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for playground eval batches (`/v1/dev/evals/runs`).
|
|
3
|
+
*
|
|
4
|
+
* Used by `agentkit eval --prod` (or `--url`) so the batch runs on the serve
|
|
5
|
+
* process and is mirrored to `defineStorage` when an `evals` table is
|
|
6
|
+
* configured. Without those flags, eval keeps the in-process ephemeral path
|
|
7
|
+
* in `cli-ax.ts`.
|
|
8
|
+
*/
|
|
9
|
+
import type { EvalRunSnapshot } from "../evals.js";
|
|
10
|
+
import type { EvalRunResult } from "./eval-runner.js";
|
|
11
|
+
import { type RequestAuth } from "./request-headers.js";
|
|
12
|
+
export type RemoteEvalErrorCode = "no_matching_evals" | "eval_run_in_progress" | "unknown_eval_run" | "start_failed" | "poll_failed" | "aborted";
|
|
13
|
+
export declare class RemoteEvalError extends Error {
|
|
14
|
+
readonly status?: number | undefined;
|
|
15
|
+
readonly code?: RemoteEvalErrorCode | undefined;
|
|
16
|
+
readonly activeRunId?: string | undefined;
|
|
17
|
+
constructor(message: string, status?: number | undefined, code?: RemoteEvalErrorCode | undefined, activeRunId?: string | undefined);
|
|
18
|
+
}
|
|
19
|
+
export interface RemoteEvalListItem {
|
|
20
|
+
id: string;
|
|
21
|
+
fileId: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
tags?: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface RunRemoteEvalsOptions extends RequestAuth {
|
|
26
|
+
baseUrl: string;
|
|
27
|
+
filterIds?: string[];
|
|
28
|
+
tags?: string[];
|
|
29
|
+
/** Per-case timeout override forwarded to the serve process. */
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
/** Ask the serve harness to emit verbose case logs (server-side). */
|
|
32
|
+
verbose?: boolean;
|
|
33
|
+
fetchImpl?: typeof fetch;
|
|
34
|
+
/** Poll interval while the batch is `running`. */
|
|
35
|
+
pollMs?: number;
|
|
36
|
+
/** Abort the wait (not the remote batch). */
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
/** Called each time the polled snapshot changes. */
|
|
39
|
+
onSnapshot?: (snap: EvalRunSnapshot) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Start a batch on the target serve via `POST /v1/dev/evals/runs`, poll until
|
|
43
|
+
* terminal, and return CLI-shaped case results.
|
|
44
|
+
*/
|
|
45
|
+
export declare function runRemoteEvals(options: RunRemoteEvalsOptions): Promise<{
|
|
46
|
+
snapshot: EvalRunSnapshot;
|
|
47
|
+
results: EvalRunResult[];
|
|
48
|
+
}>;
|
|
49
|
+
/** List datapoints from `GET /v1/dev/evals` (same surface a remote run uses). */
|
|
50
|
+
export declare function listRemoteEvals(args: {
|
|
51
|
+
baseUrl: string;
|
|
52
|
+
auth?: RequestAuth;
|
|
53
|
+
fetchImpl?: typeof fetch;
|
|
54
|
+
filterIds?: string[];
|
|
55
|
+
tags?: string[];
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
}): Promise<RemoteEvalListItem[]>;
|
|
58
|
+
export declare function startRemoteEvalRun(args: {
|
|
59
|
+
baseUrl: string;
|
|
60
|
+
auth?: RequestAuth;
|
|
61
|
+
fetchImpl?: typeof fetch;
|
|
62
|
+
filterIds?: string[];
|
|
63
|
+
tags?: string[];
|
|
64
|
+
timeoutMs?: number;
|
|
65
|
+
verbose?: boolean;
|
|
66
|
+
signal?: AbortSignal;
|
|
67
|
+
}): Promise<EvalRunSnapshot>;
|
|
68
|
+
/** One-shot `GET /v1/dev/evals/runs/:runId` (no polling). */
|
|
69
|
+
export declare function getRemoteEvalRun(args: {
|
|
70
|
+
baseUrl: string;
|
|
71
|
+
runId: string;
|
|
72
|
+
auth?: RequestAuth;
|
|
73
|
+
fetchImpl?: typeof fetch;
|
|
74
|
+
signal?: AbortSignal;
|
|
75
|
+
}): Promise<EvalRunSnapshot>;
|
|
76
|
+
/** Recent batches from `GET /v1/dev/evals/runs`. */
|
|
77
|
+
export declare function listRemoteEvalRuns(args: {
|
|
78
|
+
baseUrl: string;
|
|
79
|
+
auth?: RequestAuth;
|
|
80
|
+
fetchImpl?: typeof fetch;
|
|
81
|
+
signal?: AbortSignal;
|
|
82
|
+
}): Promise<{
|
|
83
|
+
runs: EvalRunSnapshot[];
|
|
84
|
+
activeRunId?: string;
|
|
85
|
+
}>;
|
|
86
|
+
export declare function pollRemoteEvalRun(args: {
|
|
87
|
+
baseUrl: string;
|
|
88
|
+
runId: string;
|
|
89
|
+
auth?: RequestAuth;
|
|
90
|
+
fetchImpl?: typeof fetch;
|
|
91
|
+
pollMs?: number;
|
|
92
|
+
signal?: AbortSignal;
|
|
93
|
+
onSnapshot?: (snap: EvalRunSnapshot) => void;
|
|
94
|
+
}): Promise<EvalRunSnapshot>;
|
|
95
|
+
export declare function snapshotToEvalRunResults(snapshot: EvalRunSnapshot): EvalRunResult[];
|
|
96
|
+
//# sourceMappingURL=evals-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evals-client.d.ts","sourceRoot":"","sources":["../../src/internal/evals-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for playground eval batches (`/v1/dev/evals/runs`).
|
|
3
|
+
*
|
|
4
|
+
* Used by `agentkit eval --prod` (or `--url`) so the batch runs on the serve
|
|
5
|
+
* process and is mirrored to `defineStorage` when an `evals` table is
|
|
6
|
+
* configured. Without those flags, eval keeps the in-process ephemeral path
|
|
7
|
+
* in `cli-ax.ts`.
|
|
8
|
+
*/
|
|
9
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
10
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
11
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
12
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
13
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
14
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
15
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
import { matchesEvalIdFilter } from "../evals.js";
|
|
19
|
+
import { mergeRequestHeaders } from "./request-headers.js";
|
|
20
|
+
const DEFAULT_POLL_MS = 1000;
|
|
21
|
+
export class RemoteEvalError extends Error {
|
|
22
|
+
constructor(message, status, code, activeRunId) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.status = status;
|
|
25
|
+
this.code = code;
|
|
26
|
+
this.activeRunId = activeRunId;
|
|
27
|
+
this.name = "RemoteEvalError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Start a batch on the target serve via `POST /v1/dev/evals/runs`, poll until
|
|
32
|
+
* terminal, and return CLI-shaped case results.
|
|
33
|
+
*/
|
|
34
|
+
export function runRemoteEvals(options) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
var _a;
|
|
37
|
+
var _b, _c;
|
|
38
|
+
const baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
39
|
+
const fetchImpl = (_b = options.fetchImpl) !== null && _b !== void 0 ? _b : fetch;
|
|
40
|
+
const auth = {
|
|
41
|
+
bearerToken: options.bearerToken,
|
|
42
|
+
headers: options.headers,
|
|
43
|
+
};
|
|
44
|
+
const started = yield startRemoteEvalRun({
|
|
45
|
+
baseUrl,
|
|
46
|
+
auth,
|
|
47
|
+
fetchImpl,
|
|
48
|
+
filterIds: options.filterIds,
|
|
49
|
+
tags: options.tags,
|
|
50
|
+
timeoutMs: options.timeoutMs,
|
|
51
|
+
verbose: options.verbose,
|
|
52
|
+
signal: options.signal,
|
|
53
|
+
});
|
|
54
|
+
(_a = options.onSnapshot) === null || _a === void 0 ? void 0 : _a.call(options, started);
|
|
55
|
+
const snapshot = yield pollRemoteEvalRun({
|
|
56
|
+
baseUrl,
|
|
57
|
+
runId: started.runId,
|
|
58
|
+
auth,
|
|
59
|
+
fetchImpl,
|
|
60
|
+
pollMs: (_c = options.pollMs) !== null && _c !== void 0 ? _c : DEFAULT_POLL_MS,
|
|
61
|
+
signal: options.signal,
|
|
62
|
+
onSnapshot: options.onSnapshot,
|
|
63
|
+
});
|
|
64
|
+
return { snapshot, results: snapshotToEvalRunResults(snapshot) };
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/** List datapoints from `GET /v1/dev/evals` (same surface a remote run uses). */
|
|
68
|
+
export function listRemoteEvals(args) {
|
|
69
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
var _a, _b;
|
|
71
|
+
const baseUrl = args.baseUrl.replace(/\/$/, "");
|
|
72
|
+
const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
|
|
73
|
+
let resp;
|
|
74
|
+
try {
|
|
75
|
+
resp = yield fetchImpl(`${baseUrl}/v1/dev/evals`, {
|
|
76
|
+
headers: mergeRequestHeaders(args.auth),
|
|
77
|
+
signal: args.signal,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
throw new RemoteEvalError(error instanceof Error ? error.message : "Could not list evals.", undefined, "start_failed");
|
|
82
|
+
}
|
|
83
|
+
if (!resp.ok) {
|
|
84
|
+
throw new RemoteEvalError(`Could not list evals (HTTP ${resp.status}).`, resp.status, "start_failed");
|
|
85
|
+
}
|
|
86
|
+
const body = (yield resp.json());
|
|
87
|
+
const listed = [];
|
|
88
|
+
for (const row of (_b = body.evals) !== null && _b !== void 0 ? _b : []) {
|
|
89
|
+
if (typeof row.id !== "string" || row.id === "") {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (typeof row.fileId !== "string" || row.fileId === "") {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const tags = Array.isArray(row.tags)
|
|
96
|
+
? row.tags.filter((t) => typeof t === "string")
|
|
97
|
+
: undefined;
|
|
98
|
+
listed.push(Object.assign(Object.assign({ id: row.id, fileId: row.fileId }, (typeof row.description === "string"
|
|
99
|
+
? { description: row.description }
|
|
100
|
+
: {})), (tags === undefined || tags.length === 0 ? {} : { tags })));
|
|
101
|
+
}
|
|
102
|
+
let selected = listed;
|
|
103
|
+
if (args.filterIds !== undefined && args.filterIds.length > 0) {
|
|
104
|
+
selected = selected.filter((e) => args.filterIds.some((f) => matchesEvalIdFilter(e.id, f)));
|
|
105
|
+
}
|
|
106
|
+
if (args.tags !== undefined && args.tags.length > 0) {
|
|
107
|
+
selected = selected.filter((e) => { var _a; return ((_a = e.tags) !== null && _a !== void 0 ? _a : []).some((t) => args.tags.includes(t)); });
|
|
108
|
+
}
|
|
109
|
+
return selected;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
export function startRemoteEvalRun(args) {
|
|
113
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
var _a;
|
|
115
|
+
const baseUrl = args.baseUrl.replace(/\/$/, "");
|
|
116
|
+
const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
|
|
117
|
+
const body = {};
|
|
118
|
+
if (args.filterIds !== undefined && args.filterIds.length > 0) {
|
|
119
|
+
body.filterIds = args.filterIds;
|
|
120
|
+
}
|
|
121
|
+
if (args.tags !== undefined && args.tags.length > 0) {
|
|
122
|
+
body.tags = args.tags;
|
|
123
|
+
}
|
|
124
|
+
if (args.timeoutMs !== undefined) {
|
|
125
|
+
body.timeoutMs = args.timeoutMs;
|
|
126
|
+
}
|
|
127
|
+
if (args.verbose === true) {
|
|
128
|
+
body.verbose = true;
|
|
129
|
+
}
|
|
130
|
+
let resp;
|
|
131
|
+
try {
|
|
132
|
+
resp = yield fetchImpl(`${baseUrl}/v1/dev/evals/runs`, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
headers: Object.assign({ "content-type": "application/json" }, mergeRequestHeaders(args.auth)),
|
|
135
|
+
body: JSON.stringify(body),
|
|
136
|
+
signal: args.signal,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
throw new RemoteEvalError(error instanceof Error ? error.message : "Could not start eval run.", undefined, "start_failed");
|
|
141
|
+
}
|
|
142
|
+
const json = (yield resp.json().catch(() => ({})));
|
|
143
|
+
if (json.error === "no_matching_evals") {
|
|
144
|
+
throw new RemoteEvalError("No matching evals found.", 404, "no_matching_evals");
|
|
145
|
+
}
|
|
146
|
+
if (resp.status === 409 || json.error === "eval_run_in_progress") {
|
|
147
|
+
throw new RemoteEvalError(json.activeRunId !== undefined && json.activeRunId !== ""
|
|
148
|
+
? `An eval run is already in progress (${json.activeRunId}).`
|
|
149
|
+
: "An eval run is already in progress.", 409, "eval_run_in_progress", typeof json.activeRunId === "string" ? json.activeRunId : undefined);
|
|
150
|
+
}
|
|
151
|
+
if (!resp.ok) {
|
|
152
|
+
const detail = typeof json.message === "string" && json.message !== ""
|
|
153
|
+
? json.message
|
|
154
|
+
: typeof json.error === "string" && json.error !== ""
|
|
155
|
+
? json.error
|
|
156
|
+
: `HTTP ${resp.status}`;
|
|
157
|
+
throw new RemoteEvalError(`Could not start eval run: ${detail}`, resp.status, "start_failed");
|
|
158
|
+
}
|
|
159
|
+
if (typeof json.runId !== "string" || json.runId === "") {
|
|
160
|
+
throw new RemoteEvalError("Eval start response missing runId.", undefined, "start_failed");
|
|
161
|
+
}
|
|
162
|
+
return json;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/** One-shot `GET /v1/dev/evals/runs/:runId` (no polling). */
|
|
166
|
+
export function getRemoteEvalRun(args) {
|
|
167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
var _a;
|
|
169
|
+
const baseUrl = args.baseUrl.replace(/\/$/, "");
|
|
170
|
+
const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
|
|
171
|
+
let resp;
|
|
172
|
+
try {
|
|
173
|
+
resp = yield fetchImpl(`${baseUrl}/v1/dev/evals/runs/${encodeURIComponent(args.runId)}`, {
|
|
174
|
+
headers: mergeRequestHeaders(args.auth),
|
|
175
|
+
signal: args.signal,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
throw new RemoteEvalError(error instanceof Error ? error.message : "Could not fetch eval run.", undefined, "poll_failed");
|
|
180
|
+
}
|
|
181
|
+
if (resp.status === 404) {
|
|
182
|
+
throw new RemoteEvalError(`Unknown eval run ${args.runId}.`, 404, "unknown_eval_run");
|
|
183
|
+
}
|
|
184
|
+
if (!resp.ok) {
|
|
185
|
+
throw new RemoteEvalError(`Could not fetch eval run (HTTP ${resp.status}).`, resp.status, "poll_failed");
|
|
186
|
+
}
|
|
187
|
+
return (yield resp.json());
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/** Recent batches from `GET /v1/dev/evals/runs`. */
|
|
191
|
+
export function listRemoteEvalRuns(args) {
|
|
192
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
193
|
+
var _a;
|
|
194
|
+
const baseUrl = args.baseUrl.replace(/\/$/, "");
|
|
195
|
+
const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
|
|
196
|
+
let resp;
|
|
197
|
+
try {
|
|
198
|
+
resp = yield fetchImpl(`${baseUrl}/v1/dev/evals/runs`, {
|
|
199
|
+
headers: mergeRequestHeaders(args.auth),
|
|
200
|
+
signal: args.signal,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
throw new RemoteEvalError(error instanceof Error ? error.message : "Could not list eval runs.", undefined, "poll_failed");
|
|
205
|
+
}
|
|
206
|
+
if (!resp.ok) {
|
|
207
|
+
throw new RemoteEvalError(`Could not list eval runs (HTTP ${resp.status}).`, resp.status, "poll_failed");
|
|
208
|
+
}
|
|
209
|
+
const body = (yield resp.json());
|
|
210
|
+
const runs = Array.isArray(body.runs)
|
|
211
|
+
? body.runs.filter((r) => r !== null &&
|
|
212
|
+
typeof r === "object" &&
|
|
213
|
+
typeof r.runId === "string")
|
|
214
|
+
: [];
|
|
215
|
+
return Object.assign({ runs }, (typeof body.activeRunId === "string" && body.activeRunId !== ""
|
|
216
|
+
? { activeRunId: body.activeRunId }
|
|
217
|
+
: {}));
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
export function pollRemoteEvalRun(args) {
|
|
221
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
222
|
+
var _a, _b;
|
|
223
|
+
var _c;
|
|
224
|
+
const pollMs = (_c = args.pollMs) !== null && _c !== void 0 ? _c : DEFAULT_POLL_MS;
|
|
225
|
+
let lastJson = "";
|
|
226
|
+
for (;;) {
|
|
227
|
+
if (((_a = args.signal) === null || _a === void 0 ? void 0 : _a.aborted) === true) {
|
|
228
|
+
throw new RemoteEvalError("Eval wait aborted.", undefined, "aborted");
|
|
229
|
+
}
|
|
230
|
+
const snap = yield getRemoteEvalRun(args);
|
|
231
|
+
const serialized = JSON.stringify(snap);
|
|
232
|
+
if (serialized !== lastJson) {
|
|
233
|
+
lastJson = serialized;
|
|
234
|
+
(_b = args.onSnapshot) === null || _b === void 0 ? void 0 : _b.call(args, snap);
|
|
235
|
+
}
|
|
236
|
+
if (snap.status !== "running") {
|
|
237
|
+
return snap;
|
|
238
|
+
}
|
|
239
|
+
yield sleep(pollMs, args.signal);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
export function snapshotToEvalRunResults(snapshot) {
|
|
244
|
+
return snapshot.cases.map((c) => { var _a, _b, _c, _d; return (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ id: c.id, path: c.fileId }, (c.description === undefined ? {} : { description: c.description })), { ok: c.ok === true, assertions: (_a = c.assertions) !== null && _a !== void 0 ? _a : [] }), (c.sessionId === undefined ? {} : { sessionId: c.sessionId })), { inputs: (_b = c.inputs) !== null && _b !== void 0 ? _b : [] }), (c.finalText === undefined ? {} : { finalText: c.finalText })), (c.tools === undefined ? {} : { tools: c.tools })), (c.toolCalls === undefined ? {} : { toolCalls: c.toolCalls })), (c.error === undefined ? {} : { error: c.error })), { logs: (_c = c.logs) !== null && _c !== void 0 ? _c : [], durationMs: (_d = c.durationMs) !== null && _d !== void 0 ? _d : 0 })); });
|
|
245
|
+
}
|
|
246
|
+
function sleep(ms, signal) {
|
|
247
|
+
return new Promise((resolve, reject) => {
|
|
248
|
+
if ((signal === null || signal === void 0 ? void 0 : signal.aborted) === true) {
|
|
249
|
+
reject(new RemoteEvalError("Eval wait aborted.", undefined, "aborted"));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const timer = setTimeout(() => {
|
|
253
|
+
signal === null || signal === void 0 ? void 0 : signal.removeEventListener("abort", onAbort);
|
|
254
|
+
resolve();
|
|
255
|
+
}, ms);
|
|
256
|
+
const onAbort = () => {
|
|
257
|
+
clearTimeout(timer);
|
|
258
|
+
reject(new RemoteEvalError("Eval wait aborted.", undefined, "aborted"));
|
|
259
|
+
};
|
|
260
|
+
signal === null || signal === void 0 ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
|
|
261
|
+
});
|
|
262
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author-facing durable JSON KV for {@link HostContext.kv}.
|
|
3
|
+
*
|
|
4
|
+
* When `defineStorage` is authored and exposes `get`, values live in that
|
|
5
|
+
* sink under {@link storageKeys.kv}. Otherwise they land as one JSON file
|
|
6
|
+
* per key under `--state-root/kv` (local dogfood / no durable plug-in).
|
|
7
|
+
*/
|
|
8
|
+
import type { HostKvApi } from "../types.js";
|
|
9
|
+
import type { StorageCoordinator } from "./storage-coordinator.js";
|
|
10
|
+
export interface CreateHostKvApiOptions {
|
|
11
|
+
agentName: string;
|
|
12
|
+
stateRoot: string;
|
|
13
|
+
storage?: StorageCoordinator;
|
|
14
|
+
}
|
|
15
|
+
/** Build the host KV API for one agent process. */
|
|
16
|
+
export declare function createHostKvApi(options: CreateHostKvApiOptions): HostKvApi;
|
|
17
|
+
//# sourceMappingURL=host-kv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-kv.d.ts","sourceRoot":"","sources":["../../src/internal/host-kv.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CAa1E"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author-facing durable JSON KV for {@link HostContext.kv}.
|
|
3
|
+
*
|
|
4
|
+
* When `defineStorage` is authored and exposes `get`, values live in that
|
|
5
|
+
* sink under {@link storageKeys.kv}. Otherwise they land as one JSON file
|
|
6
|
+
* per key under `--state-root/kv` (local dogfood / no durable plug-in).
|
|
7
|
+
*/
|
|
8
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
import { randomUUID } from "node:crypto";
|
|
18
|
+
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { storageKeys } from "../storage.js";
|
|
21
|
+
/** Build the host KV API for one agent process. */
|
|
22
|
+
export function createHostKvApi(options) {
|
|
23
|
+
const storage = options.storage;
|
|
24
|
+
if ((storage === null || storage === void 0 ? void 0 : storage.supportsAuthorKv) === true) {
|
|
25
|
+
return {
|
|
26
|
+
get: (key) => storage.kvGet(normalizeAuthorKey(key)),
|
|
27
|
+
put: (key, value) => storage.kvPut(normalizeAuthorKey(key), value),
|
|
28
|
+
delete: (key) => storage.kvDelete(normalizeAuthorKey(key)),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return createFilesystemKvApi({
|
|
32
|
+
agentName: options.agentName,
|
|
33
|
+
stateRoot: options.stateRoot,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function createFilesystemKvApi(options) {
|
|
37
|
+
const dir = join(options.stateRoot, "kv");
|
|
38
|
+
const filePath = (authorKey) => join(dir, `${encodeURIComponent(storageKeys.kv(options.agentName, authorKey))}.json`);
|
|
39
|
+
return {
|
|
40
|
+
get(key) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
const authorKey = normalizeAuthorKey(key);
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(yield readFile(filePath(authorKey), "utf8"));
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (error.code === "ENOENT") {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
put(key, value) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const authorKey = normalizeAuthorKey(key);
|
|
57
|
+
yield mkdir(dir, { recursive: true });
|
|
58
|
+
const target = filePath(authorKey);
|
|
59
|
+
const tmp = join(dir, `.tmp-${randomUUID()}`);
|
|
60
|
+
yield writeFile(tmp, JSON.stringify(value), "utf8");
|
|
61
|
+
yield rename(tmp, target);
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
delete(key) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const authorKey = normalizeAuthorKey(key);
|
|
67
|
+
yield rm(filePath(authorKey), { force: true });
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function normalizeAuthorKey(key) {
|
|
73
|
+
if (typeof key !== "string" || key.trim() === "") {
|
|
74
|
+
throw new Error("host.kv key must be a non-empty string");
|
|
75
|
+
}
|
|
76
|
+
return key;
|
|
77
|
+
}
|
|
@@ -301,15 +301,15 @@ Recommended loop once the project exists:
|
|
|
301
301
|
1. Edit agent/ + tools under agent/tools/
|
|
302
302
|
2. ${CLI_COMMAND_NAME} info --dir . --json
|
|
303
303
|
3. ${CLI_COMMAND_NAME} run --dir . --message "..."
|
|
304
|
-
4. ${CLI_COMMAND_NAME} eval --
|
|
304
|
+
4. ${CLI_COMMAND_NAME} eval --dir .
|
|
305
305
|
|
|
306
306
|
Evals:
|
|
307
307
|
Create evals/**/*.eval.ts using defineEval from ${PACKAGE_NAME}/evals
|
|
308
308
|
Case id is the path: evals/weather/nyc.eval.ts → weather/nyc
|
|
309
309
|
Required: evals/evals.config.ts with defineEvalConfig({ maxConcurrency })
|
|
310
310
|
(hard-capped at 200 due to model provider request limits)
|
|
311
|
-
Run: ${CLI_COMMAND_NAME} eval
|
|
312
|
-
(
|
|
311
|
+
Run: ${CLI_COMMAND_NAME} eval [--json] [evalId...]
|
|
312
|
+
(pass --prod to run against the hosted deployment)
|
|
313
313
|
|
|
314
314
|
See AGENTS.md in the ${PACKAGE_NAME} package for the full loop.
|
|
315
315
|
`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAoFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAoFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAsmB3B"}
|
package/dist/internal/server.js
CHANGED
|
@@ -272,6 +272,10 @@ export function startServer(mounts_1) {
|
|
|
272
272
|
engine.trackBackground(promise);
|
|
273
273
|
},
|
|
274
274
|
resolveApproval: (sessionId, callId, decision, auth) => engine.resolveApproval(sessionId, callId, decision, auth),
|
|
275
|
+
hasContinuationSession: (continuationToken) => engine.hasContinuationSession(channel.id, continuationToken),
|
|
276
|
+
isContinuationBusy: (continuationToken) => engine.isContinuationBusy(channel.id, continuationToken),
|
|
277
|
+
getContinuationLastBotMessageTs: (continuationToken) => engine.getContinuationLastBotMessageTs(channel.id, continuationToken),
|
|
278
|
+
interruptContinuation: (continuationToken) => engine.interruptContinuation(channel.id, continuationToken),
|
|
275
279
|
logger,
|
|
276
280
|
};
|
|
277
281
|
try {
|
|
@@ -846,14 +850,16 @@ function mountAgentRoutes(router, runtime, args) {
|
|
|
846
850
|
const body = yield readJsonObject(request);
|
|
847
851
|
const filterIds = asStringArray(body === null || body === void 0 ? void 0 : body.filterIds);
|
|
848
852
|
const tags = asStringArray(body === null || body === void 0 ? void 0 : body.tags);
|
|
853
|
+
const timeoutMs = asPositiveInt(body === null || body === void 0 ? void 0 : body.timeoutMs);
|
|
854
|
+
const verbose = (body === null || body === void 0 ? void 0 : body.verbose) === true;
|
|
849
855
|
const authHeader = request.headers.get("authorization");
|
|
850
856
|
const bearerToken = (authHeader === null || authHeader === void 0 ? void 0 : authHeader.toLowerCase().startsWith("bearer "))
|
|
851
857
|
? authHeader.slice("bearer ".length).trim()
|
|
852
858
|
: undefined;
|
|
853
859
|
try {
|
|
854
|
-
const snap = yield runtime.evalRuns.start(Object.assign(Object.assign(Object.assign({}, (filterIds === undefined ? {} : { filterIds })), (tags === undefined ? {} : { tags })), (bearerToken === undefined || bearerToken === ""
|
|
860
|
+
const snap = yield runtime.evalRuns.start(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (filterIds === undefined ? {} : { filterIds })), (tags === undefined ? {} : { tags })), (bearerToken === undefined || bearerToken === ""
|
|
855
861
|
? {}
|
|
856
|
-
: { bearerToken })));
|
|
862
|
+
: { bearerToken })), (timeoutMs === undefined ? {} : { timeoutMs })), (verbose ? { verbose: true } : {})));
|
|
857
863
|
return jsonResponse(snap, { status: 202 });
|
|
858
864
|
}
|
|
859
865
|
catch (error) {
|
|
@@ -1252,6 +1258,10 @@ function startCursorSlackRelay(input) {
|
|
|
1252
1258
|
envelope,
|
|
1253
1259
|
send: args.send,
|
|
1254
1260
|
host: args.host,
|
|
1261
|
+
hasContinuationSession: (continuationToken) => target.runtime.engine.hasContinuationSession(target.channelId, continuationToken),
|
|
1262
|
+
isContinuationBusy: (continuationToken) => target.runtime.engine.isContinuationBusy(target.channelId, continuationToken),
|
|
1263
|
+
getContinuationLastBotMessageTs: (continuationToken) => target.runtime.engine.getContinuationLastBotMessageTs(target.channelId, continuationToken),
|
|
1264
|
+
interruptContinuation: (continuationToken) => target.runtime.engine.interruptContinuation(target.channelId, continuationToken),
|
|
1255
1265
|
});
|
|
1256
1266
|
}),
|
|
1257
1267
|
});
|
|
@@ -1488,6 +1498,13 @@ function asStringArray(value) {
|
|
|
1488
1498
|
}
|
|
1489
1499
|
return out.length === 0 ? undefined : out;
|
|
1490
1500
|
}
|
|
1501
|
+
function asPositiveInt(value) {
|
|
1502
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1503
|
+
return undefined;
|
|
1504
|
+
}
|
|
1505
|
+
const n = Math.floor(value);
|
|
1506
|
+
return n > 0 ? n : undefined;
|
|
1507
|
+
}
|
|
1491
1508
|
function assertReminderReadable(input) {
|
|
1492
1509
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1493
1510
|
const existing = yield input.engine.sessions.findByContinuation(input.reminder.channelId, input.reminder.continuationToken);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* are mapped onto the channel event vocabulary and dispatched to channel
|
|
7
7
|
* event handlers and hooks.
|
|
8
8
|
*/
|
|
9
|
+
import { SlackAskDedupeStore, SlackNudgeStore } from "../channels/slack/nudge-store.js";
|
|
9
10
|
import { type AgentProject, type ApprovalDecision, type AuthContext, type CallToolOptions, type ChannelDefinition, type ChannelSession, type HostContext, type HttpChannelDefinition, type PendingApproval, type ReceiveInput, type SendMessageOptions, type SessionEvent, type SessionInfo, type SessionRecord, type SessionSummary, type ToolCallOutcome, type TurnOutcome } from "../types.js";
|
|
10
11
|
import { type ABSnapshot } from "./ab-snapshot.js";
|
|
11
12
|
import { type HostPlatforms } from "./host-platforms.js";
|
|
@@ -83,6 +84,10 @@ export declare class SessionEngine {
|
|
|
83
84
|
readonly project: AgentProject;
|
|
84
85
|
readonly stateRoot: string;
|
|
85
86
|
readonly sessions: SessionStore;
|
|
87
|
+
/** Durable Slack mid-turn nudges under `<stateRoot>/slack-nudges`. */
|
|
88
|
+
readonly nudgeStore: SlackNudgeStore;
|
|
89
|
+
/** Durable `channelId:ts` ask claims under `<stateRoot>/slack-asks`. */
|
|
90
|
+
readonly askDedupe: SlackAskDedupeStore;
|
|
86
91
|
/**
|
|
87
92
|
* Runtime for `agent/storage.ts` (`defineStorage`), when
|
|
88
93
|
* authored. All durable state changes funnel through it (session
|
|
@@ -105,6 +110,16 @@ export declare class SessionEngine {
|
|
|
105
110
|
private readonly turnAborts;
|
|
106
111
|
/** Serializes turn admission per session (latest follow-up wins). */
|
|
107
112
|
private readonly admissionChains;
|
|
113
|
+
/**
|
|
114
|
+
* Per-session coalesce queue for `admission: "coalesce"` (Slack). Drained
|
|
115
|
+
* into one follow-up turn when the active turn finishes without interrupt.
|
|
116
|
+
*/
|
|
117
|
+
private readonly coalesceQueues;
|
|
118
|
+
/**
|
|
119
|
+
* Sessions whose turn lifecycle is draining coalesced follow-ups. Counts as
|
|
120
|
+
* busy so inbound coalesce admits enqueue instead of racing `clearCoalesced`.
|
|
121
|
+
*/
|
|
122
|
+
private readonly coalesceDrains;
|
|
108
123
|
private readonly lastOutcomes;
|
|
109
124
|
private readonly updateChains;
|
|
110
125
|
private readonly dispatchChains;
|
|
@@ -114,6 +129,7 @@ export declare class SessionEngine {
|
|
|
114
129
|
private readonly approvals;
|
|
115
130
|
private readonly abCollector;
|
|
116
131
|
private reminderApi;
|
|
132
|
+
private readonly kvApi;
|
|
117
133
|
/** Serve-time resolved connections (see {@link setResolvedConnections}). */
|
|
118
134
|
private resolvedConnections;
|
|
119
135
|
constructor(options: SessionEngineOptions);
|
|
@@ -124,8 +140,9 @@ export declare class SessionEngine {
|
|
|
124
140
|
* (`ctx.host.mcp`, always loopback).
|
|
125
141
|
*/
|
|
126
142
|
setResolvedConnections(connections: EngineResolvedConnection[]): void;
|
|
127
|
-
/** Shared host services (MCP / GitHub / Slack / reminders). */
|
|
143
|
+
/** Shared host services (MCP / GitHub / Slack / reminders / kv / Slack nudges). */
|
|
128
144
|
get host(): HostContext;
|
|
145
|
+
private slackNudgeHostApi;
|
|
129
146
|
/** Attach the serve-host reminder API (called from startServer). */
|
|
130
147
|
setReminders(api: HostContext["reminders"]): void;
|
|
131
148
|
/**
|
|
@@ -134,6 +151,8 @@ export declare class SessionEngine {
|
|
|
134
151
|
* session is created (keyed by the provided token, or a fresh one).
|
|
135
152
|
*/
|
|
136
153
|
send(channelId: string, message: string, options?: EngineSendOptions): Promise<ChannelSession>;
|
|
154
|
+
/** Whether a continuation token already maps to a session on this channel. */
|
|
155
|
+
hasContinuationSession(channelId: string, continuationToken: string): Promise<boolean>;
|
|
137
156
|
/**
|
|
138
157
|
* Sticky A/B enrollment at session creation — before the first turn, so
|
|
139
158
|
* variants are in the durable stream (and on {@link SessionRecord.abs})
|
|
@@ -167,13 +186,21 @@ export declare class SessionEngine {
|
|
|
167
186
|
done: Promise<TurnOutcome>;
|
|
168
187
|
}>;
|
|
169
188
|
/**
|
|
170
|
-
* Admit a turn for `sessionId`.
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
189
|
+
* Admit a turn for `sessionId`.
|
|
190
|
+
*
|
|
191
|
+
* Default (`preempt`): a follow-up cancels the running turn and starts
|
|
192
|
+
* immediately (HTTP / MCP). With `admission: "coalesce"` (Slack), a busy
|
|
193
|
+
* session enqueues the message and returns without interrupting; the queue
|
|
194
|
+
* drains into one follow-up when the active turn finishes.
|
|
195
|
+
*
|
|
196
|
+
* Resolves to `true` when the message was coalesced (enqueued), `false`
|
|
197
|
+
* when a turn was started.
|
|
175
198
|
*/
|
|
176
199
|
private startTurn;
|
|
200
|
+
private enqueueCoalesced;
|
|
201
|
+
private clearCoalesced;
|
|
202
|
+
private formatCoalescedFollowups;
|
|
203
|
+
private drainCoalescedFollowups;
|
|
177
204
|
private admitTurn;
|
|
178
205
|
/**
|
|
179
206
|
* Cancel the turn in flight for `sessionId` (if any) and wait for it to
|
|
@@ -183,9 +210,17 @@ export declare class SessionEngine {
|
|
|
183
210
|
private interruptActiveTurn;
|
|
184
211
|
/**
|
|
185
212
|
* Abort the in-flight turn without starting a follow-up. Returns whether
|
|
186
|
-
* a turn was active (or pending abort) when called.
|
|
213
|
+
* a turn was active (or pending abort) when called. Also clears any
|
|
214
|
+
* coalesced follow-ups queued behind the session.
|
|
187
215
|
*/
|
|
188
216
|
interrupt(sessionId: string): Promise<boolean>;
|
|
217
|
+
isContinuationBusy(channelId: string, continuationToken: string): Promise<boolean>;
|
|
218
|
+
/**
|
|
219
|
+
* Last agent-posted Slack message ts for warm `<slack_thread_delta>`, from
|
|
220
|
+
* the session's channel state when present.
|
|
221
|
+
*/
|
|
222
|
+
getContinuationLastBotMessageTs(channelId: string, continuationToken: string): Promise<string | undefined>;
|
|
223
|
+
interruptContinuation(channelId: string, continuationToken: string): Promise<boolean>;
|
|
189
224
|
/**
|
|
190
225
|
* Local harness cwd for a session: per-send override, else
|
|
191
226
|
* `<agent.local.cwd>/<sessionId>`, else the durable session workspace.
|