@newheap/platform-ai-chat 0.15.0 → 0.17.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 CHANGED
@@ -288,6 +288,19 @@ custom layouts. Opened in the panel, the thread offers its proposals to the same
288
288
  **Decided by** shows the name from the subject's member snapshot (`decidedByDisplayName`)
289
289
  and falls back to the actor id.
290
290
 
291
+ The inbox also gives an overview. `divisionId` and `runId` filter it like `agentId` and
292
+ `subjectType`; `[grouped]="true"` groups the proposals by the parent the server recorded for each
293
+ proposal's subject (such as a project for its tasks) and by subject, `[groupByRun]="true"` also by
294
+ run. A group says how many of its proposals the page shows and whether it continues on another page,
295
+ and "Select group" selects only the shown proposals the person may decide. Proposals made since the
296
+ person's last visit of the inbox are marked new, and showing the inbox records the visit (`markNew`
297
+ and `recordVisit`, both on by default; turn `recordVisit` off for an inbox that shows only part of
298
+ it). `nh-assistant-run-result` lets its reader decide the run's proposals together.
299
+
300
+ ```html
301
+ <nh-assistant-agent-inbox [grouped]="true" [groupByRun]="true" [divisionId]="activeDivisionId" />
302
+ ```
303
+
291
304
  Subjects show the name of their type (`subjectTypeName`, such as "Project") and link to where
