@vitest-agent/sdk 1.3.0 → 1.3.2
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/index.js +1 -1
- package/layers/DataReaderLive.js +14 -6
- package/layers/DataStoreLive.js +9 -5
- package/package.json +4 -2
- package/services/idempotency.js +2 -1
package/index.js
CHANGED
|
@@ -115,7 +115,7 @@ import { requiredArtifactForTransition, transitionEnforcesBehaviorMatch, validat
|
|
|
115
115
|
* substituted yet. Exported for version introspection by downstream tooling.
|
|
116
116
|
* @public
|
|
117
117
|
*/
|
|
118
|
-
const CURRENT_SDK_VERSION = "1.3.
|
|
118
|
+
const CURRENT_SDK_VERSION = "1.3.2";
|
|
119
119
|
|
|
120
120
|
//#endregion
|
|
121
121
|
export { ActionSeverity, ActorType, Agent, AgentConsoleMode, AgentContext, AgentId, AgentNotFoundError, AgentPluginOptions, AgentReport, AgentReporterOptions, BehaviorAbandonedEvent, BehaviorAddedEvent, BehaviorCompletedEvent, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorScopedEventTypes, BehaviorStartedEvent, BehaviorStatus, BehaviorsReadyEvent, BlockedEvent, CURRENT_SDK_VERSION, CacheManifest, CacheManifestEntry, ChannelEvent, ChatId, CiConsoleMode, ConfigLive, ConsoleLeakFile, ConsoleLeaks, ConsoleLogLevel, ConsoleMode, ConsoleOutputMode, ConsoleOutputs, ConversationId, ConversationNotFoundError, CoverageBaselines, FileCoverageReport as CoverageFile, CoverageGap, CoverageLevel, CoverageMetric, CoverageRenderState, CoverageReport, CoverageTargets, CoverageTargetsMetrics, CoverageTotals, DATABASE_FILENAME, DataReader, DataReaderLive, DataStore, DataStoreError, DataStoreLive, DetailLevel, DetailResolver, DetailResolverLive, DiscoveryError, DiscoveryRegistry, DiscoveryRegistryLive, Environment, EnvironmentDetector, EnvironmentDetectorLive, EnvironmentDetectorTest, Executor, ExecutorResolver, ExecutorResolverLive, FailureRecord, FileCoverageReport, FileEditPayload, FormatSelector, FormatSelectorLive, GfmFormatter, GitCommandError, GoalAbandonedEvent, GoalAddedEvent, GoalCompletedEvent, GoalDetail, GoalNotFoundError, GoalRow, GoalStartedEvent, GoalStatus, GoalsReadyEvent, HistoryRecord, HistoryTracker, HistoryTrackerLive, HistoryTrackerTest, HookFirePayload, HookStatus, HookType, HostKind, HostMetadataParseError, HumanConsoleMode, HypothesisPayload, IDEMPOTENCY_ROOT_SENTINEL, IdempotencyHit, IllegalStatusTransitionError, JsonFormatter, LoggerLive, MarkdownFormatter, MetricThresholds, ModuleRecord, ModuleReport, NotePayload, OutputFormat, OutputPipelineLive, OutputRenderer, OutputRendererLive, PackageManager, PathResolutionError, PathResolutionLive, PatternThresholds, PerClientSessionMapReader, PerClientSessionMapReaderLive, PerClientSessionMapWriter, PerClientSessionMapWriterLive, PhaseTransitionEvent, ProbeMissError, ProjectDiscovery, ProjectDiscoveryLive, ProjectDiscoveryTest, ProjectIdentity, ProjectIdentityLive, ProjectIdentityNotResolvableError, ProjectIdentityTest, ProjectKey, RegistrationConflictError, RenderState, RenderTotals, ReportError, ReportSummary, ResolvedThresholds, RunContext, RunContext$, RunContextLive, RunContextService, RunContextTest, RunEvent, SessionCompleteEvent, SessionNotFoundError, SessionOutcome, SidecarTimeoutError, SilentFormatter, SuggestedActionRecord, TagCountEntry, TddTaskAlreadyEndedError, TddTaskId, TddTaskNotFoundError, TerminalFormatter, TestClassification, TestHistory, TestRecord, TestReport, TestRun, TestRunReason, TestState, ToolCallPayload, ToolResultPayload, Transport, TrendEntry, TrendRecord, TurnPayload, UserPromptPayload, VitestAgentConfig, VitestAgentConfigFile, _resetMigrationCacheForTesting, ansi, assembleHistoryRecord, assembleManifest, buildAgentReport, buildConsoleLeaks, buildEnvPrefix, canonicalizeGitUrl, ciAnnotationsFormatter, classifyTest, collectConsoleLeakEntries, compressLines, computeFailureSignature, computeTrend, deriveIdempotencyKey, detectPackageManager, detectVitestScripts, determineTier, ensureMigrated, extractSqlReason, findFunctionBoundary, formatConsoleMarkdown, formatFatalError, formatGfm, formatTriageEffect, formatWrapupEffect, getRecentDirection, getRunCommand, getWorstMetric, gitUrlToProjectKey, hashTargets, historyKey, initialRenderState, isTimeoutError, isVitestInvocation, migration as migration0001, normalizeAssertionShape, normalizeWorkspaceKey, osc8, probeHostMetadataFromEnv, migration$1 as registryMigration0001, relativePath, requiredArtifactForTransition, resolveCoverageInput, resolveDataPath, resolveLogFile, resolveLogLevel, resolveProjectIdentityFromCandidates, resolveProjectKeyFromCwd, resolveWorkspaceKey, rewriteBashCommand, safeFilename, migration$2 as sessionMapMigration0001, stripAnsi, transitionEnforcesBehaviorMatch, validateCoverageConfig, validateCoverageTargetsShape, validatePhaseTransition };
|
package/layers/DataReaderLive.js
CHANGED
|
@@ -422,9 +422,10 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
|
|
|
422
422
|
WHERE project = ${project}
|
|
423
423
|
ORDER BY timestamp DESC LIMIT 1`;
|
|
424
424
|
if (runs.length === 0) return Option.none();
|
|
425
|
+
const runId = runs[0].id;
|
|
425
426
|
const fileCoverageRows = yield* sql`SELECT f.path as file_path, fc.statements, fc.branches, fc.functions, fc.lines, fc.uncovered_lines
|
|
426
427
|
FROM file_coverage fc JOIN files f ON f.id = fc.file_id
|
|
427
|
-
WHERE fc.run_id = ${
|
|
428
|
+
WHERE fc.run_id = ${runId}`;
|
|
428
429
|
const trendRows = yield* sql`SELECT statements, branches, functions, lines
|
|
429
430
|
FROM coverage_trends
|
|
430
431
|
WHERE project = ${project}
|
|
@@ -687,11 +688,12 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
|
|
|
687
688
|
WHERE project = ${project}
|
|
688
689
|
ORDER BY timestamp DESC LIMIT 1`;
|
|
689
690
|
if (runs.length === 0) return Option.none();
|
|
691
|
+
const runId = runs[0].id;
|
|
690
692
|
const rows = yield* sql`SELECT tc.id, tc.full_name, tc.state, tc.duration, f.path as relative_module_id, tc.classification
|
|
691
693
|
FROM test_cases tc
|
|
692
694
|
JOIN test_modules tm ON tm.id = tc.module_id
|
|
693
695
|
JOIN files f ON f.id = tm.file_id
|
|
694
|
-
WHERE tm.run_id = ${
|
|
696
|
+
WHERE tm.run_id = ${runId} AND tc.full_name = ${fullName}
|
|
695
697
|
LIMIT 1`;
|
|
696
698
|
if (rows.length === 0) return Option.none();
|
|
697
699
|
const r = rows[0];
|
|
@@ -757,12 +759,13 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
|
|
|
757
759
|
WHERE project = ${project}
|
|
758
760
|
ORDER BY timestamp DESC LIMIT 1`;
|
|
759
761
|
if (runs.length === 0) return [];
|
|
762
|
+
const runId = runs[0].id;
|
|
760
763
|
return (yield* sql`SELECT tm.id, f.path as file_path, tm.state,
|
|
761
764
|
(SELECT COUNT(*) FROM test_cases tc WHERE tc.module_id = tm.id) as test_count,
|
|
762
765
|
tm.duration
|
|
763
766
|
FROM test_modules tm
|
|
764
767
|
JOIN files f ON f.id = tm.file_id
|
|
765
|
-
WHERE tm.run_id = ${
|
|
768
|
+
WHERE tm.run_id = ${runId}
|
|
766
769
|
ORDER BY f.path`).map((r) => ({
|
|
767
770
|
id: r.id,
|
|
768
771
|
file: r.file_path,
|
|
@@ -860,7 +863,8 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
|
|
|
860
863
|
})));
|
|
861
864
|
const findSessionsByChatPrefix = (prefix) => Effect.gen(function* () {
|
|
862
865
|
yield* Effect.logDebug("findSessionsByChatPrefix").pipe(Effect.annotateLogs({ prefix }));
|
|
863
|
-
|
|
866
|
+
const pattern = `${prefix}%`;
|
|
867
|
+
return (yield* sql`SELECT id, chat_id, project, cwd, agent_kind, agent_type, parent_session_id, triage_was_non_empty, started_at, ended_at, end_reason FROM sessions WHERE chat_id LIKE ${pattern} ESCAPE '\\' ORDER BY started_at DESC`).map(sessionRowToDetail);
|
|
864
868
|
}).pipe(Effect.annotateLogs("service", "DataReader"), Effect.mapError((e) => new DataStoreError({
|
|
865
869
|
operation: "read",
|
|
866
870
|
table: "sessions",
|
|
@@ -879,7 +883,10 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
|
|
|
879
883
|
const searchTurns = (options) => Effect.gen(function* () {
|
|
880
884
|
yield* Effect.logDebug("searchTurns").pipe(Effect.annotateLogs({ ...options }));
|
|
881
885
|
const limit = options.limit ?? 100;
|
|
882
|
-
|
|
886
|
+
const sessionFilter = options.sessionId !== void 0 ? sql` AND session_id = ${options.sessionId}` : sql``;
|
|
887
|
+
const typeFilter = options.type !== void 0 ? sql` AND type = ${options.type}` : sql``;
|
|
888
|
+
const sinceFilter = options.since !== void 0 ? sql` AND occurred_at >= ${options.since}` : sql``;
|
|
889
|
+
return (yield* sql`SELECT id, session_id, turn_no, type, payload, occurred_at FROM turns WHERE 1=1${sessionFilter}${typeFilter}${sinceFilter} ORDER BY occurred_at DESC, turn_no DESC LIMIT ${limit}`).map((r) => ({
|
|
883
890
|
id: r.id,
|
|
884
891
|
sessionId: r.session_id,
|
|
885
892
|
turnNo: r.turn_no,
|
|
@@ -1564,6 +1571,7 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
|
|
|
1564
1571
|
WHERE project = ${options.project}
|
|
1565
1572
|
ORDER BY timestamp DESC LIMIT 1`;
|
|
1566
1573
|
if (runs.length === 0) return [];
|
|
1574
|
+
const runId = runs[0].id;
|
|
1567
1575
|
return (yield* sql`
|
|
1568
1576
|
SELECT tc.id, tc.full_name, tc.state, tc.duration, f.path AS file_path, tc.classification
|
|
1569
1577
|
FROM test_cases tc
|
|
@@ -1571,7 +1579,7 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
|
|
|
1571
1579
|
JOIN files f ON f.id = tm.file_id
|
|
1572
1580
|
JOIN test_case_tags tct ON tct.test_case_id = tc.id
|
|
1573
1581
|
JOIN tags t ON t.id = tct.tag_id
|
|
1574
|
-
WHERE tm.run_id = ${
|
|
1582
|
+
WHERE tm.run_id = ${runId} AND t.name = ${tag}
|
|
1575
1583
|
ORDER BY tc.full_name
|
|
1576
1584
|
`).map(mapTestListRow);
|
|
1577
1585
|
}
|
package/layers/DataStoreLive.js
CHANGED
|
@@ -227,7 +227,8 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
|
|
|
227
227
|
testModuleId,
|
|
228
228
|
mappingType
|
|
229
229
|
}));
|
|
230
|
-
|
|
230
|
+
const sourceFileId = yield* ensureFile(sourceFilePath);
|
|
231
|
+
yield* sql`INSERT OR IGNORE INTO source_test_map (source_file_id, test_module_id, mapping_type) VALUES (${sourceFileId}, ${testModuleId}, ${mappingType})`;
|
|
231
232
|
}).pipe(Effect.annotateLogs("service", "DataStore"), Effect.mapError((e) => new DataStoreError({
|
|
232
233
|
operation: "write",
|
|
233
234
|
table: "source_test_map",
|
|
@@ -343,11 +344,12 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
|
|
|
343
344
|
if (input.type === "file_edit") {
|
|
344
345
|
const filePath = payload.file_path;
|
|
345
346
|
yield* sql`INSERT OR IGNORE INTO files (path) VALUES (${filePath})`;
|
|
347
|
+
const fileId = (yield* sql`SELECT id FROM files WHERE path = ${filePath}`)[0].id;
|
|
346
348
|
yield* sql`
|
|
347
349
|
INSERT INTO file_edits (turn_id, file_id, edit_kind, lines_added, lines_removed, diff)
|
|
348
350
|
VALUES (
|
|
349
351
|
${turnId},
|
|
350
|
-
${
|
|
352
|
+
${fileId},
|
|
351
353
|
${payload.edit_kind},
|
|
352
354
|
${payload.lines_added ?? null},
|
|
353
355
|
${payload.lines_removed ?? null},
|
|
@@ -356,11 +358,12 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
|
|
|
356
358
|
`;
|
|
357
359
|
} else {
|
|
358
360
|
const rawToolName = payload.tool_name;
|
|
361
|
+
const toolName = typeof rawToolName === "string" && rawToolName.startsWith("mcp__") ? rawToolName.split("__").at(-1) ?? rawToolName : rawToolName;
|
|
359
362
|
yield* sql`
|
|
360
363
|
INSERT INTO tool_invocations (turn_id, tool_name, params_hash, result_summary, duration_ms, success)
|
|
361
364
|
VALUES (
|
|
362
365
|
${turnId},
|
|
363
|
-
${
|
|
366
|
+
${toolName},
|
|
364
367
|
${null},
|
|
365
368
|
${payload.result_summary ?? null},
|
|
366
369
|
${payload.duration_ms ?? null},
|
|
@@ -530,7 +533,7 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
|
|
|
530
533
|
goal: input.goal
|
|
531
534
|
}));
|
|
532
535
|
yield* ensureTddTaskOpen(input.tddTaskId);
|
|
533
|
-
|
|
536
|
+
const rows = yield* sql`
|
|
534
537
|
INSERT INTO tdd_session_goals (session_id, ordinal, goal)
|
|
535
538
|
SELECT ${input.tddTaskId},
|
|
536
539
|
COALESCE(MAX(ordinal), -1) + 1,
|
|
@@ -542,7 +545,8 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
|
|
|
542
545
|
operation: "write",
|
|
543
546
|
table: "tdd_session_goals",
|
|
544
547
|
reason: extractSqlReason(e)
|
|
545
|
-
})))
|
|
548
|
+
})));
|
|
549
|
+
return goalRowFromDb(rows[0]);
|
|
546
550
|
}).pipe(Effect.annotateLogs("service", "DataStore"));
|
|
547
551
|
const getGoal = (id) => Effect.gen(function* () {
|
|
548
552
|
const rows = yield* sql`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/sdk",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared Effect Schema, SQLite migrations, data layer, services, formatters, and utilities for vitest-agent packages.",
|
|
6
6
|
"keywords": [
|
|
@@ -43,11 +43,13 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@effect/cluster": "^0.59.0",
|
|
46
|
+
"@effect/experimental": "^0.60.0",
|
|
46
47
|
"@effect/platform": "^0.96.2",
|
|
47
48
|
"@effect/platform-node": "^0.107.0",
|
|
48
49
|
"@effect/rpc": "^0.75.1",
|
|
49
50
|
"@effect/sql": "^0.51.1",
|
|
50
51
|
"@effect/sql-sqlite-node": "^0.52.0",
|
|
52
|
+
"@effect/workflow": "^0.18.2",
|
|
51
53
|
"@types/acorn": "^6.0.4",
|
|
52
54
|
"acorn": "^8.17.0",
|
|
53
55
|
"acorn-typescript": "^1.4.13",
|
|
@@ -55,7 +57,7 @@
|
|
|
55
57
|
"config-file-effect": "^0.3.0",
|
|
56
58
|
"effect": "^3.21.4",
|
|
57
59
|
"std-env": "^4.1.0",
|
|
58
|
-
"workspaces-effect": "^
|
|
60
|
+
"workspaces-effect": "^2.0.2",
|
|
59
61
|
"xdg-effect": "^2.1.0"
|
|
60
62
|
},
|
|
61
63
|
"engines": {
|
package/services/idempotency.js
CHANGED
|
@@ -25,7 +25,8 @@ const IDEMPOTENCY_ROOT_SENTINEL = "__ROOT__";
|
|
|
25
25
|
const deriveIdempotencyKey = (input) => {
|
|
26
26
|
const parent = input.parentAgentId ?? "__ROOT__";
|
|
27
27
|
const message = `${input.agentType}|${parent}|${input.clientNonce}`;
|
|
28
|
-
|
|
28
|
+
const digest = createHash("sha256").update(message).digest();
|
|
29
|
+
return base32Encode(digest).slice(0, 26);
|
|
29
30
|
};
|
|
30
31
|
const BASE32_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
|
|
31
32
|
/**
|