@yadsh/dsh-qa-surface 0.8.0 → 0.9.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/README.md +113 -3
- package/compatibility.json +5 -0
- package/lib/access/capability-catalog.js +32 -3
- package/lib/access/capability-catalog.js.map +1 -1
- package/lib/access/service.js +45 -17
- package/lib/access/service.js.map +1 -1
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/store.js +14 -0
- package/lib/accounts/store.js.map +1 -1
- package/lib/admin/permissions.js +4 -0
- package/lib/admin/permissions.js.map +1 -1
- package/lib/admin/quality-store.js +71 -0
- package/lib/admin/quality-store.js.map +1 -1
- package/lib/admin/service.js +106 -1
- package/lib/admin/service.js.map +1 -1
- package/lib/admin/session-log.js +66 -5
- package/lib/admin/session-log.js.map +1 -1
- package/lib/client/QaSessionController.js +359 -37
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +26 -4
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaTranscriptAdapter.js +36 -0
- package/lib/client/QaTranscriptAdapter.js.map +1 -1
- package/lib/client/admin/QaAdmin.js +9 -1
- package/lib/client/admin/QaAdmin.js.map +1 -1
- package/lib/client/admin/pages/Conversations.js +33 -7
- package/lib/client/admin/pages/Conversations.js.map +1 -1
- package/lib/client/admin/shared.js +9 -0
- package/lib/client/admin/shared.js.map +1 -1
- package/lib/client/admin/styles.js +2 -0
- package/lib/client/admin/styles.js.map +1 -1
- package/lib/client/audit/QaAuditDialog.js +74 -0
- package/lib/client/audit/QaAuditDialog.js.map +1 -0
- package/lib/client/audit/QaAuditRowBadge.js +17 -0
- package/lib/client/audit/QaAuditRowBadge.js.map +1 -0
- package/lib/client/audit/controller.js +39 -0
- package/lib/client/audit/controller.js.map +1 -0
- package/lib/client/audit/types.js +36 -0
- package/lib/client/audit/types.js.map +1 -0
- package/lib/client/audit/use-chat-audits.js +139 -0
- package/lib/client/audit/use-chat-audits.js.map +1 -0
- package/lib/client/components/QaChangelog.js +43 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/components/QaComposer.js +63 -3
- package/lib/client/components/QaComposer.js.map +1 -1
- package/lib/client/components/QaMessage.js +16 -0
- package/lib/client/components/QaMessage.js.map +1 -1
- package/lib/client/components/QaQuestions.js +1 -1
- package/lib/client/components/QaQuestions.js.map +1 -1
- package/lib/client/components/QaSidebar.js +12 -1
- package/lib/client/components/QaSidebar.js.map +1 -1
- package/lib/client/index.js +22 -2
- package/lib/client/index.js.map +1 -1
- package/lib/client/project-session-state.js +15 -2
- package/lib/client/project-session-state.js.map +1 -1
- package/lib/client/prompt-content.js +26 -0
- package/lib/client/prompt-content.js.map +1 -1
- package/lib/client/settings/card.js +2 -2
- package/lib/client/settings/card.js.map +1 -1
- package/lib/client/settings/sections/lockdown.js +1 -6
- package/lib/client/settings/sections/lockdown.js.map +1 -1
- package/lib/client/settings/sections/slash.js +57 -0
- package/lib/client/settings/sections/slash.js.map +1 -0
- package/lib/client/settings/sections/status.js +9 -1
- package/lib/client/settings/sections/status.js.map +1 -1
- package/lib/client/settings/sections.js +1 -0
- package/lib/client/settings/sections.js.map +1 -1
- package/lib/client/slash/SlashPalette.js +48 -0
- package/lib/client/slash/SlashPalette.js.map +1 -0
- package/lib/client/slash/copy.js +54 -0
- package/lib/client/slash/copy.js.map +1 -0
- package/lib/client/slash/slash-router.js +49 -0
- package/lib/client/slash/slash-router.js.map +1 -0
- package/lib/client/slash/useSlashNavigation.js +95 -0
- package/lib/client/slash/useSlashNavigation.js.map +1 -0
- package/lib/client/styles.js +51 -1
- package/lib/client/styles.js.map +1 -1
- package/lib/client/types.js +11 -0
- package/lib/client/types.js.map +1 -1
- package/lib/client.js +4231 -551
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/basics.js +11 -2
- package/lib/config-resolvers/basics.js.map +1 -1
- package/lib/config-resolvers/defaults.js +22 -0
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config-resolvers/lockdown.js +8 -2
- package/lib/config-resolvers/lockdown.js.map +1 -1
- package/lib/config-resolvers/slash-commands.js +60 -0
- package/lib/config-resolvers/slash-commands.js.map +1 -0
- package/lib/config.js +61 -2
- package/lib/config.js.map +1 -1
- package/lib/index.js +158 -1
- package/lib/index.js.map +1 -1
- package/lib/personal-skills/service.js +16 -3
- package/lib/personal-skills/service.js.map +1 -1
- package/lib/provenance/host-store.js +18 -1
- package/lib/provenance/host-store.js.map +1 -1
- package/lib/questions.js +90 -43
- package/lib/questions.js.map +1 -1
- package/lib/resolve-config.js +5 -0
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +24 -0
- package/lib/secure-session.js.map +1 -1
- package/lib/slash/catalog.js +77 -0
- package/lib/slash/catalog.js.map +1 -0
- package/lib/slash/matcher.js +100 -0
- package/lib/slash/matcher.js.map +1 -0
- package/lib/slash/parser.js +79 -0
- package/lib/slash/parser.js.map +1 -0
- package/lib/slash/policy.js +72 -0
- package/lib/slash/policy.js.map +1 -0
- package/lib/slash/remotes.js +272 -0
- package/lib/slash/remotes.js.map +1 -0
- package/lib/typert.host.js +318 -53
- package/lib/typert.remote-client.d.ts +7 -1
- package/lib/typert.remote-client.js +247 -51
- package/lib/types/access/capability-catalog.d.ts +28 -1
- package/lib/types/access/service.d.ts +33 -4
- package/lib/types/accounts/errors.d.ts +7 -1
- package/lib/types/accounts/store.d.ts +12 -0
- package/lib/types/admin/quality-store.d.ts +18 -0
- package/lib/types/admin/service.d.ts +34 -2
- package/lib/types/admin/session-log.d.ts +65 -1
- package/lib/types/client/QaSessionController.d.ts +84 -2
- package/lib/types/client/QaSurface.d.ts +14 -1
- package/lib/types/client/admin/pages/Conversations.d.ts +4 -0
- package/lib/types/client/audit/QaAuditDialog.d.ts +21 -0
- package/lib/types/client/audit/QaAuditRowBadge.d.ts +18 -0
- package/lib/types/client/audit/controller.d.ts +27 -0
- package/lib/types/client/audit/types.d.ts +72 -0
- package/lib/types/client/audit/use-chat-audits.d.ts +20 -0
- package/lib/types/client/components/QaComposer.d.ts +12 -2
- package/lib/types/client/components/QaQuestions.d.ts +7 -0
- package/lib/types/client/components/QaSidebar.d.ts +8 -0
- package/lib/types/client/project-session-state.d.ts +3 -1
- package/lib/types/client/prompt-content.d.ts +9 -1
- package/lib/types/client/settings/sections/slash.d.ts +16 -0
- package/lib/types/client/settings/sections.d.ts +1 -0
- package/lib/types/client/slash/SlashPalette.d.ts +24 -0
- package/lib/types/client/slash/copy.d.ts +30 -0
- package/lib/types/client/slash/slash-router.d.ts +67 -0
- package/lib/types/client/slash/useSlashNavigation.d.ts +47 -0
- package/lib/types/client/styles.d.ts +9 -0
- package/lib/types/client/types.d.ts +16 -1
- package/lib/types/config-resolvers/slash-commands.d.ts +20 -0
- package/lib/types/index.d.ts +78 -1
- package/lib/types/personal-skills/service.d.ts +5 -0
- package/lib/types/provenance/host-store.d.ts +13 -0
- package/lib/types/questions.d.ts +8 -0
- package/lib/types/slash/catalog.d.ts +56 -0
- package/lib/types/slash/matcher.d.ts +51 -0
- package/lib/types/slash/parser.d.ts +46 -0
- package/lib/types/slash/policy.d.ts +40 -0
- package/lib/types/slash/remotes.d.ts +35 -0
- package/lib/types/types.d.ts +200 -5
- package/package.json +7 -3
- package/scripts/attach-workspace-sessions.mjs +472 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Agent } from "@deepseek-ai/dsh-agent";
|
|
2
2
|
import type { Context } from "@deepseek-ai/cordis";
|
|
3
|
+
import type { ScopeKey } from "@deepseek-ai/dsh-scope";
|
|
3
4
|
import type { SkillSummary } from "@deepseek-ai/dsh-skill";
|
|
4
5
|
import type { QaCapabilityDescriptor, QaSkillDescriptor } from "../types.js";
|
|
5
6
|
export interface CapabilityCatalogSnapshot {
|
|
@@ -19,10 +20,36 @@ export declare class QaCapabilityCatalog {
|
|
|
19
20
|
private readonly additionalToolNames;
|
|
20
21
|
/** Role ids used to report unknown subrole ids in skill metadata. */
|
|
21
22
|
private readonly knownSubroles;
|
|
23
|
+
/**
|
|
24
|
+
* The viewing scope an administrator's catalog is read with, for callers
|
|
25
|
+
* that have no agent of their own. Skills and tools an agent preset mounts
|
|
26
|
+
* (a kit's skill catalog, the preset's tool family) live in that preset's
|
|
27
|
+
* scope, so a global-only read reported an almost empty catalog: the
|
|
28
|
+
* administrator could neither see nor grant what every chat mounts.
|
|
29
|
+
* Resolving the scope may compose the preset; a failure degrades to the
|
|
30
|
+
* global view instead of failing the page.
|
|
31
|
+
*/
|
|
32
|
+
private readonly presetScope;
|
|
22
33
|
constructor(ctx: Context, additionalToolNames?: () => readonly string[],
|
|
23
34
|
/** Role ids used to report unknown subrole ids in skill metadata. */
|
|
24
|
-
knownSubroles?: () => readonly string[]
|
|
35
|
+
knownSubroles?: () => readonly string[],
|
|
36
|
+
/**
|
|
37
|
+
* The viewing scope an administrator's catalog is read with, for callers
|
|
38
|
+
* that have no agent of their own. Skills and tools an agent preset mounts
|
|
39
|
+
* (a kit's skill catalog, the preset's tool family) live in that preset's
|
|
40
|
+
* scope, so a global-only read reported an almost empty catalog: the
|
|
41
|
+
* administrator could neither see nor grant what every chat mounts.
|
|
42
|
+
* Resolving the scope may compose the preset; a failure degrades to the
|
|
43
|
+
* global view instead of failing the page.
|
|
44
|
+
*/
|
|
45
|
+
presetScope?: () => Promise<ScopeKey | undefined>);
|
|
25
46
|
snapshot(agent?: Agent): Promise<CapabilityCatalogSnapshot>;
|
|
47
|
+
/**
|
|
48
|
+
* The scope an administrator's catalog is read with. A deployment that pins
|
|
49
|
+
* QA chats to an agent preset gets that preset's standing scope; without a
|
|
50
|
+
* pinned preset there is no scope to borrow, and the read stays global.
|
|
51
|
+
*/
|
|
52
|
+
private resolvePresetScope;
|
|
26
53
|
/**
|
|
27
54
|
* Read `metadata.qa-surface` of every discovered skill.
|
|
28
55
|
*
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Agent } from "@deepseek-ai/dsh-agent";
|
|
2
2
|
import type { Context } from "@deepseek-ai/cordis";
|
|
3
|
+
import type { ScopeKey } from "@deepseek-ai/dsh-scope";
|
|
3
4
|
import type { PluginLogger } from "@yadsh/dsh-plugin-log";
|
|
4
5
|
import type { QaAccounts } from "../accounts/store.js";
|
|
5
6
|
import type { QaAgentToolGrants } from "../enforcement/tool-grants.js";
|
|
@@ -27,6 +28,8 @@ export declare class QaAccessService {
|
|
|
27
28
|
readonly roles: QaRoleRepository;
|
|
28
29
|
readonly catalog: QaCapabilityCatalog;
|
|
29
30
|
private lastOwnershipSweepAt;
|
|
31
|
+
/** The sweep in flight, so a burst of readers runs one listing, not ten. */
|
|
32
|
+
private ownershipSweep;
|
|
30
33
|
/**
|
|
31
34
|
* Sessions the Host has listed as delegated children of another session.
|
|
32
35
|
* The live registry answers for a child that is running right now; this
|
|
@@ -42,6 +45,13 @@ export declare class QaAccessService {
|
|
|
42
45
|
readonly logger: PluginLogger;
|
|
43
46
|
readonly repository?: QaRoleRepository;
|
|
44
47
|
readonly dynamicToolNames?: () => readonly string[];
|
|
48
|
+
/**
|
|
49
|
+
* The viewing scope an administrator's catalog is read with. Skills and
|
|
50
|
+
* tools a deployment mounts through an agent preset live in that
|
|
51
|
+
* preset's scope, so a global-only catalog left the operator unable to
|
|
52
|
+
* see — or grant — what every QA chat actually mounts.
|
|
53
|
+
*/
|
|
54
|
+
readonly presetScope?: () => Promise<ScopeKey | undefined>;
|
|
45
55
|
/**
|
|
46
56
|
* Durable session listing, used to tell a chat from a delegated child
|
|
47
57
|
* across Host runs. Without it the lineage answer degrades to the live
|
|
@@ -49,6 +59,14 @@ export declare class QaAccessService {
|
|
|
49
59
|
* materialized — the sweep then reclaims nothing rather than guessing.
|
|
50
60
|
*/
|
|
51
61
|
readonly sessionLog?: QaSessionLogReader;
|
|
62
|
+
/**
|
|
63
|
+
* Called with the ids of chats the Harness no longer knows, once their
|
|
64
|
+
* ownership records are reclaimed. The record is the auth boundary, not
|
|
65
|
+
* the whole of what the deployment kept about a chat: ratings, reviews
|
|
66
|
+
* and queue entries are keyed by conversation, and they outlive their
|
|
67
|
+
* chat unless the caller drops them here.
|
|
68
|
+
*/
|
|
69
|
+
readonly onVanishedSessions?: (sessionIds: readonly string[]) => void;
|
|
52
70
|
});
|
|
53
71
|
/**
|
|
54
72
|
* Whether the Host can prove this session is a delegated child: a subagent's
|
|
@@ -68,11 +86,22 @@ export declare class QaAccessService {
|
|
|
68
86
|
* Nothing else removes them: the browser's "delete chat" hides a chat in one
|
|
69
87
|
* browser, and a record outlives its session forever, so a year of QA traffic
|
|
70
88
|
* accumulates one row per chat ever created. The sweep is throttled, runs
|
|
71
|
-
* off the reservation path, and is skipped entirely
|
|
72
|
-
* say what exists — an unanswerable question is
|
|
73
|
-
* auth boundary.
|
|
89
|
+
* off the reservation path and off the review reads, and is skipped entirely
|
|
90
|
+
* when the Harness cannot say what exists — an unanswerable question is
|
|
91
|
+
* never a licence to delete an auth boundary.
|
|
92
|
+
*
|
|
93
|
+
* What exists is both halves of the Harness's own knowledge: the sessions
|
|
94
|
+
* this process has open and the ones its storage still holds. The live store
|
|
95
|
+
* alone would make a cold chat — one nobody has opened since the last
|
|
96
|
+
* restart — look deleted, and the sweep would reclaim records of chats that
|
|
97
|
+
* are merely quiet. A listing that cannot see stored sessions therefore
|
|
98
|
+
* reclaims nothing.
|
|
99
|
+
*
|
|
100
|
+
* @returns the sweep, for callers that want to await it (tests, and the
|
|
101
|
+
* review reads that must show the console what still exists).
|
|
74
102
|
*/
|
|
75
|
-
|
|
103
|
+
sweepVanishedOwnership(): Promise<void>;
|
|
104
|
+
private runOwnershipSweep;
|
|
76
105
|
/**
|
|
77
106
|
* Migrate a browser's local chat index into server-side ownership.
|
|
78
107
|
*
|
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
* marker pattern the attestation path established; the browser maps them to
|
|
4
4
|
* audience-safe copy and the precise cause stays in the Host logs.
|
|
5
5
|
*/
|
|
6
|
-
export type QaAccountsErrorReason = "auth-required" | "admin-required" | "forbidden" | "invalid-credentials" | "account-disabled" | "email-taken" | "invalid-email" | "invalid-display-name" | "invalid-profile" | "profile-disabled" | "invalid-starters" | "starters-disabled" | "invalid-role" | "weak-password" | "registration-disabled" | "rate-limited" | "session-owned-elsewhere"
|
|
6
|
+
export type QaAccountsErrorReason = "auth-required" | "admin-required" | "forbidden" | "invalid-credentials" | "account-disabled" | "email-taken" | "invalid-email" | "invalid-display-name" | "invalid-profile" | "profile-disabled" | "invalid-starters" | "starters-disabled" | "invalid-role" | "weak-password" | "registration-disabled" | "rate-limited" | "session-owned-elsewhere"
|
|
7
|
+
/** The conversation a deletion names is not one this deployment knows. */
|
|
8
|
+
| "conversation-unknown"
|
|
9
|
+
/** The Harness still holds the conversation open, so its log would come back. */
|
|
10
|
+
| "conversation-live"
|
|
11
|
+
/** This deployment cannot remove stored conversations at all. */
|
|
12
|
+
| "conversation-not-removable";
|
|
7
13
|
export declare class QaAccountsError extends Error {
|
|
8
14
|
readonly reason: QaAccountsErrorReason;
|
|
9
15
|
constructor(reason: QaAccountsErrorReason, message: string);
|
|
@@ -138,6 +138,18 @@ export declare class QaAccounts {
|
|
|
138
138
|
* @returns the session ids whose records were dropped.
|
|
139
139
|
*/
|
|
140
140
|
pruneDelegatedOwnership(sessionIds: ReadonlySet<string>): readonly string[];
|
|
141
|
+
/**
|
|
142
|
+
* Drop the ownership records of the named sessions, whatever their lineage.
|
|
143
|
+
*
|
|
144
|
+
* This is the record half of a deletion: the caller has already established
|
|
145
|
+
* that these sessions are gone (or is removing them as part of the same
|
|
146
|
+
* act), so the auth boundary goes with them. Nothing here decides anything —
|
|
147
|
+
* the sweeps above own the judgments, and both end in this.
|
|
148
|
+
*
|
|
149
|
+
* @param sessionIds - the ids whose records are dropped.
|
|
150
|
+
* @returns the session ids whose records were actually there.
|
|
151
|
+
*/
|
|
152
|
+
forgetSessions(sessionIds: ReadonlySet<string>): readonly string[];
|
|
141
153
|
/**
|
|
142
154
|
* Drop ownership records for chats the Harness no longer knows.
|
|
143
155
|
*
|
|
@@ -67,6 +67,24 @@ export declare class QaQualityStore {
|
|
|
67
67
|
/** Drop a manual queue entry once a reviewer has answered it. */
|
|
68
68
|
dequeueReview(conversationId: string, messageId?: string): boolean;
|
|
69
69
|
manualQueue(): readonly QaManualQueueEntry[];
|
|
70
|
+
/**
|
|
71
|
+
* Drop every quality record of the named conversations.
|
|
72
|
+
*
|
|
73
|
+
* A record is keyed by the conversation it judges, and nothing else removes
|
|
74
|
+
* it: a chat deleted from the Harness would otherwise leave its ratings,
|
|
75
|
+
* reviews and queue entries behind, still counted by the metrics and still
|
|
76
|
+
* pointing at a conversation the console cannot open. The ownership sweep is
|
|
77
|
+
* the one place that learns a chat is gone, and it calls this with the ids
|
|
78
|
+
* it reclaimed.
|
|
79
|
+
*
|
|
80
|
+
* The audit trail is not touched: it records what administrators did, not
|
|
81
|
+
* what a conversation held, and a housekeeping drop is not an administrative
|
|
82
|
+
* act to answer for.
|
|
83
|
+
*
|
|
84
|
+
* @param conversationIds - the conversations to forget.
|
|
85
|
+
* @returns how many rows were removed.
|
|
86
|
+
*/
|
|
87
|
+
dropConversations(conversationIds: readonly string[]): number;
|
|
70
88
|
/** Append one administrative action to the audit trail. */
|
|
71
89
|
appendAudit(input: {
|
|
72
90
|
readonly actorId: string;
|
|
@@ -2,10 +2,10 @@ import type { PluginLogger } from "@yadsh/dsh-plugin-log";
|
|
|
2
2
|
import type { QaAccounts } from "../accounts/store.js";
|
|
3
3
|
import type { QaAccessService } from "../access/service.js";
|
|
4
4
|
import type { QaRoleRepository } from "../access/role-repository.js";
|
|
5
|
-
import type { QaAdminAuditEvent, QaAdminOverview, QaAdminPage, QaAdminUserDetail, QaAdminUserRow, QaAdminUserUpdate, QaAuditQuery, QaConversationDetail, QaConversationQuery, QaConversationReview, QaConversationReviewInput, QaConversationSummary, QaFeedbackQuery, QaFeedbackRow, QaMessageFeedback, QaMessageFeedbackInput, QaQualityMetrics, QaReviewQueueItem, QaReviewQueueRow, QaUserQuery } from "../types.js";
|
|
5
|
+
import type { QaAdminAuditEvent, QaAdminOverview, QaAdminPage, QaAdminUserDetail, QaAdminUserRow, QaAdminUserUpdate, QaAuditQuery, QaConversationDetail, QaConversationDeletion, QaConversationQuery, QaConversationReview, QaConversationReviewInput, QaConversationSummary, QaFeedbackQuery, QaFeedbackRow, QaMessageFeedback, QaMessageFeedbackInput, QaQualityMetrics, QaReviewQueueItem, QaReviewQueueRow, QaUserQuery } from "../types.js";
|
|
6
6
|
import type { QaQualityStore } from "./quality-store.js";
|
|
7
7
|
import type { QaAdminRedactor } from "./redaction.js";
|
|
8
|
-
import type { QaSessionLogReader } from "./session-log.js";
|
|
8
|
+
import type { QaSessionLogReader, QaStoredSessionEraser } from "./session-log.js";
|
|
9
9
|
/**
|
|
10
10
|
* The administrative console's server side.
|
|
11
11
|
*
|
|
@@ -31,6 +31,14 @@ export interface QaAdminServiceOptions {
|
|
|
31
31
|
readonly roles: () => QaRoleRepository;
|
|
32
32
|
readonly access: () => QaAccessService;
|
|
33
33
|
readonly sessionLog: QaSessionLogReader;
|
|
34
|
+
/**
|
|
35
|
+
* Removal of stored session logs, the one thing the Harness does not offer.
|
|
36
|
+
* Without it the console refuses to delete a conversation rather than
|
|
37
|
+
* pretending it did.
|
|
38
|
+
*/
|
|
39
|
+
readonly sessionFiles?: QaStoredSessionEraser;
|
|
40
|
+
/** Drops the sources a conversation collected, when the deployment keeps any. */
|
|
41
|
+
readonly dropSources?: (sessionId: string) => void;
|
|
34
42
|
readonly logger: PluginLogger;
|
|
35
43
|
readonly redactor?: QaAdminRedactor;
|
|
36
44
|
readonly clock?: QaServiceClock;
|
|
@@ -52,6 +60,12 @@ export declare class QaAdminService {
|
|
|
52
60
|
* enriched with the stored header when the deployment can list one. A chat
|
|
53
61
|
* that exists but has no readable log still appears — the reviewer must see
|
|
54
62
|
* that it happened.
|
|
63
|
+
*
|
|
64
|
+
* Reading the index first asks the access sweep to reclaim what the Harness
|
|
65
|
+
* no longer knows: a chat deleted outside the deployment would otherwise sit
|
|
66
|
+
* in this list, in the counters and in the metrics until some later chat
|
|
67
|
+
* creation happened to trigger housekeeping. The sweep is throttled, so this
|
|
68
|
+
* costs a listing per interval at most.
|
|
55
69
|
*/
|
|
56
70
|
private index;
|
|
57
71
|
/** One conversation's projected log, cached for the TTL unless asked fresh. */
|
|
@@ -76,6 +90,24 @@ export declare class QaAdminService {
|
|
|
76
90
|
conversations(token: string, query: QaConversationQuery, cursor: string | undefined, limit: number | undefined): Promise<QaAdminPage<QaConversationSummary>>;
|
|
77
91
|
private summaryOf;
|
|
78
92
|
conversation(token: string, conversationId: string): Promise<QaConversationDetail>;
|
|
93
|
+
/**
|
|
94
|
+
* Delete one conversation from the deployment.
|
|
95
|
+
*
|
|
96
|
+
* The Harness has no deletion seam: persistence offers create, open, flush,
|
|
97
|
+
* stat and list, and a chat stops existing only when its stored log is gone.
|
|
98
|
+
* This is where the console's delete button gets its teeth — the stored logs
|
|
99
|
+
* of the conversation and of every session delegated from it are removed,
|
|
100
|
+
* and then everything the QA layer kept about it: the ownership record that
|
|
101
|
+
* is its authorization boundary, its ratings, reviews and queue entries, and
|
|
102
|
+
* the sources it collected. The act is audited, because it destroys what a
|
|
103
|
+
* person wrote, and that is not the same as hiding a row.
|
|
104
|
+
*
|
|
105
|
+
* Every refusal comes before anything is removed, so a chat is never
|
|
106
|
+
* half-deleted: a conversation the Harness still holds open would have its
|
|
107
|
+
* log written back by the next flush, and one the deployment stores somewhere
|
|
108
|
+
* directories do not express cannot be removed at all.
|
|
109
|
+
*/
|
|
110
|
+
deleteConversation(token: string, conversationId: string): Promise<QaConversationDeletion>;
|
|
79
111
|
private failuresOf;
|
|
80
112
|
private failureSignals;
|
|
81
113
|
/**
|
|
@@ -35,9 +35,54 @@ export type QaSessionReadResult = {
|
|
|
35
35
|
readonly ok: false;
|
|
36
36
|
readonly reason: QaTranscriptUnavailableReason;
|
|
37
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* One listing of the deployment's sessions together with what the answer
|
|
40
|
+
* covers. The distinction is load-bearing: on a deployment that serves no
|
|
41
|
+
* durable query engine the listing is only what this process has open, and a
|
|
42
|
+
* chat nobody opened since the last restart is absent from it without being
|
|
43
|
+
* gone.
|
|
44
|
+
*/
|
|
45
|
+
export interface QaSessionListing {
|
|
46
|
+
readonly headers: readonly QaStoredSessionHeader[];
|
|
47
|
+
/**
|
|
48
|
+
* True when the listing answers for every stored session, not only the live
|
|
49
|
+
* ones. A consumer that must never read "absent" as "deleted" — the
|
|
50
|
+
* ownership sweep — reclaims nothing against an incomplete listing.
|
|
51
|
+
*/
|
|
52
|
+
readonly complete: boolean;
|
|
53
|
+
}
|
|
38
54
|
export interface QaSessionLogReader {
|
|
39
|
-
list(): Promise<
|
|
55
|
+
list(): Promise<QaSessionListing>;
|
|
40
56
|
read(sessionId: string): Promise<QaSessionReadResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Whether the Harness holds this session in memory right now. Such a session
|
|
59
|
+
* is still being written: storage removal cannot take it away, because the
|
|
60
|
+
* next flush would put its log back.
|
|
61
|
+
*/
|
|
62
|
+
live(sessionId: string): boolean;
|
|
63
|
+
}
|
|
64
|
+
/** What one storage-removal call did, id by id. */
|
|
65
|
+
export interface QaSessionEraseOutcome {
|
|
66
|
+
/** Ids whose stored directories were removed. */
|
|
67
|
+
readonly removed: readonly string[];
|
|
68
|
+
/**
|
|
69
|
+
* Ids with no stored directory to remove: the session is already gone, or
|
|
70
|
+
* this deployment keeps it somewhere directories cannot express.
|
|
71
|
+
*/
|
|
72
|
+
readonly absent: readonly string[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Removal of stored sessions.
|
|
76
|
+
*
|
|
77
|
+
* The Harness has no deletion seam: `sessionPersistence` offers
|
|
78
|
+
* create/open/flush/stat/list, and the in-memory store drops a session only
|
|
79
|
+
* when the fiber that owns it disposes. A deployment that wants a conversation
|
|
80
|
+
* to stop existing therefore has to remove the artifacts storage keeps, which
|
|
81
|
+
* for the directory-backed backend means the session directories under the
|
|
82
|
+
* home. Implementations report what they could not do instead of guessing.
|
|
83
|
+
*/
|
|
84
|
+
export interface QaStoredSessionEraser {
|
|
85
|
+
erase(sessionIds: readonly string[]): Promise<QaSessionEraseOutcome>;
|
|
41
86
|
}
|
|
42
87
|
/**
|
|
43
88
|
* Build the reader for one plugin instance. The services are looked up per
|
|
@@ -49,5 +94,24 @@ export declare function createSessionLogReader(ctx: Context): QaSessionLogReader
|
|
|
49
94
|
export declare function staticSessionLogReader(input: {
|
|
50
95
|
readonly sessions?: readonly QaStoredSessionHeader[];
|
|
51
96
|
readonly events?: Readonly<Record<string, readonly StoredSessionEvent[]>>;
|
|
97
|
+
/**
|
|
98
|
+
* Whether the listed sessions are the fixture's whole world. True by
|
|
99
|
+
* default — a fixture that names its sessions means them to be all of them;
|
|
100
|
+
* pass false to stand for a live-only view of a larger deployment.
|
|
101
|
+
*/
|
|
102
|
+
readonly complete?: boolean;
|
|
103
|
+
/** Ids the fixture's Harness still holds open. */
|
|
104
|
+
readonly held?: readonly string[];
|
|
52
105
|
}): QaSessionLogReader;
|
|
106
|
+
/**
|
|
107
|
+
* The stored sessions of a directory-backed deployment: one directory per
|
|
108
|
+
* session under `<home>/sessions/<project>/<sessionId>`, named by the id the
|
|
109
|
+
* header carries. The home follows the same convention as the deployment's
|
|
110
|
+
* other stores (`DSH_HOME`, then the working directory).
|
|
111
|
+
*
|
|
112
|
+
* Removal is by directory name and never by guessing a project key: the id is
|
|
113
|
+
* what the caller knows, and the directory either exists under one of the
|
|
114
|
+
* projects or does not exist at all.
|
|
115
|
+
*/
|
|
116
|
+
export declare function createSessionEraser(home?: string): QaStoredSessionEraser;
|
|
53
117
|
//# sourceMappingURL=session-log.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ConnectionGenerationState } from "@deepseek-ai/dsh-client-connection/client";
|
|
2
2
|
import type { QaAttachmentDraft, QaSessionState, ResolvedQaSurfaceConfig } from "../types.js";
|
|
3
|
-
import type { QaApprovalApi, QaConversation, QaCreateSession, QaFileUpload, QaSecureSession, QaSessions, QaSessionsApi, QaQuestionApi, QaSourceApi, StorageLike } from "./types.js";
|
|
3
|
+
import type { QaApprovalApi, QaConversation, QaCreateSession, QaFileUpload, QaSecureSession, QaSessions, QaSessionsApi, QaQuestionApi, QaSlashApi, QaSourceApi, StorageLike } from "./types.js";
|
|
4
4
|
import type { QaApprovalDecision, QaQuestionAnswerItem } from "../types.js";
|
|
5
5
|
export interface QaAccountsFacade {
|
|
6
6
|
/** The account bearer token, or null while anonymous. */
|
|
@@ -38,6 +38,12 @@ export interface QaSessionControllerOptions {
|
|
|
38
38
|
* does not answer questions: the surface then only renders what it can.
|
|
39
39
|
*/
|
|
40
40
|
readonly questionApi?: QaQuestionApi;
|
|
41
|
+
/**
|
|
42
|
+
* The slash half of the Host namespace. Absent on a page whose Host build
|
|
43
|
+
* predates it: the palette then never appears and ordinary prompts keep
|
|
44
|
+
* working, which is exactly the pre-feature behaviour.
|
|
45
|
+
*/
|
|
46
|
+
readonly slashApi?: QaSlashApi;
|
|
41
47
|
readonly storage?: StorageLike;
|
|
42
48
|
/**
|
|
43
49
|
* Browser file-upload service, resolved lazily: the page may not serve the
|
|
@@ -74,6 +80,8 @@ export declare class QaSessionController {
|
|
|
74
80
|
private readonly sourceApi;
|
|
75
81
|
private readonly chats;
|
|
76
82
|
private readonly accounts;
|
|
83
|
+
/** Slash half of the Host namespace; absent on an older Host build. */
|
|
84
|
+
private readonly slashApi;
|
|
77
85
|
/** Resolved per send: a page without the upload plugin has no receipts. */
|
|
78
86
|
private readonly fileUpload;
|
|
79
87
|
/** Per-chat attachment URL cache; blob URLs die with the chat binding. */
|
|
@@ -114,6 +122,25 @@ export declare class QaSessionController {
|
|
|
114
122
|
private readonly hostQuestions;
|
|
115
123
|
/** Set while a running turn is polled for parked requests. */
|
|
116
124
|
private pendingTimer;
|
|
125
|
+
/**
|
|
126
|
+
* Slash catalog of the bound chat. Keyed by session: it depends on the
|
|
127
|
+
* chat's cwd, its agent composition and its role, so it is dropped with the
|
|
128
|
+
* binding instead of being carried across chats.
|
|
129
|
+
*/
|
|
130
|
+
private slashSessionId;
|
|
131
|
+
private slashEntries;
|
|
132
|
+
private slashDenied;
|
|
133
|
+
private slashSurface;
|
|
134
|
+
private slashState;
|
|
135
|
+
private slashError;
|
|
136
|
+
private slashLoadedAt;
|
|
137
|
+
private slashLoading;
|
|
138
|
+
/** Last published view; its identity is the render signal. */
|
|
139
|
+
private slashViewCache;
|
|
140
|
+
/** Bumped to re-open a palette the user dismissed; see `QaSlashView`. */
|
|
141
|
+
private slashReopen;
|
|
142
|
+
/** Chat, connection and admission state of the last one-shot probe. */
|
|
143
|
+
private pendingProbeKey;
|
|
117
144
|
constructor(options: QaSessionControllerOptions);
|
|
118
145
|
getSnapshot: () => QaSessionState;
|
|
119
146
|
subscribe: (listener: () => void) => (() => void);
|
|
@@ -124,7 +151,48 @@ export declare class QaSessionController {
|
|
|
124
151
|
* favor of a fresh Host-owned session.
|
|
125
152
|
*/
|
|
126
153
|
selectSubrole(subroleId: string, adminPreview?: boolean): Promise<void>;
|
|
127
|
-
|
|
154
|
+
/**
|
|
155
|
+
* The attested live session a submission may ride, or `undefined` when the
|
|
156
|
+
* caller must abort. Materializing a draft chat, attesting policy and
|
|
157
|
+
* recovering from a stale proof live here, so the prompt path and the
|
|
158
|
+
* command path cannot drift apart on what "ready to send" means.
|
|
159
|
+
*/
|
|
160
|
+
private liveTarget;
|
|
161
|
+
/**
|
|
162
|
+
* Route one composer draft. Ordinary text and a skill invocation both ride
|
|
163
|
+
* the native prompt path — a skill is a gesture inside the prompt, not a
|
|
164
|
+
* call this surface makes — while a human command goes to the Host's command
|
|
165
|
+
* runtime and never becomes a model message.
|
|
166
|
+
*/
|
|
167
|
+
send(text: string, attachments?: readonly QaAttachmentDraft[], pick?: string | null): Promise<boolean>;
|
|
168
|
+
/**
|
|
169
|
+
* Run one admitted human command. The Host answers it and writes the
|
|
170
|
+
* lifecycle into the session log; this method only decides what the composer
|
|
171
|
+
* does next, which is why nothing here creates a pending user row.
|
|
172
|
+
*
|
|
173
|
+
* A refusal keeps the draft and the attachments: the user asked for
|
|
174
|
+
* something the deployment does not allow, and retyping the line is a worse
|
|
175
|
+
* answer than leaving it in place to be edited.
|
|
176
|
+
*/
|
|
177
|
+
private sendCommand;
|
|
178
|
+
/**
|
|
179
|
+
* Refresh the catalog of the bound chat. Called when a chat binds, and again
|
|
180
|
+
* when the palette opens on a catalog that has had time to go stale: the
|
|
181
|
+
* skill registry has no browser-facing change event, so a skill installed
|
|
182
|
+
* while the page is open is only discovered by asking again.
|
|
183
|
+
*/
|
|
184
|
+
refreshSlashCatalog(force?: boolean): Promise<void>;
|
|
185
|
+
/**
|
|
186
|
+
* Install one catalog answer. `null` means the deployment runs with the
|
|
187
|
+
* slash interface off; `undefined` means the answer never arrived. The
|
|
188
|
+
* difference matters: an unreachable catalog must not turn ordinary prompts
|
|
189
|
+
* into refusals.
|
|
190
|
+
*/
|
|
191
|
+
private applySlashCatalog;
|
|
192
|
+
/** Whether the catalog of the bound chat was read successfully. */
|
|
193
|
+
private slashCatalogReady;
|
|
194
|
+
/** The slash view of the current state; assembled where the state is. */
|
|
195
|
+
private slashView;
|
|
128
196
|
/** Publish a browser-only copy before any network or Host admission awaits. */
|
|
129
197
|
private beginSubmission;
|
|
130
198
|
/**
|
|
@@ -239,8 +307,22 @@ export declare class QaSessionController {
|
|
|
239
307
|
* inside an open turn, and it is Host state: polling is how the page learns
|
|
240
308
|
* about it, and how it reappears after a reload. One timer serves both seams,
|
|
241
309
|
* and each is polled only where the deployment answers it.
|
|
310
|
+
*
|
|
311
|
+
* A request that is already on screen keeps the timer alive past the end of
|
|
312
|
+
* its turn: the Host settles what the turn can no longer answer — an aborted
|
|
313
|
+
* tool call, an agent that went idle — and this keeps reading until that
|
|
314
|
+
* settlement reaches the page, so the form goes away instead of sitting
|
|
315
|
+
* there answerable but dead.
|
|
242
316
|
*/
|
|
243
317
|
private syncPendingPolling;
|
|
318
|
+
/**
|
|
319
|
+
* Read what the Host parks once per chat and connection, whether or not a
|
|
320
|
+
* turn is running. A reload binds the chat before any turn reports itself
|
|
321
|
+
* over the fresh stream, and a turn that is already waiting on a question
|
|
322
|
+
* would otherwise sit behind an empty composer until the operator happened
|
|
323
|
+
* to send something.
|
|
324
|
+
*/
|
|
325
|
+
private probePending;
|
|
244
326
|
private stopPendingPolling;
|
|
245
327
|
private hostToken;
|
|
246
328
|
}
|
|
@@ -3,9 +3,10 @@ import type { InjectFace, PropsRenderSlots, PropsRuntime } from "@deepseek-ai/ds
|
|
|
3
3
|
import type { QaConfigController } from "./QaConfigController.js";
|
|
4
4
|
import type { QaRouteController } from "./QaRouteController.js";
|
|
5
5
|
import type { QaAccountsController } from "./QaAccountsController.js";
|
|
6
|
-
import type { QaApprovalApi, QaAccessApi, QaAdminApi, QaConversation, QaCreateSession, QaFileUpload, QaSecureSession, QaSessions, QaSessionsApi, QaQuestionApi, QaSkillApi, QaSourceApi } from "./types.js";
|
|
6
|
+
import type { QaApprovalApi, QaAccessApi, QaAdminApi, QaConversation, QaCreateSession, QaFileUpload, QaSecureSession, QaSessions, QaSessionsApi, QaQuestionApi, QaSkillApi, QaSlashApi, QaSourceApi } from "./types.js";
|
|
7
7
|
import type { QaSurfacePanelRegistry } from "./panels/registry.js";
|
|
8
8
|
import type { QaUserSettingsSections } from "./settings-extensions/index.js";
|
|
9
|
+
import type { QaAuditController } from "./audit/controller.js";
|
|
9
10
|
export interface QaSurfaceFace {
|
|
10
11
|
readonly route: QaRouteController;
|
|
11
12
|
readonly config: QaConfigController;
|
|
@@ -34,6 +35,12 @@ export interface QaSurfaceFace {
|
|
|
34
35
|
readonly approvalApi?: QaApprovalApi;
|
|
35
36
|
/** Question half of the plugin's namespace, when the Host answers it. */
|
|
36
37
|
readonly questionApi?: QaQuestionApi;
|
|
38
|
+
/**
|
|
39
|
+
* Slash half of the plugin's namespace. Absent on a Host build that predates
|
|
40
|
+
* it: the composer then never opens a palette and ordinary prompts are
|
|
41
|
+
* untouched.
|
|
42
|
+
*/
|
|
43
|
+
readonly slashApi?: QaSlashApi;
|
|
37
44
|
/**
|
|
38
45
|
* Browser file-upload service, when the page serves the upload plugin.
|
|
39
46
|
* Resolved per send so a page that loads it later still gets file support.
|
|
@@ -45,6 +52,12 @@ export interface QaSurfaceFace {
|
|
|
45
52
|
readonly panels: QaSurfacePanelRegistry;
|
|
46
53
|
/** First-class settings pages registered by additive QA plugins. */
|
|
47
54
|
readonly settingsSections: QaUserSettingsSections;
|
|
55
|
+
/**
|
|
56
|
+
* Whether the session-audit provider is installed. Its snapshot carries the
|
|
57
|
+
* audit API, or `null` — the badge and the dialog exist only while it is
|
|
58
|
+
* present.
|
|
59
|
+
*/
|
|
60
|
+
readonly audit: QaAuditController;
|
|
48
61
|
}
|
|
49
62
|
export type QaSurfaceProps = PropsRuntime<"shell.overlay"> & PropsRenderSlots<"qa.surface.panel"> & InjectFace<QaSurfaceFace>;
|
|
50
63
|
export declare function QaSurface(props: QaSurfaceProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -16,6 +16,10 @@ export declare function AdminConversation(props: {
|
|
|
16
16
|
readonly conversationId: string;
|
|
17
17
|
readonly messageId?: string;
|
|
18
18
|
readonly canReview: boolean;
|
|
19
|
+
/** Removing the conversation itself belongs to the administrator alone. */
|
|
20
|
+
readonly canDelete: boolean;
|
|
19
21
|
readonly onBack: () => void;
|
|
22
|
+
/** Called once the conversation is gone, so the console leaves the page. */
|
|
23
|
+
readonly onDeleted?: () => void;
|
|
20
24
|
}): import("react/jsx-runtime").JSX.Element;
|
|
21
25
|
//# sourceMappingURL=Conversations.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The audit dialog: the same content as the session page, in this surface's
|
|
3
|
+
* own shell (SPEC §51).
|
|
4
|
+
*
|
|
5
|
+
* The status bar is compact and the tab strip is shared, because the audit is
|
|
6
|
+
* the same audit — a reader who has seen it in the ordinary DSH session should
|
|
7
|
+
* recognise every number here.
|
|
8
|
+
*/
|
|
9
|
+
import { type ReactNode } from "react";
|
|
10
|
+
import type { QaAuditApi, QaAuditSummary } from "./types.js";
|
|
11
|
+
export interface QaAuditDialogProps {
|
|
12
|
+
readonly open: boolean;
|
|
13
|
+
readonly sessionId: string | null;
|
|
14
|
+
readonly title: string;
|
|
15
|
+
readonly api: QaAuditApi | null;
|
|
16
|
+
/** The summary the badge was built from, for the reload key. */
|
|
17
|
+
readonly summary: QaAuditSummary | undefined;
|
|
18
|
+
readonly onClose: () => void;
|
|
19
|
+
}
|
|
20
|
+
export declare function QaAuditDialog(props: QaAuditDialogProps): ReactNode;
|
|
21
|
+
//# sourceMappingURL=QaAuditDialog.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The row badge: "this chat was audited", and what the audit found.
|
|
3
|
+
*
|
|
4
|
+
* Two visually distinct things, on purpose (SPEC §52). The check mark and the
|
|
5
|
+
* label say *an audit exists*; the verdict and the counts say *what it found*.
|
|
6
|
+
* A green tick next to "poor" has to read as "audited, and it went badly",
|
|
7
|
+
* which is why the tick is never the thing that carries the quality.
|
|
8
|
+
*/
|
|
9
|
+
import type { ReactNode } from "react";
|
|
10
|
+
import type { QaAuditMark } from "./types.js";
|
|
11
|
+
export interface QaAuditRowBadgeProps {
|
|
12
|
+
readonly mark: QaAuditMark;
|
|
13
|
+
/** Whether the row also carries a delete control, which takes the right slot. */
|
|
14
|
+
readonly withDelete: boolean;
|
|
15
|
+
readonly onOpen: () => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function QaAuditRowBadge(props: QaAuditRowBadgeProps): ReactNode;
|
|
18
|
+
//# sourceMappingURL=QaAuditRowBadge.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the audit provider is present, as a client-side service.
|
|
3
|
+
*
|
|
4
|
+
* The audit plugin may or may not be installed, and its Remote namespace
|
|
5
|
+
* arrives asynchronously. A React tree cannot watch a Cordis injection by
|
|
6
|
+
* itself, so the attach/detach pair below is exposed as an external store and
|
|
7
|
+
* the surface reads it with `useSyncExternalStore` — the same shape the rest
|
|
8
|
+
* of this client uses for host-driven state.
|
|
9
|
+
*/
|
|
10
|
+
import type { QaAuditApi } from "./types.js";
|
|
11
|
+
/** The snapshot the surface renders from; replaced, never mutated. */
|
|
12
|
+
export interface QaAuditSnapshot {
|
|
13
|
+
readonly api: QaAuditApi | null;
|
|
14
|
+
}
|
|
15
|
+
export declare class QaAuditController {
|
|
16
|
+
private snapshot;
|
|
17
|
+
private readonly listeners;
|
|
18
|
+
/** The provider's namespace resolved: audits become visible. */
|
|
19
|
+
attach(api: QaAuditApi): void;
|
|
20
|
+
/** The provider went away: the badge and the dialog disappear with it. */
|
|
21
|
+
detach(): void;
|
|
22
|
+
getSnapshot: () => QaAuditSnapshot;
|
|
23
|
+
subscribe: (listener: () => void) => (() => void);
|
|
24
|
+
dispose(): void;
|
|
25
|
+
private emit;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The QA Surface's view of the session-audit Remote namespace.
|
|
3
|
+
*
|
|
4
|
+
* Declared here, structurally, rather than imported from `@yadsh/dsh-session-audit`:
|
|
5
|
+
* a plugin may not depend on another plugin, and it does not need to. The
|
|
6
|
+
* namespace is a wire contract, and the surface simply asks whether it is
|
|
7
|
+
* there — when the audit plugin is not installed, `ctx.inject` never fires and
|
|
8
|
+
* the badge and the dialog are simply absent (SPEC §48).
|
|
9
|
+
*/
|
|
10
|
+
/** The cheap per-session summary the badge reads. */
|
|
11
|
+
export interface QaAuditSummary {
|
|
12
|
+
readonly available: boolean;
|
|
13
|
+
readonly auditId: string;
|
|
14
|
+
readonly sessionId: string;
|
|
15
|
+
readonly verdict: string;
|
|
16
|
+
readonly outcomeStatus: string;
|
|
17
|
+
readonly evidenceLevel: string;
|
|
18
|
+
readonly model: string;
|
|
19
|
+
readonly agentPreset: string;
|
|
20
|
+
readonly toolCalls: number;
|
|
21
|
+
readonly toolErrors: number;
|
|
22
|
+
readonly critical: number;
|
|
23
|
+
readonly major: number;
|
|
24
|
+
readonly minor: number;
|
|
25
|
+
readonly observation: number;
|
|
26
|
+
readonly other: number;
|
|
27
|
+
readonly schemaVersion: number;
|
|
28
|
+
readonly modifiedAt: string;
|
|
29
|
+
}
|
|
30
|
+
/** The full audit, as two documents and their summary. */
|
|
31
|
+
export interface QaSessionAudit {
|
|
32
|
+
readonly available: boolean;
|
|
33
|
+
readonly summary: QaAuditSummary;
|
|
34
|
+
readonly analysisJson: string;
|
|
35
|
+
readonly report: string;
|
|
36
|
+
}
|
|
37
|
+
/** A failed Remote result, narrowed to what the surface reports. */
|
|
38
|
+
interface RemoteFailure {
|
|
39
|
+
readonly ok: false;
|
|
40
|
+
readonly error: {
|
|
41
|
+
readonly code: string;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
type RemoteResult<T> = {
|
|
45
|
+
readonly ok: true;
|
|
46
|
+
readonly value: T;
|
|
47
|
+
} | RemoteFailure;
|
|
48
|
+
/** The `sessionAudit` namespace as the browser sees it. */
|
|
49
|
+
export interface QaAuditRemote {
|
|
50
|
+
summary(sessionId: string): Promise<RemoteResult<QaAuditSummary>>;
|
|
51
|
+
audit(sessionId: string): Promise<RemoteResult<QaSessionAudit>>;
|
|
52
|
+
}
|
|
53
|
+
/** The narrow surface the surface's components are handed. */
|
|
54
|
+
export interface QaAuditApi {
|
|
55
|
+
summary(sessionId: string): Promise<QaAuditSummary>;
|
|
56
|
+
audit(sessionId: string): Promise<QaSessionAudit>;
|
|
57
|
+
}
|
|
58
|
+
/** Build the facade over a mounted Remote namespace. */
|
|
59
|
+
export declare function createQaAuditApi(remote: QaAuditRemote): QaAuditApi;
|
|
60
|
+
/** The numbers the row badge shows, or `null` when there is no audit. */
|
|
61
|
+
export interface QaAuditMark {
|
|
62
|
+
readonly verdict: string;
|
|
63
|
+
readonly critical: number;
|
|
64
|
+
readonly major: number;
|
|
65
|
+
readonly minor: number;
|
|
66
|
+
readonly observation: number;
|
|
67
|
+
readonly other: number;
|
|
68
|
+
}
|
|
69
|
+
/** Reduce a summary to the mark a row shows. */
|
|
70
|
+
export declare function auditMark(summary: QaAuditSummary | undefined): QaAuditMark | null;
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=types.d.ts.map
|