292
305
  the application shows them (`subjectLink`, from the server's `AddSubjectType(...).OpenAt(...)`).
293
306
  A link within the application navigates through the router; an `https` link leaves it. Replace
package/admin/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { OnInit } from '@angular/core';
3
3
  import * as _newheap_platform_ai_chat from '@newheap/platform-ai-chat';
4
- import { NhAssistantStore, NhAssistantError, ApplicationContext, ApplicationContextVersion, AdminAgent, ToolCatalogEntry, McpServer, RunCatalog, SetAgentStateRequest, AgentShadowMode, AgentSkillState, AgentShadowState, AssistantAutonomy, AgentEvaluation, AgentReplay, AgentEvaluationCost, AgentProposalFeedbackCategory, AgentFeedbackSummaryRow, AgentFeedbackItem, AgentFeedbackCategoryCount, StaleKind, AgentProposalFeedbackGroup, AgentSubjectType, AgentRunStatus, ɵnhAssistantCodeKeys as _nhAssistantCodeKeys, AgentRunHistoryItem, DataSkill, AgentRunConfiguration, DataTrigger, SkillComparison, DataSkillVersion, ɵNhAssistantPickerOption as _NhAssistantPickerOption, McpServerTestResult, McpConnectionsSummary, McpBuiltInAuthMode, McpCustomAuthMode, McpAuthMode, McpTransport, McpConnectionScope, McpHeadlessUse, McpDiscovery, McpToolEffect, McpTool } from '@newheap/platform-ai-chat';
4
+ import { NhAssistantStore, NhAssistantError, ApplicationContext, ApplicationContextVersion, AdminAgent, ToolCatalogEntry, McpServer, RunCatalog, SetAgentStateRequest, AgentSkillState, AgentShadowMode, AgentShadowState, AssistantAutonomy, AssistantDataClassification, AgentEvaluation, AgentReplay, AgentEvaluationCost, AgentProposalFeedbackCategory, AgentFeedbackSummaryRow, AgentFeedbackItem, AgentFeedbackCategoryCount, StaleKind, AgentProposalFeedbackGroup, AgentSubjectType, AgentRunStatus, ɵnhAssistantCodeKeys as _nhAssistantCodeKeys, AgentRunHistoryItem, DataSkill, AgentRunConfiguration, DataTrigger, SkillComparison, DataSkillVersion, ɵNhAssistantPickerOption as _NhAssistantPickerOption, McpServerTestResult, McpConnectionsSummary, McpBuiltInAuthMode, McpCustomAuthMode, McpAuthMode, McpTransport, McpConnectionScope, McpHeadlessUse, McpDiscovery, McpTool, McpToolEffect } from '@newheap/platform-ai-chat';
5
5
  import { ɵNhAssistantRunNowAgent as _NhAssistantRunNowAgent } from '@newheap/platform-ai-chat/agent-runs';
6
6
 
7
7
  type NhAssistantAdminTab = 'context' | 'agents' | 'mcp-servers';
@@ -127,6 +127,11 @@ declare function skillNameKeys(agentId: string, skillId: string): string[];
127
127
  * themselves in the language triage reads; the screen shows a translation when there is one.
128
128
  */
129
129
  declare function skillDescriptionKeys(agentId: string, skillId: string): string[];
130
+ /**
131
+ * The key of a warning about an agent or a skill that is saved and in effect but may not work as
132
+ * configured, such as `classification-not-permitted`; a code the screen does not know shows as sent.
133
+ */
134
+ declare function warningKeys(kind: 'agent' | 'skill', code: string): string[];
130
135
  /** The key an application may translate an authorization policy's name with. */
131
136
  declare function policyKeys(policy: string | null | undefined): string[];
132
137
  /** A readable name for a dash-case id: `task-follow-up` reads "Task follow up". */
@@ -149,9 +154,17 @@ interface WorksOnSummary {
149
154
  }
150
155
 
151
156
  type AgentStateAction = SetAgentStateRequest['state'];
157
+ /** A state change being entered, of the agent or one of its skills, with the state it changes from. */
158
+ interface StateChange {
159
+ agentId: string;
160
+ skillId?: string;
161
+ state: AgentStateAction;
162
+ from: AdminAgent['runState'] | AgentSkillState['runState'];
163
+ }
152
164
  /**
153
165
  * Agent administration: code agents (override, reset) and agents created here (edit, delete),
154
- * and for every agent its run state with pause, stop and resume, its shadow mode and that of each
166
+ * and for every agent and skill its run state with pause, switch off, stop and resume (switch on
167
+ * for one that is off), its shadow mode and that of each
155
168
  * skill, and the technical account of an agent that answers to one, each with an optional reason.
156
169
  * Editing opens `nh-assistant-admin-agent-editor`; the feedback action opens
157
170
  * `nh-assistant-agent-feedback-report` for the agent, the evaluation action of an agent with
@@ -214,11 +227,7 @@ declare class NhAssistantAdminAgentsComponent {
214
227
  } | null>;
215
228
  readonly busyAgentId: _angular_core.WritableSignal<string | null>;
216
229
  /** The state change whose reason is being entered, of the agent or one of its skills. */
217
- readonly changingState: _angular_core.WritableSignal<{
218
- agentId: string;
219
- skillId?: string;
220
- state: AgentStateAction;
221
- } | null>;
230
+ readonly changingState: _angular_core.WritableSignal<StateChange | null>;
222
231
  /** The shadow mode change whose reason is being entered, of the agent or one of its skills. */
223
232
  readonly changingShadow: _angular_core.WritableSignal<{
224
233
  agentId: string;
@@ -258,6 +267,7 @@ declare class NhAssistantAdminAgentsComponent {
258
267
  readonly errorKeys: _angular_core.Signal<string[]>;
259
268
  readonly codeTextKeys: typeof codeTextKeys;
260
269
  readonly skillNameKeys: typeof skillNameKeys;
270
+ readonly warningKeys: typeof warningKeys;
261
271
  readonly skillDescriptionKeys: typeof skillDescriptionKeys;
262
272
  readonly policyKeys: typeof policyKeys;
263
273
  readonly readableId: typeof readableId;
@@ -280,8 +290,8 @@ declare class NhAssistantAdminAgentsComponent {
280
290
  hasRunConfiguration(agent: AdminAgent): boolean;
281
291
  /**
282
292
  * Whether the agent can be run now: it runs on its own, so it has a run configuration, it is
283
- * neither stopped nor disabled in code, and the run catalog names what it can run on. The server
284
- * decides the rest when the run starts.
293
+ * neither stopped nor disabled in code, and the run catalog names what it can run on. An agent
294
+ * that is off still runs for a person. The server decides the rest when the run starts.
285
295
  */
286
296
  canRunNow(agent: AdminAgent): boolean;
287
297
  /** Opens the run-now dialog of the agent. */
@@ -332,6 +342,13 @@ declare class NhAssistantAdminAgentsComponent {
332
342
  stateActions(agent: AdminAgent): AgentStateAction[];
333
343
  /** The state changes a skill allows. */
334
344
  skillActions(skill: AgentSkillState): AgentStateAction[];
345
+ /**
346
+ * The key of a state change's label, explanation or confirmation: making an agent or skill that is
347
+ * off active again switches it on, which replays nothing, unlike a resume.
348
+ */
349
+ stateKey(part: 'action' | 'explain' | 'confirm', from: string, action: AgentStateAction): string;
350
+ /** The explanation of a state change of one skill. */
351
+ skillStateExplainKey(change: StateChange): string;
335
352
  /** Opens the reason form of a state change of the agent or, with a skill, of that skill. */
336
353
  askState(agent: AdminAgent, state: AgentStateAction, skill?: AgentSkillState): void;
337
354
  /**
@@ -435,6 +452,7 @@ declare class NhAssistantAdminAgentEditorComponent {
435
452
  readonly id: string;
436
453
  readonly max = 20000;
437
454
  readonly autonomyLevels: readonly AssistantAutonomy[];
455
+ readonly classifications: readonly AssistantDataClassification[];
438
456
  readonly agentId: _angular_core.WritableSignal<string>;
439
457
  readonly displayName: _angular_core.WritableSignal<string>;
440
458
  readonly description: _angular_core.WritableSignal<string>;
@@ -442,6 +460,12 @@ declare class NhAssistantAdminAgentEditorComponent {
442
460
  readonly autonomy: _angular_core.WritableSignal<AssistantAutonomy>;
443
461
  /** How the agent is used: in the chat, on its own, or both. */
444
462
  readonly use: _angular_core.WritableSignal<AgentUse>;
463
+ /** A new agent takes its triggers at once; without it, it starts off until someone switches it on. */
464
+ readonly switchOnNow: _angular_core.WritableSignal<boolean>;
465
+ /** The model profile of an agent created here; empty uses the application's chat profile. */
466
+ readonly profile: _angular_core.WritableSignal<string>;
467
+ /** The classification of the model calls of an agent created here; `internal` when it has none. */
468
+ readonly dataClassification: _angular_core.WritableSignal<AssistantDataClassification>;
445
469
  readonly requiredPolicy: _angular_core.WritableSignal<string>;
446
470
  readonly toolSelectors: _angular_core.WritableSignal<string[]>;
447
471
  readonly mcpServerIds: _angular_core.WritableSignal<string[]>;
@@ -498,10 +522,17 @@ declare class NhAssistantAdminAgentEditorComponent {
498
522
  readonly knownTypes: _angular_core.Signal<string[]>;
499
523
  /** What the agent works on is edited here: an agent created here, while the run catalog is known. */
500
524
  readonly editsWorksOn: _angular_core.Signal<boolean>;
525
+ /** An agent created here chooses its profile from those the run catalog offers. */
526
+ readonly choosesProfile: _angular_core.Signal<boolean>;
527
+ /** The profiles the run catalog offers, and the agent's own when the catalog no longer lists it. */
528
+ readonly profileChoices: _angular_core.Signal<string[]>;
501
529
  /** Chosen object types without a type, and not the application either: the agent would work on nothing. */
502
530
  readonly worksOnMissing: _angular_core.Signal<boolean>;
503
531
  readonly tooManyTypes: _angular_core.Signal<boolean>;
504
532
  readonly policyKeys: typeof policyKeys;
533
+ readonly warningKeys: typeof warningKeys;
534
+ /** The warnings of the agent as it was saved, until this editor saves it again. */
535
+ readonly warnings: _angular_core.Signal<_newheap_platform_ai_chat.AssistantConfigurationWarning[]>;
505
536
  readonly valid: _angular_core.Signal<boolean>;
506
537
  readonly errorKeys: _angular_core.Signal<string[]>;
507
538
  readonly filteredTools: _angular_core.Signal<ToolCatalogEntry[]>;
@@ -845,6 +876,7 @@ declare class NhAssistantAgentRunConfigurationComponent implements OnInit {
845
876
  readonly id: string;
846
877
  readonly maxReason: 500;
847
878
  readonly skillNameKeys: typeof skillNameKeys;
879
+ readonly warningKeys: typeof warningKeys;
848
880
  readonly skillDescriptionKeys: typeof skillDescriptionKeys;
849
881
  readonly readableId: typeof readableId;
850
882
  readonly loading: _angular_core.WritableSignal<boolean>;
@@ -855,6 +887,8 @@ declare class NhAssistantAgentRunConfigurationComponent implements OnInit {
855
887
  readonly error: _angular_core.WritableSignal<NhAssistantError | null>;
856
888
  readonly errorKeys: _angular_core.Signal<string[]>;
857
889
  readonly saved: _angular_core.WritableSignal<string | null>;
890
+ /** The warnings of the skill that was just saved, shown with the saved message. */
891
+ readonly savedWarnings: _angular_core.WritableSignal<readonly string[]>;
858
892
  readonly form: _angular_core.WritableSignal<Form | null>;
859
893
  readonly confirming: _angular_core.WritableSignal<Confirmation | null>;
860
894
  readonly reason: _angular_core.WritableSignal<string>;
@@ -1036,12 +1070,35 @@ declare class NhAssistantAdminMcpServersComponent {
1036
1070
  type NhAssistantSecretAction = 'keep' | 'replace' | 'clear';
1037
1071
  /** Where the secret is: stored here, encrypted, or a reference to a secret of the application. */
1038
1072
  type NhAssistantSecretSource = 'stored' | 'reference';
1073
+ /**
1074
+ * One reader as the editor shows it: the tool, the media types as typed (separated by commas, spaces
1075
+ * or new lines), the highest classification and the priority as typed. `key` keeps a row's controls
1076
+ * when another row is removed.
1077
+ */
1078
+ interface NhAssistantReaderDraft {
1079
+ key: number;
1080
+ toolName: string;
1081
+ mediaTypes: string;
1082
+ maxClassification: AssistantDataClassification | '';
1083
+ priority: string;
1084
+ }
1085
+ /** What is wrong with one reader before it is saved. */
1086
+ interface ReaderProblems {
1087
+ types: boolean;
1088
+ tool: boolean;
1089
+ duplicate: boolean;
1090
+ classification: boolean;
1091
+ priority: boolean;
1092
+ }
1039
1093
  /**
1040
1094
  * Creates or edits one MCP server: the authentication with a write-only secret or a reference to
1041
1095
  * one, OAuth with discovery the administrator confirms, an optional client certificate, the
1042
- * transport and the use in background runs. Every field stops at the length the server accepts; a
1043
- * refused save shows each of the server's field errors at its field, for example a secret reference
1044
- * the application cannot resolve (`not-found`), and moves the focus to the first of them.
1096
+ * transport, the use in background runs and, for a server that exists, its readers: per reader the
1097
+ * synced tool that turns files into text, the media types it reads, the highest classification that
1098
+ * may be sent to it and its priority, with readers to add and remove. Every field stops at the length
1099
+ * the server accepts; a refused save shows each of the server's field errors at its field, those of a
1100
+ * reader at that reader (`readers[0].toolName`), for example a secret reference the application cannot
1101
+ * resolve (`not-found`), and moves the focus to the first of them.
1045
1102
  */
1046
1103
  declare class NhAssistantAdminMcpServerEditorComponent {
1047
1104
  private readonly admin;
@@ -1050,6 +1107,7 @@ declare class NhAssistantAdminMcpServerEditorComponent {
1050
1107
  private subscription?;
1051
1108
  private discoverySubscription?;
1052
1109
  private modesSubscription?;
1110
+ private toolsSubscription?;
1053
1111
  /** Fields whose server error the administrator changed since the refused save. */
1054
1112
  private readonly touched;
1055
1113
  /** The server to edit, or null for a new server. */
@@ -1080,6 +1138,7 @@ declare class NhAssistantAdminMcpServerEditorComponent {
1080
1138
  readonly transports: readonly McpTransport[];
1081
1139
  readonly secretSources: readonly NhAssistantSecretSource[];
1082
1140
  readonly connectionScopes: readonly McpConnectionScope[];
1141
+ readonly classifications: readonly AssistantDataClassification[];
1083
1142
  readonly serverId: _angular_core.WritableSignal<string>;
1084
1143
  readonly displayName: _angular_core.WritableSignal<string>;
1085
1144
  readonly url: _angular_core.WritableSignal<string>;
@@ -1110,6 +1169,15 @@ declare class NhAssistantAdminMcpServerEditorComponent {
1110
1169
  readonly discovering: _angular_core.WritableSignal<boolean>;
1111
1170
  readonly discoveryError: _angular_core.WritableSignal<NhAssistantError | null>;
1112
1171
  readonly confirmAuthorization: _angular_core.WritableSignal<boolean>;
1172
+ /** The readers of the server as the editor shows them, in their order. */
1173
+ readonly readers: _angular_core.WritableSignal<readonly NhAssistantReaderDraft[]>;
1174
+ readonly maxReaders = 16;
1175
+ readonly readerPriority: {
1176
+ readonly min: -1000;
1177
+ readonly max: 1000;
1178
+ };
1179
+ /** The server's synced tools, which can read files; empty until they are loaded. */
1180
+ readonly readerTools: _angular_core.WritableSignal<readonly McpTool[]>;
1113
1181
  readonly submitted: _angular_core.WritableSignal<boolean>;
1114
1182
  readonly saving: _angular_core.WritableSignal<boolean>;
1115
1183
  readonly error: _angular_core.WritableSignal<NhAssistantError | null>;
@@ -1161,6 +1229,13 @@ declare class NhAssistantAdminMcpServerEditorComponent {
1161
1229
  readonly certificateInvalid: _angular_core.Signal<boolean>;
1162
1230
  readonly oauthInvalid: _angular_core.Signal<boolean>;
1163
1231
  readonly headerNameInvalid: _angular_core.Signal<boolean>;
1232
+ /** The tool names to choose from, keeping the stored tools the list no longer holds selectable. */
1233
+ readonly readerToolNames: _angular_core.Signal<string[]>;
1234
+ /** What is wrong with each reader, in the order of `readers`. */
1235
+ readonly readerProblems: _angular_core.Signal<readonly ReaderProblems[]>;
1236
+ /** Why a reader can or cannot be added: the server's tools are not synced, or it has the most. */
1237
+ readonly readerAddHint: _angular_core.Signal<"nh-assistant.admin.server-editor.reader.tool-sync" | "nh-assistant.admin.server-editor.reader.limit" | "nh-assistant.admin.server-editor.reader.add-hint">;
1238
+ readonly readerInvalid: _angular_core.Signal<boolean>;
1164
1239
  readonly valid: _angular_core.Signal<boolean>;
1165
1240
  readonly errorKeys: _angular_core.Signal<string[]>;
1166
1241
  /** The server's first error per field of the refused save, until the administrator changes the field. */
@@ -1179,6 +1254,17 @@ declare class NhAssistantAdminMcpServerEditorComponent {
1179
1254
  serverErrorKeys(field: string): string[];
1180
1255
  /** The id of a field's error, for `aria-describedby`. */
1181
1256
  errorId(field: string): string;
1257
+ /** The name of a reader's field in the server's errors, such as `readers[0].toolName`. */
1258
+ readerField(index: number, field: 'mediaTypes' | 'toolName' | 'maxClassification' | 'priority'): string;
1259
+ /** Adds an empty reader at the end, at priority 0, and moves the focus to its tool. */
1260
+ addReader(): void;
1261
+ /**
1262
+ * Removes a reader and moves the focus to the button that adds one; the server's errors of the
1263
+ * readers no longer match their positions.
1264
+ */
1265
+ removeReader(index: number): void;
1266
+ /** Changes one field of a reader as the administrator typed or chose it. */
1267
+ updateReader(index: number, field: 'toolName' | 'mediaTypes' | 'maxClassification' | 'priority', value: string): void;
1182
1268
  /** The ids a control describes itself with: its hint and, while the server refused it, its error. */
1183
1269
  describedBy(hintId: string | null, field: string): string | null;
1184
1270
  /** The administrator changed a field; its server error no longer applies. */
@@ -1195,8 +1281,15 @@ declare class NhAssistantAdminMcpServerEditorComponent {
1195
1281
  discover(): void;
1196
1282
  save(): void;
1197
1283
  private focusFirstInvalid;
1284
+ private focusById;
1198
1285
  private valueKeys;
1286
+ /** Whether the editor shows a field error at a reader's own field. */
1287
+ private showsReaderField;
1288
+ /** The server's errors of the readers no longer apply once a reader is added or removed. */
1289
+ private forgetReaderErrors;
1199
1290
  private reset;
1291
+ /** The synced tools of an existing server, to choose the reading tool from. */
1292
+ private loadReaderTools;
1200
1293
  /**
1201
1294
  * The OAuth settings as the editor shows them: every value is sent, so an emptied field clears the
1202
1295
  * stored value. The client secret is write-only: sent only when replaced.
@@ -1251,4 +1344,4 @@ declare class NhAssistantAdminMcpToolsComponent {
1251
1344
  }
1252
1345
 
1253
1346
  export { NH_ASSISTANT_MAX_INSTRUCTIONS, NhAssistantAdminAgentEditorComponent, NhAssistantAdminAgentsComponent, NhAssistantAdminComponent, NhAssistantAdminContextComponent, NhAssistantAdminMcpServerEditorComponent, NhAssistantAdminMcpServersComponent, NhAssistantAdminMcpToolsComponent, NhAssistantAgentEvaluationComponent, NhAssistantAgentFeedbackReportComponent, NhAssistantAgentRunConfigurationComponent, NhAssistantAgentRunHistoryComponent, nhAssistantSelectorMatches };
1254
- export type { AgentUse, NhAssistantAdminTab, NhAssistantEvaluationPeriod, NhAssistantFeedbackPeriod, NhAssistantSecretAction, NhAssistantSecretSource, WorksOnScope };
1347
+ export type { AgentUse, NhAssistantAdminTab, NhAssistantEvaluationPeriod, NhAssistantFeedbackPeriod, NhAssistantReaderDraft, NhAssistantSecretAction, NhAssistantSecretSource, WorksOnScope };
@@ -1,6 +1,6 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import * as _newheap_platform_ai_chat from '@newheap/platform-ai-chat';
3
- import { AgentProposal, AgentThreadLookup, AgentTriggerReceipt, NhAssistantError, AgentProposalDecisionRight, AgentProposalFeedback, AgentProposalOrigin, AgentProposalDecision, AgentExecutionResolution, AgentSubjectRole, AgentRun, ɵnhAssistantCodeKeys as _nhAssistantCodeKeys, AgentRunRetryMode, AgentThreadMemory, AgentArtifact, AgentConsultation, AgentSubjectWork, AgentSubjectWorkAgent, AgentSubjectType, ɵNhAssistantPickerOption as _NhAssistantPickerOption, NhAssistantAgentRunApiService, AgentObjectAgents, AgentObjectAgent, AgentRunResult, AgentBoard, AgentBoardAgent } from '@newheap/platform-ai-chat';
3
+ import { AgentProposal, AgentInboxGroup, AgentThreadLookup, AgentTriggerReceipt, NhAssistantError, AgentProposalDecisionRight, AgentProposalFeedback, AgentProposalOrigin, AgentProposalDecision, AgentExecutionResolution, AgentSubjectRole, AgentRun, ɵnhAssistantCodeKeys as _nhAssistantCodeKeys, AgentRunRetryMode, AgentThreadMemory, AgentArtifact, AgentConsultation, AgentSubjectWork, AgentSubjectWorkAgent, AgentSubjectType, ɵNhAssistantPickerOption as _NhAssistantPickerOption, NhAssistantAgentRunApiService, AgentObjectAgents, AgentObjectAgent, AgentRunResult, AgentBoard, AgentBoardAgent } from '@newheap/platform-ai-chat';
4
4
  import { Observable } from 'rxjs';
5
5
 
6
6
  /**
@@ -14,15 +14,49 @@ import { Observable } from 'rxjs';
14
14
  * longer fits, for example because someone did the work by hand, stays as a closed card with the
15
15
  * reason until it is dismissed. A proposal a run placed at its object from another subject, such as a
16
16
  * run for the whole application, names that run; `openConversation` emits its conversation.
17
+ *
18
+ * `agentId`, `subjectType`, `divisionId` and `runId` filter the inbox; changing a filter, or `grouped`,
19
+ * reloads it from the first page. With `grouped` the inbox shows the proposals per parent, such as a
20
+ * project with its own proposals and those of its tasks, and per subject, optionally per run
21
+ * (`groupByRun`); a group that goes on on another page says so, and "Select group" selects only its
22
+ * proposals shown here. With `markNew` (on by default) it marks the proposals made since the person's
23
+ * last visit of the inbox in its scope, the whole application or the division of `divisionId`, and
24
+ * those that arrive while it is shown; with `recordVisit` (on by default) showing it records the
25
+ * visit. Turn `recordVisit` off for an inbox that shows only part of the scope, such as one agent's
26
+ * proposals, so the person's next visit of the whole inbox still marks what they have not seen.
17
27
  */
18
28
  declare class NhAssistantAgentInboxComponent {
19
29
  private readonly api;
20
30
  private readonly proposalList;
21
31
  private subscription?;
32
+ private visitSubscription?;
33
+ /** The scope whose visit this view recorded; the visit is recorded once per scope shown. */
34
+ private visited;
35
+ /**
36
+ * What the first read of the shown scope found: the visit before this one and the proposals that
37
+ * were new since. Later reads, after live updates, paging or a decision, compare with both, so what
38
+ * was new when the inbox was opened stays new while it is shown.
39
+ */
40
+ private opened;
22
41
  /** Limits the inbox to one agent. */
23
42
  readonly agentId: _angular_core.InputSignal<string | undefined>;
24
43
  /** Limits the inbox to one kind of subject, for example `project`. */
25
44
  readonly subjectType: _angular_core.InputSignal<string | undefined>;
45
+ /**
46
+ * Limits the inbox to the subjects of one division, for example the active division; its visits are
47
+ * then those of that division.
48
+ */
49
+ readonly divisionId: _angular_core.InputSignal<string | null | undefined>;
50
+ /** Limits the inbox to the proposals of one run. */
51
+ readonly runId: _angular_core.InputSignal<string | null | undefined>;
52
+ /** Groups the proposals per parent and subject instead of listing them by expiry alone. */
53
+ readonly grouped: _angular_core.InputSignal<boolean>;
54
+ /** In a grouped inbox, also shows a header per run within a subject. */
55
+ readonly groupByRun: _angular_core.InputSignal<boolean>;
56
+ /** Marks the proposals made since the person's last visit of the inbox, and those that arrive while it is shown. */
57
+ readonly markNew: _angular_core.InputSignal<boolean>;
58
+ /** Records the person's visit of the inbox in its scope when it is shown. */
59
+ readonly recordVisit: _angular_core.InputSignal<boolean>;
26
60
  readonly itemsPerPage: _angular_core.InputSignal<number>;
27
61
  /**
28
62
  * Emits the conversation of the run that placed a proposal at its object from another subject, so
@@ -36,6 +70,15 @@ declare class NhAssistantAgentInboxComponent {
36
70
  readonly loadFailed: _angular_core.WritableSignal<boolean>;
37
71
  readonly items: _angular_core.WritableSignal<AgentProposal[]>;
38
72
  readonly total: _angular_core.WritableSignal<number>;
73
+ /** The groups of the page in a grouped inbox; `null` for the flat inbox. */
74
+ readonly groups: _angular_core.WritableSignal<AgentInboxGroup[] | null>;
75
+ /** The proposals of the page marked as new. */
76
+ readonly newIds: _angular_core.WritableSignal<ReadonlySet<string>>;
77
+ /**
78
+ * The person's visit of the shown scope before the inbox was opened: `null` before their first
79
+ * visit, `undefined` while unknown or when new proposals are not marked.
80
+ */
81
+ readonly previousVisit: _angular_core.WritableSignal<string | null | undefined>;
39
82
  readonly pages: _angular_core.Signal<number>;
40
83
  constructor();
41
84
  load(): void;
@@ -47,8 +90,19 @@ declare class NhAssistantAgentInboxComponent {
47
90
  */
48
91
  private refresh;
49
92
  private fetch;
93
+ /**
94
+ * Marks what is new: what the server marks since the visit this view recorded, and what was made
95
+ * after the person's visit before the inbox was opened, on any page. Before the first visit
96
+ * everything is new. A server without visits marks nothing.
97
+ */
98
+ private markNewOf;
99
+ /**
100
+ * Records the visit of the shown scope after its first read, so that read still marks what arrived
101
+ * since the visit before.
102
+ */
103
+ private recordVisitOf;
50
104
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantAgentInboxComponent, never>;
51
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentInboxComponent, "nh-assistant-agent-inbox", never, { "agentId": { "alias": "agentId"; "required": false; "isSignal": true; }; "subjectType": { "alias": "subjectType"; "required": false; "isSignal": true; }; "itemsPerPage": { "alias": "itemsPerPage"; "required": false; "isSignal": true; }; }, { "openConversation": "openConversation"; }, never, never, true, never>;
105
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentInboxComponent, "nh-assistant-agent-inbox", never, { "agentId": { "alias": "agentId"; "required": false; "isSignal": true; }; "subjectType": { "alias": "subjectType"; "required": false; "isSignal": true; }; "divisionId": { "alias": "divisionId"; "required": false; "isSignal": true; }; "runId": { "alias": "runId"; "required": false; "isSignal": true; }; "grouped": { "alias": "grouped"; "required": false; "isSignal": true; }; "groupByRun": { "alias": "groupByRun"; "required": false; "isSignal": true; }; "markNew": { "alias": "markNew"; "required": false; "isSignal": true; }; "recordVisit": { "alias": "recordVisit"; "required": false; "isSignal": true; }; "itemsPerPage": { "alias": "itemsPerPage"; "required": false; "isSignal": true; }; }, { "openConversation": "openConversation"; }, never, never, true, never>;
52
106
  }
53
107
 
54
108
  type NhAssistantAgentThreadTab = 'proposals' | 'runs' | 'consultations' | 'memory' | 'artifacts';
@@ -109,6 +163,45 @@ declare class NhAssistantAgentThreadViewComponent {
109
163
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentThreadViewComponent, "nh-assistant-agent-thread-view", never, { "agentId": { "alias": "agentId"; "required": true; "isSignal": true; }; "subjectType": { "alias": "subjectType"; "required": true; "isSignal": true; }; "subjectId": { "alias": "subjectId"; "required": true; "isSignal": true; }; }, { "openConversation": "openConversation"; }, never, never, true, never>;
110
164
  }
111
165
 
166
+ /** The proposals of one run within a subject of a grouped list, in the order the list gave them. */
167
+ interface NhAssistantRunSection {
168
+ key: string;
169
+ runId: string | null;
170
+ agentId: string;
171
+ /** When the run's first proposal on the page was made. */
172
+ proposedAt: string;
173
+ items: AgentProposal[];
174
+ }
175
+ /** One subject within a group of a grouped list. */
176
+ interface NhAssistantSubjectSection {
177
+ key: string;
178
+ subjectType: string;
179
+ subjectId: string;
180
+ label: string;
181
+ typeName: string | null;
182
+ link: string | null;
183
+ /** The group's own subject, whose proposals stand directly under the group's header. */
184
+ own: boolean;
185
+ count: number;
186
+ total: number;
187
+ runs: NhAssistantRunSection[];
188
+ }
189
+ /** One group of a grouped list, such as a parent subject of the grouped inbox. */
190
+ interface NhAssistantGroupSection {
191
+ key: string;
192
+ subjectType: string;
193
+ subjectId: string;
194
+ label: string;
195
+ typeName: string | null;
196
+ link: string | null;
197
+ count: number;
198
+ total: number;
199
+ continuesFromPreviousPage: boolean;
200
+ continuesOnNextPage: boolean;
201
+ subjects: NhAssistantSubjectSection[];
202
+ /** The group's pending proposals on this page that the caller may decide: what "Select group" selects. */
203
+ selectableIds: string[];
204
+ }
112
205
  /** A feedback question: after a rejection above the list, or from a card's own action. */
113
206
  interface NhAssistantFeedbackRequest {
114
207
  approvalIds: string[];
@@ -132,7 +225,10 @@ interface NhAssistantFeedbackRequest {
132
225
  * replaced, as a closed card when it closes while shown, or when an approval is refused because of
133
226
  * it, until the person dismisses it. It reads those proposals by id with one lookup, never through
134
227
  * their threads. A proposal that a run placed here from another subject, such as a run for the whole
135
- * application, says so and offers that run's conversation through `openConversation`.
228
+ * application, says so and offers that run's conversation through `openConversation`. With `groups`
229
+ * from the grouped inbox the list shows a header per group and per subject, optionally per run
230
+ * (`groupByRun`), and "Select group" selects only the group's pending proposals in this list that
231
+ * the caller may decide, never those on another page. `newIds` marks proposals as new.
136
232
  */
137
233
  declare class NhAssistantAgentProposalsComponent {
138
234
  private readonly api;
@@ -154,6 +250,16 @@ declare class NhAssistantAgentProposalsComponent {
154
250
  * it closes.
155
251
  */
156
252
  readonly holdClosedCards: _angular_core.InputSignal<boolean>;
253
+ /**
254
+ * The groups of the grouped inbox (`AgentInbox.groups`) for `proposals` in the order the inbox gave
255
+ * them: the first `count` proposals belong to the first group, and so on. Without groups, or when
256
+ * they do not describe `proposals`, the list is flat.
257
+ */
258
+ readonly groups: _angular_core.InputSignal<readonly AgentInboxGroup[] | null>;
259
+ /** Shows a header per run within a subject of a grouped list. */
260
+ readonly groupByRun: _angular_core.InputSignal<boolean>;
261
+ /** Proposals to mark as new, by approval id, for example those made since the last visit of the inbox. */
262
+ readonly newIds: _angular_core.InputSignal<ReadonlySet<string> | null>;
157
263
  /** Emits after a proposal or its feedback changed, so the host reloads its list. */
158
264
  readonly changed: _angular_core.OutputEmitterRef<void>;
159
265
  /**
@@ -175,6 +281,11 @@ declare class NhAssistantAgentProposalsComponent {
175
281
  /** The held closed cards first, then the proposals the host gave. */
176
282
  readonly shown: _angular_core.Signal<AgentProposal[]>;
177
283
  private readonly lookups;
284
+ /**
285
+ * The grouped list: the held closed cards stay above it; `null` for a flat list, or when the groups
286
+ * do not describe the proposals.
287
+ */
288
+ readonly sections: _angular_core.Signal<NhAssistantGroupSection[] | null>;
178
289
  constructor();
179
290
  /**
180
291
  * The translation key of a proposal's status: the kind of a stale proposal, "replaced" for a
@@ -189,6 +300,16 @@ declare class NhAssistantAgentProposalsComponent {
189
300
  key: string;
190
301
  params: Record<string, string>;
191
302
  };
303
+ /** Whether the proposal is marked as new. */
304
+ isNew(proposal: AgentProposal): boolean;
305
+ /** Whether every proposal "Select group" would select in the group is selected. */
306
+ groupSelected(group: NhAssistantGroupSection): boolean;
307
+ /**
308
+ * Selects the group's pending proposals in this list that the caller may decide, or deselects them
309
+ * when all are selected. Proposals of the group on another page are never selected: an approver
310
+ * decides only what they see.
311
+ */
312
+ toggleGroup(group: NhAssistantGroupSection): void;
192
313
  /** True when the newer proposal that replaced this one is in the list. */
193
314
  hasSuccessor(proposal: AgentProposal): boolean;
194
315
  /** Moves focus to the newer proposal that replaced this one. */
@@ -224,6 +345,7 @@ declare class NhAssistantAgentProposalsComponent {
224
345
  onFeedbackSaved(): void;
225
346
  /** Closes the question; from a card, focus returns to the card's feedback action. */
226
347
  onFeedbackDismissed(): void;
348
+ private groupSection;
227
349
  private ask;
228
350
  /**
229
351
  * Reads `proposals` again by id and keeps those that closed as stale or were replaced as closed
@@ -232,7 +354,7 @@ declare class NhAssistantAgentProposalsComponent {
232
354
  private holdStale;
233
355
  private run;
234
356
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantAgentProposalsComponent, never>;
235
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentProposalsComponent, "nh-assistant-agent-proposals", never, { "proposals": { "alias": "proposals"; "required": true; "isSignal": true; }; "canDecide": { "alias": "canDecide"; "required": false; "isSignal": true; }; "decisionRights": { "alias": "decisionRights"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "holdClosedCards": { "alias": "holdClosedCards"; "required": false; "isSignal": true; }; }, { "changed": "changed"; "openConversation": "openConversation"; }, never, never, true, never>;
357
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentProposalsComponent, "nh-assistant-agent-proposals", never, { "proposals": { "alias": "proposals"; "required": true; "isSignal": true; }; "canDecide": { "alias": "canDecide"; "required": false; "isSignal": true; }; "decisionRights": { "alias": "decisionRights"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "holdClosedCards": { "alias": "holdClosedCards"; "required": false; "isSignal": true; }; "groups": { "alias": "groups"; "required": false; "isSignal": true; }; "groupByRun": { "alias": "groupByRun"; "required": false; "isSignal": true; }; "newIds": { "alias": "newIds"; "required": false; "isSignal": true; }; }, { "changed": "changed"; "openConversation": "openConversation"; }, never, never, true, never>;
236
358
  }
237
359
 
238
360
  /**
@@ -690,11 +812,18 @@ interface RunDuration {
690
812
  * its object, for the whole application the agent's view policy, administrators every run. The
691
813
  * thread view's run timeline and the administration's runs view open it; an application may show
692
814
  * it anywhere with a run id. With live updates it reloads by itself while the run works.
815
+ *
816
+ * The run's pending proposals that the reader may decide, by the same live check as the inbox and the
817
+ * subject's work (`POST approvals/lookup`), can be decided in place, one by one or selected together
818
+ * with "Select all"; a pending proposal the reader may not decide says who does, and a reader who may
819
+ * decide none sees no selection. After a rejection the list asks, optionally, what was wrong, and a
820
+ * proposal refused because it no longer fits stays as a closed card with the reason until dismissed.
693
821
  */
694
822
  declare class NhAssistantRunResultComponent {
695
823
  private readonly api;
696
824
  private readonly document;
697
825
  private subscription?;
826
+ private rightsSubscription?;
698
827
  /** The run to show. */
699
828
  readonly runId: _angular_core.InputSignal<string>;
700
829
  /**
@@ -718,11 +847,25 @@ declare class NhAssistantRunResultComponent {
718
847
  /** The text of the download's failure, then the text that a file could not be downloaded. */
719
848
  readonly downloadErrorKeys: _angular_core.Signal<string[]>;
720
849
  readonly codeKeys: typeof _nhAssistantCodeKeys;
850
+ /**
851
+ * The reader's live right to decide each pending proposal of the run, by approval id; `null` until
852
+ * it is known, when nobody may decide.
853
+ */
854
+ readonly rights: _angular_core.WritableSignal<ReadonlyMap<string, AgentProposalDecisionRight> | null>;
855
+ /** Whether the reader may decide at least one of the run's proposals: only then can they select. */
856
+ readonly decidable: _angular_core.Signal<boolean>;
721
857
  readonly duration: _angular_core.Signal<RunDuration | null>;
722
858
  readonly tokens: _angular_core.Signal<number>;
723
859
  constructor();
724
860
  load(): void;
861
+ /** A proposal was decided or its feedback given: the run's proposals and the rights are read again. */
862
+ onProposalsChanged(): void;
725
863
  download(artifact: AgentArtifact): Promise<void>;
864
+ /**
865
+ * Reads the reader's live right to decide each pending proposal of the run, as the server checks it
866
+ * for every decision. Without an answer nobody may decide here; the server checks again anyway.
867
+ */
868
+ private readRights;
726
869
  /**
727
870
  * Reads the run. A quiet reload, after a live update, keeps what is shown when it fails and shows
728
871
  * no loading state.