@yadsh/dsh-qa-surface 0.7.4 → 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 +169 -12
- 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/model.js +24 -4
- package/lib/access/model.js.map +1 -1
- package/lib/access/role-repository.js +199 -91
- package/lib/access/role-repository.js.map +1 -1
- package/lib/access/service.js +223 -7
- package/lib/access/service.js.map +1 -1
- package/lib/account-remotes.js +2 -4
- package/lib/account-remotes.js.map +1 -1
- package/lib/accounts/database.js +447 -0
- package/lib/accounts/database.js.map +1 -0
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/file.js +27 -90
- package/lib/accounts/file.js.map +1 -1
- package/lib/accounts/store.js +224 -59
- 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 +270 -54
- package/lib/admin/quality-store.js.map +1 -1
- package/lib/admin/service.js +145 -7
- 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/cli.js +2 -1
- package/lib/cli.js.map +1 -1
- package/lib/client/QaSessionController.js +379 -39
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +94 -34
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaTranscriptAdapter.js +40 -0
- package/lib/client/QaTranscriptAdapter.js.map +1 -1
- package/lib/client/admin/QaAdmin.js +26 -8
- package/lib/client/admin/QaAdmin.js.map +1 -1
- package/lib/client/admin/{format.js → copy.js} +1 -1
- package/lib/client/admin/copy.js.map +1 -0
- package/lib/client/admin/pages/Conversations.js +34 -8
- package/lib/client/admin/pages/Conversations.js.map +1 -1
- package/lib/client/admin/pages/Overview.js +1 -1
- package/lib/client/admin/pages/Overview.js.map +1 -1
- package/lib/client/admin/pages/Quality.js +1 -1
- package/lib/client/admin/pages/Quality.js.map +1 -1
- package/lib/client/admin/pages/Review.js +1 -1
- package/lib/client/admin/pages/Review.js.map +1 -1
- package/lib/client/admin/pages/Users.js +6 -2
- package/lib/client/admin/pages/Users.js.map +1 -1
- package/lib/client/admin/shared.js +10 -1
- 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/Markdown.js +14 -206
- package/lib/client/components/Markdown.js.map +1 -1
- package/lib/client/components/QaChangelog.js +91 -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/QaHeader.js +1 -3
- package/lib/client/components/QaHeader.js.map +1 -1
- package/lib/client/components/QaMessage.js +25 -4
- 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 +17 -3
- package/lib/client/components/QaSidebar.js.map +1 -1
- package/lib/client/components/QaSourcesPanel.js +3 -18
- package/lib/client/components/QaSourcesPanel.js.map +1 -1
- package/lib/client/components/QaWorkGroup.js +4 -8
- package/lib/client/components/QaWorkGroup.js.map +1 -1
- package/lib/client/components/source-icon.js +26 -0
- package/lib/client/components/source-icon.js.map +1 -0
- package/lib/client/components/thinking-phrases.js +2 -11
- package/lib/client/components/thinking-phrases.js.map +1 -1
- package/lib/client/components/use-now.js +21 -0
- package/lib/client/components/use-now.js.map +1 -0
- package/lib/client/index.js +33 -5
- package/lib/client/index.js.map +1 -1
- package/lib/client/lineage.js +18 -0
- package/lib/client/lineage.js.map +1 -0
- package/lib/client/markdown/CodeBlock.js +28 -0
- package/lib/client/markdown/CodeBlock.js.map +1 -0
- package/lib/client/markdown/blocks.js +342 -0
- package/lib/client/markdown/blocks.js.map +1 -0
- package/lib/client/markdown/highlight.js +1089 -0
- package/lib/client/markdown/highlight.js.map +1 -0
- package/lib/client/markdown/inline.js +377 -0
- package/lib/client/markdown/inline.js.map +1 -0
- package/lib/client/markdown/render.js +147 -0
- package/lib/client/markdown/render.js.map +1 -0
- package/lib/client/markdown/source-chip.js +55 -0
- package/lib/client/markdown/source-chip.js.map +1 -0
- package/lib/client/markdown/use-transient-flag.js +27 -0
- package/lib/client/markdown/use-transient-flag.js.map +1 -0
- 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/role/RoleSelector.js +11 -2
- package/lib/client/role/RoleSelector.js.map +1 -1
- package/lib/client/role/preview.js +123 -0
- package/lib/client/role/preview.js.map +1 -0
- 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 +124 -20
- 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 +7615 -1567
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/accounts.js +15 -0
- package/lib/config-resolvers/accounts.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 +30 -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-resolvers/sources.js +16 -0
- package/lib/config-resolvers/sources.js.map +1 -1
- package/lib/config.js +118 -2
- package/lib/config.js.map +1 -1
- package/lib/index.js +183 -11
- package/lib/index.js.map +1 -1
- package/lib/lockdown-policy.js +19 -0
- package/lib/lockdown-policy.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 +25 -4
- package/lib/provenance/host-store.js.map +1 -1
- package/lib/provenance/retention.js +25 -0
- package/lib/provenance/retention.js.map +1 -0
- package/lib/provenance/snapshot-store.js +290 -35
- package/lib/provenance/snapshot-store.js.map +1 -1
- package/lib/questions.js +98 -38
- 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 +139 -21
- 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 +348 -56
- package/lib/typert.remote-client.d.ts +7 -1
- package/lib/typert.remote-client.js +274 -51
- package/lib/types/access/capability-catalog.d.ts +28 -1
- package/lib/types/access/role-repository.d.ts +38 -7
- package/lib/types/access/service.d.ts +106 -3
- package/lib/types/account-remotes.d.ts +8 -4
- package/lib/types/accounts/database.d.ts +84 -0
- package/lib/types/accounts/errors.d.ts +7 -1
- package/lib/types/accounts/file.d.ts +17 -39
- package/lib/types/accounts/store.d.ts +110 -19
- package/lib/types/admin/quality-store.d.ts +38 -2
- 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/{format.d.ts → copy.d.ts} +1 -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/Markdown.d.ts +7 -8
- 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 +11 -1
- package/lib/types/client/components/QaSourcesPanel.d.ts +1 -3
- package/lib/types/client/components/source-icon.d.ts +12 -0
- package/lib/types/client/components/use-now.d.ts +8 -0
- package/lib/types/client/lineage.d.ts +15 -0
- package/lib/types/client/markdown/CodeBlock.d.ts +14 -0
- package/lib/types/client/markdown/blocks.d.ts +74 -0
- package/lib/types/client/markdown/highlight.d.ts +29 -0
- package/lib/types/client/markdown/inline.d.ts +40 -0
- package/lib/types/client/markdown/render.d.ts +13 -0
- package/lib/types/client/markdown/source-chip.d.ts +32 -0
- package/lib/types/client/markdown/use-transient-flag.d.ts +12 -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/role/RoleSelector.d.ts +11 -1
- package/lib/types/client/role/preview.d.ts +109 -0
- 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 +83 -2
- package/lib/types/lockdown-policy.d.ts +16 -0
- package/lib/types/personal-skills/service.d.ts +5 -0
- package/lib/types/provenance/host-store.d.ts +20 -3
- package/lib/types/provenance/retention.d.ts +46 -0
- package/lib/types/provenance/snapshot-store.d.ts +63 -7
- package/lib/types/questions.d.ts +13 -0
- package/lib/types/secure-session.d.ts +27 -1
- 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 +254 -5
- package/package.json +9 -5
- package/scripts/attach-workspace-sessions.mjs +472 -0
- package/lib/client/admin/format.js.map +0 -1
|
@@ -20,6 +20,8 @@ export interface QaManualQueueEntry {
|
|
|
20
20
|
readonly createdAt: string;
|
|
21
21
|
}
|
|
22
22
|
export declare function defaultQualityFilePath(): string;
|
|
23
|
+
/** The pre-SQLite quality file, imported once on first use. */
|
|
24
|
+
export declare function defaultLegacyQualityFilePath(): string;
|
|
23
25
|
/**
|
|
24
26
|
* Atomic, externally reloadable store for the quality layer. Writes are
|
|
25
27
|
* synchronous and persisted with a temp file plus rename, matching the accounts
|
|
@@ -33,9 +35,11 @@ export declare function defaultQualityFilePath(): string;
|
|
|
33
35
|
*/
|
|
34
36
|
export declare class QaQualityStore {
|
|
35
37
|
readonly filePath: string;
|
|
38
|
+
private readonly storage;
|
|
36
39
|
private file;
|
|
37
|
-
private
|
|
40
|
+
private observedDataVersion;
|
|
38
41
|
constructor(filePath?: string);
|
|
42
|
+
close(): void;
|
|
39
43
|
/**
|
|
40
44
|
* Record or replace one user's rating of one message. Re-rating the same
|
|
41
45
|
* message overwrites in place rather than appending: a reviewer reads the
|
|
@@ -63,6 +67,24 @@ export declare class QaQualityStore {
|
|
|
63
67
|
/** Drop a manual queue entry once a reviewer has answered it. */
|
|
64
68
|
dequeueReview(conversationId: string, messageId?: string): boolean;
|
|
65
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;
|
|
66
88
|
/** Append one administrative action to the audit trail. */
|
|
67
89
|
appendAudit(input: {
|
|
68
90
|
readonly actorId: string;
|
|
@@ -75,8 +97,22 @@ export declare class QaQualityStore {
|
|
|
75
97
|
auditEvents(): readonly QaAdminAuditEvent[];
|
|
76
98
|
/** Serialize one before/after value, refusing what no reader could use. */
|
|
77
99
|
private snapshot;
|
|
100
|
+
/** Write one record, moving it to the end of its family's order. */
|
|
101
|
+
private upsertRow;
|
|
102
|
+
/** Append a record whose identity the store mints itself. */
|
|
103
|
+
private appendRow;
|
|
104
|
+
private deleteRow;
|
|
105
|
+
private applyCap;
|
|
106
|
+
private rowsOf;
|
|
107
|
+
private readDataVersion;
|
|
78
108
|
private reload;
|
|
79
109
|
private load;
|
|
80
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Import a pre-SQLite `qa-quality.json` exactly once, then rename it aside.
|
|
112
|
+
* A row the database already holds wins, so a leftover file cannot overwrite
|
|
113
|
+
* a verdict a person has since given.
|
|
114
|
+
*/
|
|
115
|
+
private importLegacyFile;
|
|
116
|
+
private assertImportArrived;
|
|
81
117
|
}
|
|
82
118
|
//# sourceMappingURL=quality-store.d.ts.map
|
|
@@ -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;
|
|
@@ -40,4 +40,4 @@ export declare function formatRelative(iso: string, now?: number): string;
|
|
|
40
40
|
/** Milliseconds as a short duration; tool timings are second-scale. */
|
|
41
41
|
export declare function formatDuration(ms: number | undefined): string;
|
|
42
42
|
export declare function formatCount(value: number): string;
|
|
43
|
-
//# sourceMappingURL=
|
|
43
|
+
//# sourceMappingURL=copy.d.ts.map
|
|
@@ -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
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { QaAuditApi, QaSessionAudit, QaAuditSummary } from "./types.js";
|
|
2
|
+
/** How often the chat list re-asks which chats have an audit. */
|
|
3
|
+
export declare const AUDIT_POLL_MS = 30000;
|
|
4
|
+
/**
|
|
5
|
+
* Poll the audit summary for every chat id.
|
|
6
|
+
*
|
|
7
|
+
* @param api - the Remote facade, or `null` when the audit plugin is absent.
|
|
8
|
+
* @param sessionIds - the chats currently listed.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useChatAudits(api: QaAuditApi | null, sessionIds: readonly string[]): ReadonlyMap<string, QaAuditSummary>;
|
|
11
|
+
/** The dialog's own load: one audit's documents, fetched when it opens. */
|
|
12
|
+
export interface QaAuditLoad {
|
|
13
|
+
readonly loading: boolean;
|
|
14
|
+
readonly audit: QaSessionAudit | null;
|
|
15
|
+
readonly error: string | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function useSessionAuditDocument(api: QaAuditApi | null, sessionId: string | null, open: boolean,
|
|
18
|
+
/** Reload key; the summary's `modifiedAt` changes exactly when bytes do. */
|
|
19
|
+
modifiedAt: string | null): QaAuditLoad;
|
|
20
|
+
//# sourceMappingURL=use-chat-audits.d.ts.map
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { QaSource } from "../../types.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export interface MarkdownSourceContext {
|
|
5
|
-
readonly refs?: QaSourceRefs;
|
|
6
|
-
/** Open a path-backed source in the sources drawer's detail view. */
|
|
7
|
-
readonly onSourceOpen?: (source: QaSource) => void;
|
|
8
|
-
}
|
|
2
|
+
import type { QaSourceRefs } from "./source-refs.js";
|
|
3
|
+
export type { MarkdownSourceContext } from "../markdown/source-chip.js";
|
|
9
4
|
/**
|
|
10
|
-
*
|
|
5
|
+
* Assistant-visible Markdown. The grammar lives in `../markdown/`: blocks are
|
|
6
|
+
* parsed once per text value, inline content is resolved per block, and a link
|
|
7
|
+
* or inline-code token that names a source the owning message knows about
|
|
8
|
+
* renders as a source chip instead of plain text.
|
|
9
|
+
*
|
|
11
10
|
* Memoized on the text value: stream updates re-render only the message whose
|
|
12
11
|
* text actually changed, so committed history is never re-parsed.
|
|
13
12
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { QaAttachmentDraft } from "../../types.js";
|
|
1
|
+
import type { QaAttachmentDraft, QaSlashView, ResolvedQaSlashCommands } from "../../types.js";
|
|
2
2
|
import { type QaAttachmentLimits } from "../attachments.js";
|
|
3
3
|
import type { QaQuickQuestion } from "../types.js";
|
|
4
4
|
export interface QaComposerProps {
|
|
@@ -13,8 +13,18 @@ export interface QaComposerProps {
|
|
|
13
13
|
readonly attachments: readonly QaAttachmentDraft[];
|
|
14
14
|
/** Deployment policy: accepted kinds, ceilings and the paste threshold. */
|
|
15
15
|
readonly limits: QaAttachmentLimits;
|
|
16
|
+
/** Slash catalog of this chat; inert while the master switch is off. */
|
|
17
|
+
readonly slash: QaSlashView;
|
|
18
|
+
readonly slashPolicy: ResolvedQaSlashCommands["palette"];
|
|
16
19
|
readonly onAttachmentsChange: (attachments: readonly QaAttachmentDraft[]) => void;
|
|
17
|
-
|
|
20
|
+
/**
|
|
21
|
+
* `pick` names the entry the user chose in the palette, while the draft
|
|
22
|
+
* still reads as its invocation. It is what disambiguates a skill and a
|
|
23
|
+
* command that share a name; `null` means the draft alone decides.
|
|
24
|
+
*/
|
|
25
|
+
readonly onSend: (text: string, attachments: readonly QaAttachmentDraft[], pick: string | null) => Promise<boolean>;
|
|
26
|
+
/** Called when the palette opens, so the caller can revalidate the catalog. */
|
|
27
|
+
readonly onSlashOpen: () => void;
|
|
18
28
|
readonly onStop: () => Promise<void>;
|
|
19
29
|
}
|
|
20
30
|
/**
|
|
@@ -3,6 +3,13 @@ export interface QaQuestionsProps {
|
|
|
3
3
|
readonly questions: readonly QaPendingQuestion[];
|
|
4
4
|
readonly onAnswer: (requestId: string, answers: readonly QaQuestionAnswerItem[]) => Promise<void>;
|
|
5
5
|
readonly onCancel: (requestId: string) => Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Stop the turn the questions belong to. The form takes the composer's
|
|
8
|
+
* place, so the run's own stop action moves here: an operator who does not
|
|
9
|
+
* want to answer must still be able to end the turn instead.
|
|
10
|
+
*/
|
|
11
|
+
readonly onStop?: () => Promise<void>;
|
|
12
|
+
readonly canStop?: boolean;
|
|
6
13
|
}
|
|
7
14
|
/**
|
|
8
15
|
* The questions a running turn waits on. Answers are the operator's own: the
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SessionSummary } from "@deepseek-ai/dsh-api-session-controller/client";
|
|
2
|
+
import { type QaAuditSummary } from "../audit/types.js";
|
|
2
3
|
/** One renderable row of the chat-history sidebar. */
|
|
3
4
|
export interface QaChatRow {
|
|
4
5
|
readonly id: string;
|
|
@@ -14,7 +15,9 @@ export interface QaChatRow {
|
|
|
14
15
|
* Project this browser's indexed chat ids onto the host session list, most
|
|
15
16
|
* recently updated first. Opening a chat is not an update: only the host's
|
|
16
17
|
* `updatedAt` (fresh messages) orders the list. Ids the host no longer lists
|
|
17
|
-
* are skipped (the controller prunes them on switch)
|
|
18
|
+
* are skipped (the controller prunes them on switch), and so is a delegated
|
|
19
|
+
* child: a subagent's session is not a chat, even when an ownership record
|
|
20
|
+
* from an older release still names it.
|
|
18
21
|
*/
|
|
19
22
|
export declare function buildChatRows(chatIds: readonly string[], byId: Readonly<Record<string, SessionSummary>>, activeId: string | null, ownerNameOf?: (sessionId: string) => string | undefined, now?: number): readonly QaChatRow[];
|
|
20
23
|
/** One per-owner section of the admin sidebar grouping. */
|
|
@@ -51,6 +54,13 @@ export interface QaSidebarProps {
|
|
|
51
54
|
readonly onNewChat: () => void;
|
|
52
55
|
/** Removes a chat from this browser's index; omit to hide the control. */
|
|
53
56
|
readonly onDelete?: (sessionId: string) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Audit summaries by chat id, for the row badge. Empty when the audit plugin
|
|
59
|
+
* is not installed — the badge is then absent rather than empty.
|
|
60
|
+
*/
|
|
61
|
+
readonly audits?: ReadonlyMap<string, QaAuditSummary>;
|
|
62
|
+
/** Opens the audit dialog for a chat; omit when audits are unavailable. */
|
|
63
|
+
readonly onAudit?: (sessionId: string) => void;
|
|
54
64
|
/** The signed-in account; omit when accounts are disabled. */
|
|
55
65
|
readonly account?: {
|
|
56
66
|
readonly email: string;
|