@semiont/react-ui 0.5.26 → 0.5.27
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 +28 -4
- package/dist/{PdfAnnotationCanvas.client-6ZSF6ZTJ.js → PdfAnnotationCanvas.client-EVUPTUWZ.js} +5 -5
- package/dist/PdfAnnotationCanvas.client-EVUPTUWZ.js.map +1 -0
- package/dist/{PdfAnnotationCanvas.client-JCJMXWWJ.css → PdfAnnotationCanvas.client-TGDPPGXJ.css} +6 -1
- package/dist/PdfAnnotationCanvas.client-TGDPPGXJ.css.map +1 -0
- package/dist/{ar-YTUUGK2O.js → ar-OU3DQGC6.js} +53 -7
- package/dist/ar-OU3DQGC6.js.map +1 -0
- package/dist/{bn-ASGNGPMD.js → bn-PHWCR6AZ.js} +53 -7
- package/dist/bn-PHWCR6AZ.js.map +1 -0
- package/dist/{chunk-OBQOZCJE.js → chunk-5VDTWRXJ.js} +31 -31
- package/dist/{chunk-L3WKRWP3.js → chunk-PCRRBU7H.js} +53 -7
- package/dist/chunk-PCRRBU7H.js.map +1 -0
- package/dist/{cs-WMYVAOZY.js → cs-NEXYZ62I.js} +53 -7
- package/dist/cs-NEXYZ62I.js.map +1 -0
- package/dist/{da-FSHHN4D6.js → da-FAT43YCU.js} +53 -7
- package/dist/da-FAT43YCU.js.map +1 -0
- package/dist/{de-FJFO3TPT.js → de-KRQ3WBCU.js} +53 -7
- package/dist/de-KRQ3WBCU.js.map +1 -0
- package/dist/{el-XOH4QIAG.js → el-Q4IU3EKC.js} +53 -7
- package/dist/el-Q4IU3EKC.js.map +1 -0
- package/dist/{en-3FCBW3YD.js → en-2KADE7N4.js} +4 -2
- package/dist/{es-HDX4QI7E.js → es-2IO3R2MK.js} +53 -7
- package/dist/es-2IO3R2MK.js.map +1 -0
- package/dist/{fa-DJ6WTFTJ.js → fa-Q5GOQFXX.js} +53 -7
- package/dist/fa-Q5GOQFXX.js.map +1 -0
- package/dist/{fi-4S7H7W7U.js → fi-R6NMRWBE.js} +53 -7
- package/dist/fi-R6NMRWBE.js.map +1 -0
- package/dist/{fr-6UJSYHXC.js → fr-QY4D5E6J.js} +53 -7
- package/dist/fr-QY4D5E6J.js.map +1 -0
- package/dist/{he-ZZJOHJX2.js → he-X6Y77XHY.js} +53 -7
- package/dist/he-X6Y77XHY.js.map +1 -0
- package/dist/{hi-HZJTAW7U.js → hi-XL7IOEQM.js} +53 -7
- package/dist/hi-XL7IOEQM.js.map +1 -0
- package/dist/{id-E3I6ILEM.js → id-QZ4ZZS67.js} +53 -7
- package/dist/id-QZ4ZZS67.js.map +1 -0
- package/dist/index.css +105 -454
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +155 -54
- package/dist/index.js +1798 -1637
- package/dist/index.js.map +1 -1
- package/dist/integrations/css-modules-helper.js +1 -3
- package/dist/integrations/css-modules-helper.js.map +1 -1
- package/dist/{it-ULAPAD7U.js → it-ME2Q7OB6.js} +53 -7
- package/dist/it-ME2Q7OB6.js.map +1 -0
- package/dist/{ja-SAHZQ4CZ.js → ja-HX7QASRI.js} +53 -7
- package/dist/ja-HX7QASRI.js.map +1 -0
- package/dist/{ko-DFU2ADQ4.js → ko-EQO5AHAV.js} +53 -7
- package/dist/ko-EQO5AHAV.js.map +1 -0
- package/dist/{ms-NWL76XNT.js → ms-UILFSF3I.js} +53 -7
- package/dist/ms-UILFSF3I.js.map +1 -0
- package/dist/{nl-ATCM76WN.js → nl-NNI45PMK.js} +53 -7
- package/dist/nl-NNI45PMK.js.map +1 -0
- package/dist/{no-UIAQ5RJF.js → no-MAL5F6P6.js} +53 -7
- package/dist/no-MAL5F6P6.js.map +1 -0
- package/dist/{pl-NOECQDXD.js → pl-4RMY6JAJ.js} +53 -7
- package/dist/pl-4RMY6JAJ.js.map +1 -0
- package/dist/{pt-SVWIIUPC.js → pt-VQH2X3QQ.js} +53 -7
- package/dist/pt-VQH2X3QQ.js.map +1 -0
- package/dist/{ro-NR2DRTZG.js → ro-XXCQO2OG.js} +53 -7
- package/dist/ro-XXCQO2OG.js.map +1 -0
- package/dist/{sv-STVJ37JP.js → sv-7Z6EJ6U4.js} +53 -7
- package/dist/sv-7Z6EJ6U4.js.map +1 -0
- package/dist/test-utils.css +1 -1
- package/dist/test-utils.css.map +1 -1
- package/dist/test-utils.d.ts +1 -1
- package/dist/test-utils.js +2 -2
- package/dist/test-utils.js.map +1 -1
- package/dist/{th-UWQR4K54.js → th-L3DXXYVQ.js} +53 -7
- package/dist/th-L3DXXYVQ.js.map +1 -0
- package/dist/{tr-WNXZSD27.js → tr-P3DFVLFJ.js} +53 -7
- package/dist/tr-P3DFVLFJ.js.map +1 -0
- package/dist/{uk-SJRMB47Y.js → uk-7C5D3PXS.js} +53 -7
- package/dist/uk-7C5D3PXS.js.map +1 -0
- package/dist/{vi-TMRQFES2.js → vi-ZLTLEO7P.js} +53 -7
- package/dist/vi-ZLTLEO7P.js.map +1 -0
- package/dist/{zh-QOL3LYEM.js → zh-5FHVWDIN.js} +53 -7
- package/dist/zh-5FHVWDIN.js.map +1 -0
- package/package.json +7 -7
- package/src/components/AssistProgress.tsx +144 -134
- package/src/components/{EntityFoundLog.tsx → ItemFoundLog.tsx} +12 -7
- package/src/components/ProtectedErrorBoundary.css +3 -1
- package/src/components/StatusDisplay.css +1 -1
- package/src/components/Toast.css +3 -1
- package/src/components/__tests__/AssistProgress.test.tsx +216 -148
- package/src/components/annotation/annotation-entries.css +0 -4
- package/src/components/annotation/references.css +0 -4
- package/src/components/image-annotation/AnnotationOverlay.tsx +6 -6
- package/src/components/image-annotation/SvgDrawingCanvas.tsx +1 -1
- package/src/components/image-annotation/__tests__/AnnotationOverlay.click.test.tsx +7 -9
- package/src/components/image-annotation/__tests__/SvgDrawingCanvas.click.test.tsx +1 -2
- package/src/components/layout/Header.css +0 -4
- package/src/components/layout/LeftSidebar.css +0 -4
- package/src/components/modals/ConfigureGenerationStep.tsx +109 -48
- package/src/components/modals/ConfigureSearchStep.tsx +23 -40
- package/src/components/modals/ReferenceWizardModal.tsx +55 -16
- package/src/components/modals/ResourceGenerateModal.tsx +24 -8
- package/src/components/modals/ResourceSearchModal.tsx +1 -1
- package/src/components/modals/SearchModal.css +0 -12
- package/src/components/modals/SearchModal.tsx +1 -1
- package/src/components/modals/SearchResultsStep.tsx +2 -20
- package/src/components/modals/WizardFooter.tsx +63 -0
- package/src/components/modals/__tests__/ConfigureGenerationStep.test.tsx +255 -0
- package/src/components/modals/__tests__/ConfigureSearchStep.test.tsx +72 -0
- package/src/components/modals/__tests__/ReferenceWizardModal.test.tsx +256 -0
- package/src/components/modals/__tests__/ResourceGenerateModal.test.tsx +1 -0
- package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +6 -2
- package/src/components/modals/__tests__/SearchModal.search-wiring.test.tsx +6 -2
- package/src/components/modals/__tests__/WizardFooter.test.tsx +235 -0
- package/src/components/modals/modals.css +16 -42
- package/src/components/navigation/NavigationTabs.css +0 -20
- package/src/components/pdf-annotation/PdfAnnotationCanvas.css +21 -2
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +2 -2
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +3 -5
- package/src/components/resource/AnnotateView.tsx +16 -5
- package/src/components/resource/AnnotationHistory.tsx +2 -0
- package/src/components/resource/BrowseView.tsx +15 -4
- package/src/components/resource/ResourceViewer.tsx +23 -24
- package/src/components/resource/__tests__/AnnotateView.focus.test.tsx +50 -0
- package/src/components/resource/__tests__/AnnotationHistory.test.tsx +2 -0
- package/src/components/resource/__tests__/BrowseView.test.tsx +29 -3
- package/src/components/resource/__tests__/ResourceViewer.embeddable.test.tsx +47 -3
- package/src/components/resource/event-formatting.ts +0 -3
- package/src/components/resource/panels/AssessmentEntry.tsx +1 -1
- package/src/components/resource/panels/AssessmentPanel.css +5 -6
- package/src/components/resource/panels/AssistSection.css +68 -271
- package/src/components/resource/panels/AssistSection.tsx +4 -4
- package/src/components/resource/panels/AssistShell.tsx +12 -4
- package/src/components/resource/panels/CollaborationPanel.css +47 -22
- package/src/components/resource/panels/CollaborationPanel.tsx +93 -2
- package/src/components/resource/panels/CommentEntry.tsx +1 -1
- package/src/components/resource/panels/CommentsPanel.css +0 -16
- package/src/components/resource/panels/HighlightEntry.tsx +1 -1
- package/src/components/resource/panels/HighlightPanel.css +0 -7
- package/src/components/resource/panels/JsonLdPanel.css +0 -4
- package/src/components/resource/panels/ReferenceEntry.tsx +1 -1
- package/src/components/resource/panels/ReferencesPanel.css +0 -12
- package/src/components/resource/panels/ReferencesPanel.tsx +12 -20
- package/src/components/resource/panels/ResourceInfoPanel.css +0 -32
- package/src/components/resource/panels/ResourceInfoPanel.tsx +1 -1
- package/src/components/resource/panels/StatisticsPanel.css +0 -20
- package/src/components/resource/panels/TagEntry.tsx +1 -1
- package/src/components/resource/panels/TaggingPanel.css +0 -4
- package/src/components/resource/panels/TaggingPanel.tsx +2 -10
- package/src/components/resource/panels/UnifiedAnnotationsPanel.css +0 -4
- package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/AssistSection.test.tsx +48 -50
- package/src/components/resource/panels/__tests__/AssistShell.test.tsx +11 -6
- package/src/components/resource/panels/__tests__/CollaborationPanel.test.tsx +89 -0
- package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +1 -2
- package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +44 -36
- package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/ReferencesPanel.headless.test.tsx +1 -1
- package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +34 -53
- package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +37 -1
- package/src/components/resource/panels/__tests__/TagEntry.test.tsx +0 -1
- package/src/components/settings/SettingsPanel.css +0 -4
- package/src/features/auth/auth.css +2 -26
- package/src/features/resource-compose/state/__tests__/compose-page-state-unit.test.ts +25 -1
- package/src/features/resource-compose/state/compose-page-state-unit.ts +11 -2
- package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +55 -0
- package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +29 -0
- package/src/features/resource-discovery/state/__tests__/discover-state-unit.test.ts +53 -3
- package/src/features/resource-discovery/state/discover-state-unit.ts +29 -8
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +41 -20
- package/src/features/resource-viewer/hooks/__tests__/useResourceViewedReport.test.tsx +63 -0
- package/src/features/resource-viewer/hooks/useResourceViewedReport.ts +33 -0
- package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts +2 -2
- package/src/features/resource-viewer/state/resource-viewer-page-state-unit.ts +1 -1
- package/src/styles/core/buttons.css +3 -1
- package/src/styles/core/forms.css +0 -21
- package/src/styles/core/indicators.css +0 -4
- package/src/styles/core/inputs.css +0 -4
- package/src/styles/core/progress.css +2 -34
- package/src/styles/core/sliders.css +0 -4
- package/src/styles/core/toggles.css +0 -4
- package/src/styles/features/resource-discovery.css +13 -0
- package/src/styles/features/resource-viewer.css +0 -20
- package/src/styles/motivations/motivation-assessment.css +2 -2
- package/src/styles/panels/history-panel.css +0 -40
- package/src/styles/panels/user-panel.css +0 -3
- package/src/styles/patterns/panel-helpers.css +0 -27
- package/src/styles/patterns/panel-sections.css +0 -59
- package/src/styles/patterns/panels-base.css +0 -32
- package/translations/ar.json +49 -5
- package/translations/bn.json +49 -5
- package/translations/cs.json +49 -5
- package/translations/da.json +49 -5
- package/translations/de.json +49 -5
- package/translations/el.json +49 -5
- package/translations/en.json +49 -5
- package/translations/es.json +49 -5
- package/translations/fa.json +49 -5
- package/translations/fi.json +49 -5
- package/translations/fr.json +49 -5
- package/translations/he.json +49 -5
- package/translations/hi.json +49 -5
- package/translations/id.json +49 -5
- package/translations/it.json +49 -5
- package/translations/ja.json +49 -5
- package/translations/ko.json +49 -5
- package/translations/ms.json +49 -5
- package/translations/nl.json +49 -5
- package/translations/no.json +49 -5
- package/translations/pl.json +49 -5
- package/translations/pt.json +49 -5
- package/translations/ro.json +49 -5
- package/translations/sv.json +49 -5
- package/translations/th.json +49 -5
- package/translations/tr.json +49 -5
- package/translations/uk.json +49 -5
- package/translations/vi.json +49 -5
- package/translations/zh.json +49 -5
- package/dist/PdfAnnotationCanvas.client-6ZSF6ZTJ.js.map +0 -1
- package/dist/PdfAnnotationCanvas.client-JCJMXWWJ.css.map +0 -1
- package/dist/ar-YTUUGK2O.js.map +0 -1
- package/dist/bn-ASGNGPMD.js.map +0 -1
- package/dist/chunk-L3WKRWP3.js.map +0 -1
- package/dist/chunk-XUDKYAVC.js +0 -21
- package/dist/chunk-XUDKYAVC.js.map +0 -1
- package/dist/cs-WMYVAOZY.js.map +0 -1
- package/dist/da-FSHHN4D6.js.map +0 -1
- package/dist/de-FJFO3TPT.js.map +0 -1
- package/dist/el-XOH4QIAG.js.map +0 -1
- package/dist/es-HDX4QI7E.js.map +0 -1
- package/dist/fa-DJ6WTFTJ.js.map +0 -1
- package/dist/fi-4S7H7W7U.js.map +0 -1
- package/dist/fr-6UJSYHXC.js.map +0 -1
- package/dist/he-ZZJOHJX2.js.map +0 -1
- package/dist/hi-HZJTAW7U.js.map +0 -1
- package/dist/id-E3I6ILEM.js.map +0 -1
- package/dist/it-ULAPAD7U.js.map +0 -1
- package/dist/ja-SAHZQ4CZ.js.map +0 -1
- package/dist/ko-DFU2ADQ4.js.map +0 -1
- package/dist/ms-NWL76XNT.js.map +0 -1
- package/dist/nl-ATCM76WN.js.map +0 -1
- package/dist/no-UIAQ5RJF.js.map +0 -1
- package/dist/pl-NOECQDXD.js.map +0 -1
- package/dist/pt-SVWIIUPC.js.map +0 -1
- package/dist/ro-NR2DRTZG.js.map +0 -1
- package/dist/sv-STVJ37JP.js.map +0 -1
- package/dist/th-UWQR4K54.js.map +0 -1
- package/dist/tr-WNXZSD27.js.map +0 -1
- package/dist/uk-SJRMB47Y.js.map +0 -1
- package/dist/vi-TMRQFES2.js.map +0 -1
- package/dist/zh-QOL3LYEM.js.map +0 -1
- package/src/integrations/tailwind-plugin.cjs +0 -224
- /package/dist/{chunk-OBQOZCJE.js.map → chunk-5VDTWRXJ.js.map} +0 -0
- /package/dist/{en-3FCBW3YD.js.map → en-2KADE7N4.js.map} +0 -0
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import React, {
|
|
4
|
-
import
|
|
3
|
+
import React, { useEffect } from 'react';
|
|
4
|
+
import { WizardFooter } from './WizardFooter';
|
|
5
|
+
import type { CollaboratorEntry, GatheredContext } from '@semiont/core';
|
|
5
6
|
import { LOCALES } from '@semiont/core';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Bounds for the max-length control when no ceiling is known. These are the
|
|
10
|
+
* values this control has always shipped — the fallback is today's behaviour,
|
|
11
|
+
* not an unbounded field (INFERENCE-LIMITS-EXPOSURE D6, as corrected in review).
|
|
12
|
+
*/
|
|
13
|
+
const MIN_MAX_TOKENS = 100;
|
|
14
|
+
const DEFAULT_MAX_TOKENS_CEILING = 4000;
|
|
15
|
+
/** The step's form values, owned by the wizard so Back cannot discard them (D3). */
|
|
16
|
+
export interface GenerationDraft {
|
|
17
|
+
title: string;
|
|
18
|
+
storagePath: string;
|
|
19
|
+
prompt: string;
|
|
20
|
+
language: string;
|
|
21
|
+
temperature: number;
|
|
22
|
+
/** Text, not number: the field is user-editable and may be mid-edit or empty. */
|
|
23
|
+
maxTokensText: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
6
26
|
export interface GenerationConfig {
|
|
7
27
|
title: string;
|
|
8
28
|
storagePath: string;
|
|
@@ -14,11 +34,11 @@ export interface GenerationConfig {
|
|
|
14
34
|
}
|
|
15
35
|
|
|
16
36
|
export interface ConfigureGenerationStepProps {
|
|
17
|
-
defaultTitle: string;
|
|
18
|
-
locale: string;
|
|
19
37
|
context: GatheredContext;
|
|
38
|
+
/** Owned by the wizard so Back is lossless (WIZARD-NAVIGATION D3). */
|
|
39
|
+
config: GenerationDraft;
|
|
40
|
+
onConfigChange: (config: GenerationDraft) => void;
|
|
20
41
|
onBack: () => void;
|
|
21
|
-
onCancel: () => void;
|
|
22
42
|
onGenerate: (config: GenerationConfig) => void;
|
|
23
43
|
translations: {
|
|
24
44
|
resourceTitle: string;
|
|
@@ -32,27 +52,65 @@ export interface ConfigureGenerationStepProps {
|
|
|
32
52
|
creativityCreative: string;
|
|
33
53
|
maxLength: string;
|
|
34
54
|
maxLengthHelp: string;
|
|
35
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Shown INSTEAD of `maxLengthHelp` when the ceiling is known, so the bound
|
|
57
|
+
* is legible rather than mysterious. Interpolates `{{maxOutputTokens}}`
|
|
58
|
+
* and `{{model}}`.
|
|
59
|
+
*/
|
|
60
|
+
maxLengthCeiling: string;
|
|
36
61
|
back: string;
|
|
37
62
|
generate: string;
|
|
38
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* The roster entry serving `generation` (from `useCollaborators`). When its
|
|
66
|
+
* `limits` are known the max-length control is hard-bounded by the model's
|
|
67
|
+
* output ceiling; absent — or present without `limits`, which is normal when
|
|
68
|
+
* discovery could not answer right now — the control keeps its default
|
|
69
|
+
* bounds and generation still submits (D3).
|
|
70
|
+
*/
|
|
71
|
+
generationAgent?: CollaboratorEntry;
|
|
39
72
|
}
|
|
40
73
|
|
|
41
74
|
export function ConfigureGenerationStep({
|
|
42
|
-
defaultTitle,
|
|
43
|
-
locale,
|
|
44
75
|
context,
|
|
76
|
+
config,
|
|
77
|
+
onConfigChange,
|
|
45
78
|
onBack,
|
|
46
|
-
onCancel,
|
|
47
79
|
onGenerate,
|
|
48
80
|
translations: t,
|
|
81
|
+
generationAgent,
|
|
49
82
|
}: ConfigureGenerationStepProps) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
83
|
+
// CONTROLLED (WIZARD-NAVIGATION D3): these were six local `useState`s, so Back
|
|
84
|
+
// unmounted the step and threw away every typed instruction, the save path and
|
|
85
|
+
// both sliders. `maxTokensText` stays TEXT rather than a number so the field can
|
|
86
|
+
// be cleared mid-edit — `parseInt` on an empty field yields NaN, which React
|
|
87
|
+
// warns about and which used to travel into the job config.
|
|
88
|
+
const { title, storagePath, prompt, language, temperature, maxTokensText } = config;
|
|
89
|
+
const set = (patch: Partial<GenerationDraft>) => onConfigChange({ ...config, ...patch });
|
|
90
|
+
|
|
91
|
+
const ceiling = generationAgent?.limits?.maxOutputTokens ?? DEFAULT_MAX_TOKENS_CEILING;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The value that will actually be submitted: always finite, always inside
|
|
95
|
+
* the bounds, whatever the field currently shows.
|
|
96
|
+
*/
|
|
97
|
+
const clamp = (n: number): number =>
|
|
98
|
+
Math.min(Math.max(Number.isFinite(n) ? n : MIN_MAX_TOKENS, MIN_MAX_TOKENS), ceiling);
|
|
99
|
+
|
|
100
|
+
const submittedMaxTokens = clamp(parseInt(maxTokensText, 10));
|
|
101
|
+
|
|
102
|
+
// Re-clamp whenever the ceiling changes — which INCLUDES its first arrival.
|
|
103
|
+
// `browse.agents()` is asynchronous, so `generationAgent` is undefined on the
|
|
104
|
+
// first render and lands later; clamping only in the `useState` initializer
|
|
105
|
+
// would satisfy a mount-time test and do nothing in the running app.
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
const n = parseInt(maxTokensText, 10);
|
|
108
|
+
// An empty/mid-edit field is left alone; submission clamps it anyway.
|
|
109
|
+
if (Number.isFinite(n) && n > ceiling) set({ maxTokensText: String(ceiling) });
|
|
110
|
+
// `set` and the draft are intentionally out of the dep list: this reacts to the
|
|
111
|
+
// CEILING arriving (browse.agents() is async), not to the user typing.
|
|
112
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
113
|
+
}, [ceiling]);
|
|
56
114
|
|
|
57
115
|
const handleSubmit = (e: React.FormEvent) => {
|
|
58
116
|
e.preventDefault();
|
|
@@ -63,7 +121,7 @@ export function ConfigureGenerationStep({
|
|
|
63
121
|
...(trimmedPrompt ? { prompt: trimmedPrompt } : {}),
|
|
64
122
|
language,
|
|
65
123
|
temperature,
|
|
66
|
-
maxTokens,
|
|
124
|
+
maxTokens: submittedMaxTokens,
|
|
67
125
|
context,
|
|
68
126
|
});
|
|
69
127
|
};
|
|
@@ -79,7 +137,7 @@ export function ConfigureGenerationStep({
|
|
|
79
137
|
id="wizard-title"
|
|
80
138
|
type="text"
|
|
81
139
|
value={title}
|
|
82
|
-
onChange={(e) =>
|
|
140
|
+
onChange={(e) => set({ title: e.target.value })}
|
|
83
141
|
required
|
|
84
142
|
className="semiont-input"
|
|
85
143
|
placeholder={t.resourceTitlePlaceholder}
|
|
@@ -97,7 +155,7 @@ export function ConfigureGenerationStep({
|
|
|
97
155
|
id="wizard-storagePath"
|
|
98
156
|
type="text"
|
|
99
157
|
value={storagePath}
|
|
100
|
-
onChange={(e) =>
|
|
158
|
+
onChange={(e) => set({ storagePath: e.target.value })}
|
|
101
159
|
required
|
|
102
160
|
className="semiont-input semiont-input--addon"
|
|
103
161
|
placeholder="generated/my-resource.md"
|
|
@@ -113,7 +171,7 @@ export function ConfigureGenerationStep({
|
|
|
113
171
|
<textarea
|
|
114
172
|
id="wizard-prompt"
|
|
115
173
|
value={prompt}
|
|
116
|
-
onChange={(e) =>
|
|
174
|
+
onChange={(e) => set({ prompt: e.target.value })}
|
|
117
175
|
rows={2}
|
|
118
176
|
className="semiont-textarea"
|
|
119
177
|
placeholder={t.additionalInstructionsPlaceholder}
|
|
@@ -129,7 +187,7 @@ export function ConfigureGenerationStep({
|
|
|
129
187
|
<select
|
|
130
188
|
id="wizard-language"
|
|
131
189
|
value={language}
|
|
132
|
-
onChange={(e) =>
|
|
190
|
+
onChange={(e) => set({ language: e.target.value })}
|
|
133
191
|
className="semiont-select"
|
|
134
192
|
>
|
|
135
193
|
{LOCALES.map((lang) => (
|
|
@@ -151,7 +209,7 @@ export function ConfigureGenerationStep({
|
|
|
151
209
|
max="1"
|
|
152
210
|
step="0.1"
|
|
153
211
|
value={temperature}
|
|
154
|
-
onChange={(e) =>
|
|
212
|
+
onChange={(e) => set({ temperature: parseFloat(e.target.value) })}
|
|
155
213
|
className="semiont-slider"
|
|
156
214
|
/>
|
|
157
215
|
<div className="semiont-slider__labels semiont-slider__labels--small">
|
|
@@ -167,39 +225,42 @@ export function ConfigureGenerationStep({
|
|
|
167
225
|
<input
|
|
168
226
|
id="wizard-maxTokens"
|
|
169
227
|
type="number"
|
|
170
|
-
min=
|
|
171
|
-
max=
|
|
228
|
+
min={MIN_MAX_TOKENS}
|
|
229
|
+
max={ceiling}
|
|
172
230
|
step="100"
|
|
173
|
-
value={
|
|
174
|
-
onChange={(e) =>
|
|
231
|
+
value={maxTokensText}
|
|
232
|
+
onChange={(e) => {
|
|
233
|
+
const raw = e.target.value;
|
|
234
|
+
// Empty is a legitimate transient state while retyping.
|
|
235
|
+
if (raw === '') { set({ maxTokensText: '' }); return; }
|
|
236
|
+
const n = parseInt(raw, 10);
|
|
237
|
+
if (!Number.isFinite(n)) return;
|
|
238
|
+
// `max` alone does not stop a larger value being typed — it only
|
|
239
|
+
// marks the field invalid. D6 says it cannot be entered, so the
|
|
240
|
+
// clamp lives here.
|
|
241
|
+
set({ maxTokensText: String(Math.min(n, ceiling)) });
|
|
242
|
+
}}
|
|
175
243
|
className="semiont-input"
|
|
176
244
|
/>
|
|
245
|
+
<p className="semiont-form__help">
|
|
246
|
+
{generationAgent?.limits
|
|
247
|
+
? t.maxLengthCeiling
|
|
248
|
+
.replace('{{maxOutputTokens}}', String(ceiling))
|
|
249
|
+
.replace(
|
|
250
|
+
'{{model}}',
|
|
251
|
+
(generationAgent.agent as { model?: string; name?: string }).model
|
|
252
|
+
?? generationAgent.agent.name,
|
|
253
|
+
)
|
|
254
|
+
: t.maxLengthHelp}
|
|
255
|
+
</p>
|
|
177
256
|
</div>
|
|
178
257
|
</div>
|
|
179
258
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
className="semiont-button--secondary semiont-button--flex"
|
|
186
|
-
>
|
|
187
|
-
✕ {t.cancel}
|
|
188
|
-
</button>
|
|
189
|
-
<button
|
|
190
|
-
type="button"
|
|
191
|
-
onClick={onBack}
|
|
192
|
-
className="semiont-button--secondary semiont-button--flex"
|
|
193
|
-
>
|
|
194
|
-
◀ {t.back}
|
|
195
|
-
</button>
|
|
196
|
-
<button
|
|
197
|
-
type="submit"
|
|
198
|
-
className="semiont-button--primary semiont-button--flex"
|
|
199
|
-
>
|
|
200
|
-
✨ {t.generate}
|
|
201
|
-
</button>
|
|
202
|
-
</div>
|
|
259
|
+
<WizardFooter
|
|
260
|
+
backLabel={t.back}
|
|
261
|
+
onBack={onBack}
|
|
262
|
+
primary={{ label: t.generate, type: 'submit' }}
|
|
263
|
+
/>
|
|
203
264
|
</form>
|
|
204
265
|
);
|
|
205
266
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import React
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { WizardFooter } from './WizardFooter';
|
|
4
5
|
|
|
5
6
|
export interface SearchConfig {
|
|
6
7
|
limit: number;
|
|
@@ -8,15 +9,21 @@ export interface SearchConfig {
|
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export interface ConfigureSearchStepProps {
|
|
12
|
+
/**
|
|
13
|
+
* CONTROLLED (WIZARD-NAVIGATION D3). This used to be local `useState`, so stepping
|
|
14
|
+
* Back unmounted the component and silently discarded what the user had chosen —
|
|
15
|
+
* a Back button that costs you work is worse than no Back button, because it
|
|
16
|
+
* invites the press. The wizard owns it for the modal's lifetime instead.
|
|
17
|
+
*/
|
|
18
|
+
config: SearchConfig;
|
|
19
|
+
onConfigChange: (config: SearchConfig) => void;
|
|
11
20
|
isSearching?: boolean;
|
|
12
21
|
onBack: () => void;
|
|
13
|
-
onCancel: () => void;
|
|
14
22
|
onSearch: (config: SearchConfig) => void;
|
|
15
23
|
translations: {
|
|
16
24
|
maxResults: string;
|
|
17
25
|
semanticScoring: string;
|
|
18
26
|
semanticScoringHelp: string;
|
|
19
|
-
cancel: string;
|
|
20
27
|
back: string;
|
|
21
28
|
search: string;
|
|
22
29
|
searching: string;
|
|
@@ -24,18 +31,16 @@ export interface ConfigureSearchStepProps {
|
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
export function ConfigureSearchStep({
|
|
34
|
+
config,
|
|
35
|
+
onConfigChange,
|
|
27
36
|
isSearching = false,
|
|
28
37
|
onBack,
|
|
29
|
-
onCancel,
|
|
30
38
|
onSearch,
|
|
31
39
|
translations: t,
|
|
32
40
|
}: ConfigureSearchStepProps) {
|
|
33
|
-
const [limit, setLimit] = useState(10);
|
|
34
|
-
const [useSemanticScoring, setUseSemanticScoring] = useState(true);
|
|
35
|
-
|
|
36
41
|
const handleSubmit = (e: React.FormEvent) => {
|
|
37
42
|
e.preventDefault();
|
|
38
|
-
onSearch(
|
|
43
|
+
onSearch(config);
|
|
39
44
|
};
|
|
40
45
|
|
|
41
46
|
return (
|
|
@@ -47,8 +52,8 @@ export function ConfigureSearchStep({
|
|
|
47
52
|
</label>
|
|
48
53
|
<select
|
|
49
54
|
id="wizard-limit"
|
|
50
|
-
value={limit}
|
|
51
|
-
onChange={(e) =>
|
|
55
|
+
value={config.limit}
|
|
56
|
+
onChange={(e) => onConfigChange({ ...config, limit: parseInt(e.target.value) })}
|
|
52
57
|
className="semiont-select"
|
|
53
58
|
>
|
|
54
59
|
<option value={1}>1</option>
|
|
@@ -60,11 +65,11 @@ export function ConfigureSearchStep({
|
|
|
60
65
|
|
|
61
66
|
{/* Semantic Scoring Toggle */}
|
|
62
67
|
<div className="semiont-form__field">
|
|
63
|
-
<label className="semiont-form__label"
|
|
68
|
+
<label className="semiont-form__label semiont-form__label--inline">
|
|
64
69
|
<input
|
|
65
70
|
type="checkbox"
|
|
66
|
-
checked={useSemanticScoring}
|
|
67
|
-
onChange={(e) =>
|
|
71
|
+
checked={config.useSemanticScoring}
|
|
72
|
+
onChange={(e) => onConfigChange({ ...config, useSemanticScoring: e.target.checked })}
|
|
68
73
|
/>
|
|
69
74
|
{t.semanticScoring}
|
|
70
75
|
</label>
|
|
@@ -73,33 +78,11 @@ export function ConfigureSearchStep({
|
|
|
73
78
|
</p>
|
|
74
79
|
</div>
|
|
75
80
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
className="semiont-button--secondary semiont-button--flex"
|
|
82
|
-
disabled={isSearching}
|
|
83
|
-
>
|
|
84
|
-
✕ {t.cancel}
|
|
85
|
-
</button>
|
|
86
|
-
<button
|
|
87
|
-
type="button"
|
|
88
|
-
onClick={onBack}
|
|
89
|
-
className="semiont-button--secondary semiont-button--flex"
|
|
90
|
-
disabled={isSearching}
|
|
91
|
-
>
|
|
92
|
-
◀ {t.back}
|
|
93
|
-
</button>
|
|
94
|
-
<button
|
|
95
|
-
type="submit"
|
|
96
|
-
className="semiont-button--primary semiont-button--flex"
|
|
97
|
-
disabled={isSearching}
|
|
98
|
-
data-generating={isSearching ? 'true' : 'false'}
|
|
99
|
-
>
|
|
100
|
-
{isSearching ? `✨ ${t.searching}` : `🔍 ${t.search}`}
|
|
101
|
-
</button>
|
|
102
|
-
</div>
|
|
81
|
+
<WizardFooter
|
|
82
|
+
backLabel={t.back}
|
|
83
|
+
onBack={onBack}
|
|
84
|
+
primary={{ label: t.search, pendingLabel: t.searching, pending: isSearching, type: 'submit' }}
|
|
85
|
+
/>
|
|
103
86
|
</form>
|
|
104
87
|
);
|
|
105
88
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useState, useEffect, useCallback } from 'react';
|
|
4
4
|
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from '@headlessui/react';
|
|
5
|
-
import type { GatheredContext } from '@semiont/core';
|
|
5
|
+
import type { GatheredContext, CollaboratorEntry } from '@semiont/core';
|
|
6
6
|
import { uuidV4 } from '@semiont/core';
|
|
7
7
|
import { useSemiont } from '../../session/SemiontProvider';
|
|
8
8
|
import { useObservable } from '../../hooks/useObservable';
|
|
@@ -12,6 +12,7 @@ import { ConfigureGenerationStep } from './ConfigureGenerationStep';
|
|
|
12
12
|
import type { GenerationConfig } from './ConfigureGenerationStep';
|
|
13
13
|
import { ConfigureSearchStep } from './ConfigureSearchStep';
|
|
14
14
|
import type { SearchConfig } from './ConfigureSearchStep';
|
|
15
|
+
import type { GenerationDraft } from './ConfigureGenerationStep';
|
|
15
16
|
import { SearchResultsStep } from './SearchResultsStep';
|
|
16
17
|
import type { ScoredResult } from './SearchResultsStep';
|
|
17
18
|
|
|
@@ -22,6 +23,12 @@ type WizardStep =
|
|
|
22
23
|
| { step: 'configure-generation' };
|
|
23
24
|
|
|
24
25
|
export interface ReferenceWizardModalProps {
|
|
26
|
+
/**
|
|
27
|
+
* Roster entry serving `generation`, forwarded to ConfigureGenerationStep so
|
|
28
|
+
* the max-length control is bounded by the model's real output ceiling.
|
|
29
|
+
* Optional: absent means today's default bounds (INFERENCE-LIMITS-EXPOSURE D3).
|
|
30
|
+
*/
|
|
31
|
+
generationAgent?: CollaboratorEntry;
|
|
25
32
|
isOpen: boolean;
|
|
26
33
|
onClose: () => void;
|
|
27
34
|
/** The annotation being resolved */
|
|
@@ -76,6 +83,7 @@ export interface ReferenceWizardModalProps {
|
|
|
76
83
|
creativityCreative: string;
|
|
77
84
|
maxLength: string;
|
|
78
85
|
maxLengthHelp: string;
|
|
86
|
+
maxLengthCeiling: string;
|
|
79
87
|
maxResults: string;
|
|
80
88
|
semanticScoring: string;
|
|
81
89
|
semanticScoringHelp: string;
|
|
@@ -97,9 +105,18 @@ export function ReferenceWizardModal({
|
|
|
97
105
|
onLinkResource,
|
|
98
106
|
onComposeNavigate,
|
|
99
107
|
translations: t,
|
|
108
|
+
generationAgent,
|
|
100
109
|
}: ReferenceWizardModalProps) {
|
|
101
110
|
const session = useObservable(useSemiont().activeSession$);
|
|
102
111
|
const [wizardStep, setWizardStep] = useState<WizardStep>({ step: 'gather' });
|
|
112
|
+
// Both step drafts live HERE, not in the steps (WIZARD-NAVIGATION D3). Stepping
|
|
113
|
+
// back unmounts a step; if the step owned its values, Back would silently discard
|
|
114
|
+
// everything typed — which is exactly what it used to do.
|
|
115
|
+
const [searchConfig, setSearchConfig] = useState<SearchConfig>({ limit: 10, useSemanticScoring: true });
|
|
116
|
+
const [generationDraft, setGenerationDraft] = useState<GenerationDraft>({
|
|
117
|
+
title: defaultTitle, storagePath: '', prompt: '', language: locale,
|
|
118
|
+
temperature: 0.7, maxTokensText: '500',
|
|
119
|
+
});
|
|
103
120
|
const [isSearching, setIsSearching] = useState(false);
|
|
104
121
|
const [userHint, setUserHint] = useState('');
|
|
105
122
|
|
|
@@ -107,6 +124,11 @@ export function ReferenceWizardModal({
|
|
|
107
124
|
useEffect(() => {
|
|
108
125
|
if (isOpen) {
|
|
109
126
|
setWizardStep({ step: 'gather' });
|
|
127
|
+
setSearchConfig({ limit: 10, useSemanticScoring: true });
|
|
128
|
+
setGenerationDraft({
|
|
129
|
+
title: defaultTitle, storagePath: '', prompt: '', language: locale,
|
|
130
|
+
temperature: 0.7, maxTokensText: '500',
|
|
131
|
+
});
|
|
110
132
|
setIsSearching(false);
|
|
111
133
|
setUserHint('');
|
|
112
134
|
}
|
|
@@ -125,25 +147,44 @@ export function ReferenceWizardModal({
|
|
|
125
147
|
setWizardStep({ step: 'configure-search' });
|
|
126
148
|
}, []);
|
|
127
149
|
|
|
150
|
+
/**
|
|
151
|
+
* The gather step's Hint, placed where the schema says it lives.
|
|
152
|
+
*
|
|
153
|
+
* Two defects, one line. (1) Search and compose each built this inline and
|
|
154
|
+
* generation did not, so picking the AI path silently discarded what the user had
|
|
155
|
+
* typed — and then showed them an empty "Additional Instructions" box.
|
|
156
|
+
* (2) Both existing sites wrote `{ ...context, userHint }`, a TOP-LEVEL key
|
|
157
|
+
* `GatheredContext` does not define; `GatheredContext.json` puts it at
|
|
158
|
+
* `focus.userHint` ("hint to supplement or replace the selected text for search and
|
|
159
|
+
* generation"). So the hint was misplaced on every path, not just missing on one.
|
|
160
|
+
*
|
|
161
|
+
* NOTE: no production code reads `focus.userHint` yet — this is correct plumbing
|
|
162
|
+
* for a field nothing consumes. Making the hint actually steer search or generation
|
|
163
|
+
* is a separate change (see WIZARD-NAVIGATION's execution log).
|
|
164
|
+
*/
|
|
165
|
+
const contextWithHint = !context
|
|
166
|
+
? null
|
|
167
|
+
: userHint
|
|
168
|
+
? { ...context, focus: { ...context.focus, userHint } }
|
|
169
|
+
: context;
|
|
170
|
+
|
|
128
171
|
const handleGenerate = useCallback(() => {
|
|
129
172
|
setWizardStep({ step: 'configure-generation' });
|
|
130
173
|
}, []);
|
|
131
174
|
|
|
132
175
|
const handleCompose = useCallback(() => {
|
|
133
|
-
if (!
|
|
134
|
-
const contextWithHint = userHint ? { ...context, userHint } : context;
|
|
176
|
+
if (!contextWithHint || !annotationId || !resourceId) return;
|
|
135
177
|
onComposeNavigate(contextWithHint, annotationId, resourceId, defaultTitle, entityTypes);
|
|
136
178
|
onClose();
|
|
137
|
-
}, [
|
|
179
|
+
}, [contextWithHint, annotationId, resourceId, defaultTitle, entityTypes, onComposeNavigate, onClose]);
|
|
138
180
|
|
|
139
181
|
const handleBackToGather = useCallback(() => {
|
|
140
182
|
setWizardStep({ step: 'gather' });
|
|
141
183
|
}, []);
|
|
142
184
|
|
|
143
185
|
const handleSearchSubmit = useCallback((config: SearchConfig) => {
|
|
144
|
-
if (!annotationId || !
|
|
186
|
+
if (!annotationId || !contextWithHint || !resourceId) return;
|
|
145
187
|
setIsSearching(true);
|
|
146
|
-
const contextWithHint = userHint ? { ...context, userHint } : context;
|
|
147
188
|
session?.client.match.requestSearch({
|
|
148
189
|
correlationId: uuidV4(),
|
|
149
190
|
resourceId,
|
|
@@ -153,7 +194,7 @@ export function ReferenceWizardModal({
|
|
|
153
194
|
useSemanticScoring: config.useSemanticScoring,
|
|
154
195
|
});
|
|
155
196
|
// Stay on configure-search until results arrive (subscription above handles transition)
|
|
156
|
-
}, [annotationId, resourceId,
|
|
197
|
+
}, [annotationId, resourceId, contextWithHint, session]);
|
|
157
198
|
|
|
158
199
|
const handleGenerateSubmit = useCallback((config: GenerationConfig) => {
|
|
159
200
|
if (!annotationId) return;
|
|
@@ -245,11 +286,11 @@ export function ReferenceWizardModal({
|
|
|
245
286
|
|
|
246
287
|
{wizardStep.step === 'configure-generation' && context && (
|
|
247
288
|
<ConfigureGenerationStep
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
289
|
+
{...(generationAgent ? { generationAgent } : {})}
|
|
290
|
+
context={contextWithHint ?? context}
|
|
291
|
+
config={generationDraft}
|
|
292
|
+
onConfigChange={setGenerationDraft}
|
|
251
293
|
onBack={handleBackToGather}
|
|
252
|
-
onCancel={onClose}
|
|
253
294
|
onGenerate={handleGenerateSubmit}
|
|
254
295
|
translations={{
|
|
255
296
|
resourceTitle: t.resourceTitle,
|
|
@@ -263,7 +304,7 @@ export function ReferenceWizardModal({
|
|
|
263
304
|
creativityCreative: t.creativityCreative,
|
|
264
305
|
maxLength: t.maxLength,
|
|
265
306
|
maxLengthHelp: t.maxLengthHelp,
|
|
266
|
-
|
|
307
|
+
maxLengthCeiling: t.maxLengthCeiling,
|
|
267
308
|
back: t.back,
|
|
268
309
|
generate: t.generate,
|
|
269
310
|
}}
|
|
@@ -272,15 +313,15 @@ export function ReferenceWizardModal({
|
|
|
272
313
|
|
|
273
314
|
{wizardStep.step === 'configure-search' && (
|
|
274
315
|
<ConfigureSearchStep
|
|
316
|
+
config={searchConfig}
|
|
317
|
+
onConfigChange={setSearchConfig}
|
|
275
318
|
isSearching={isSearching}
|
|
276
319
|
onBack={handleBackToGather}
|
|
277
|
-
onCancel={onClose}
|
|
278
320
|
onSearch={handleSearchSubmit}
|
|
279
321
|
translations={{
|
|
280
322
|
maxResults: t.maxResults,
|
|
281
323
|
semanticScoring: t.semanticScoring,
|
|
282
324
|
semanticScoringHelp: t.semanticScoringHelp,
|
|
283
|
-
cancel: t.cancel,
|
|
284
325
|
back: t.back,
|
|
285
326
|
search: t.search,
|
|
286
327
|
searching: t.searching,
|
|
@@ -294,12 +335,10 @@ export function ReferenceWizardModal({
|
|
|
294
335
|
context={context}
|
|
295
336
|
onLink={handleLink}
|
|
296
337
|
onBack={handleBackToGather}
|
|
297
|
-
onCancel={onClose}
|
|
298
338
|
translations={{
|
|
299
339
|
noResults: t.noResults,
|
|
300
340
|
link: t.link,
|
|
301
341
|
back: t.back,
|
|
302
|
-
cancel: t.cancel,
|
|
303
342
|
score: t.score,
|
|
304
343
|
sourceContextLabel: t.sourceContextLabel,
|
|
305
344
|
connectionsLabel: t.connectionsLabel,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useEffect, useCallback } from 'react';
|
|
4
|
+
import type { CollaboratorEntry } from '@semiont/core';
|
|
4
5
|
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from '@headlessui/react';
|
|
5
6
|
import { useResourceGather } from '../../hooks/useResourceGather';
|
|
6
7
|
import { ConfigureGatherStep, type ResourceGatherConfig } from './ConfigureGatherStep';
|
|
7
8
|
import { GatherContextStep } from './GatherContextStep';
|
|
8
|
-
import { ConfigureGenerationStep, type GenerationConfig } from './ConfigureGenerationStep';
|
|
9
|
+
import { ConfigureGenerationStep, type GenerationConfig, type GenerationDraft } from './ConfigureGenerationStep';
|
|
9
10
|
|
|
10
11
|
export interface ResourceGenerateModalTranslations {
|
|
11
12
|
// Step titles + nav
|
|
@@ -41,10 +42,17 @@ export interface ResourceGenerateModalTranslations {
|
|
|
41
42
|
creativityCreative: string;
|
|
42
43
|
maxLength: string;
|
|
43
44
|
maxLengthHelp: string;
|
|
45
|
+
maxLengthCeiling: string;
|
|
44
46
|
generate: string;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
export interface ResourceGenerateModalProps {
|
|
50
|
+
/**
|
|
51
|
+
* Roster entry serving `generation`, forwarded to ConfigureGenerationStep so
|
|
52
|
+
* the max-length control is bounded by the model's real output ceiling.
|
|
53
|
+
* Optional: absent means today's default bounds (INFERENCE-LIMITS-EXPOSURE D3).
|
|
54
|
+
*/
|
|
55
|
+
generationAgent?: CollaboratorEntry;
|
|
48
56
|
isOpen: boolean;
|
|
49
57
|
onClose: () => void;
|
|
50
58
|
resourceId: string;
|
|
@@ -58,8 +66,8 @@ export interface ResourceGenerateModalProps {
|
|
|
58
66
|
entityTypeOptions?: string[];
|
|
59
67
|
/**
|
|
60
68
|
* Emit the chosen generation config. The parent runs the job
|
|
61
|
-
* (`client.yield.
|
|
62
|
-
* annotation wizard delegates
|
|
69
|
+
* (`client.yield.fromContext(config.context, …)`) — mirrors how the
|
|
70
|
+
* annotation wizard delegates generation to its parent.
|
|
63
71
|
*/
|
|
64
72
|
onGenerateSubmit: (resourceId: string, config: GenerationConfig) => void;
|
|
65
73
|
translations: ResourceGenerateModalTranslations;
|
|
@@ -82,7 +90,15 @@ export function ResourceGenerateModal({
|
|
|
82
90
|
entityTypeOptions = [],
|
|
83
91
|
onGenerateSubmit,
|
|
84
92
|
translations: t,
|
|
93
|
+
generationAgent,
|
|
85
94
|
}: ResourceGenerateModalProps) {
|
|
95
|
+
// Same draft ownership as the wizard (WIZARD-NAVIGATION D3): the step is
|
|
96
|
+
// controlled, so stepping back through this modal keeps what was typed.
|
|
97
|
+
const [generationDraft, setGenerationDraft] = useState<GenerationDraft>({
|
|
98
|
+
title: defaultTitle, storagePath: '', prompt: '', language: locale,
|
|
99
|
+
temperature: 0.7, maxTokensText: '500',
|
|
100
|
+
});
|
|
101
|
+
|
|
86
102
|
const [step, setStep] = useState<Step>('configure-gather');
|
|
87
103
|
const { context, loading, error, gather, reset } = useResourceGather();
|
|
88
104
|
// Supplied by the owner, which already tracks the list with its failure
|
|
@@ -153,12 +169,12 @@ export function ResourceGenerateModal({
|
|
|
153
169
|
onGather={handleGather}
|
|
154
170
|
onCancel={onClose}
|
|
155
171
|
translations={{
|
|
172
|
+
cancel: t.cancel,
|
|
156
173
|
intro: t.gatherIntro,
|
|
157
174
|
includeContent: t.includeContent,
|
|
158
175
|
includeSummary: t.includeSummary,
|
|
159
176
|
depth: t.gatherDepth,
|
|
160
177
|
maxResources: t.gatherMaxResources,
|
|
161
|
-
cancel: t.cancel,
|
|
162
178
|
gather: t.gatherButton,
|
|
163
179
|
}}
|
|
164
180
|
>
|
|
@@ -230,11 +246,11 @@ export function ResourceGenerateModal({
|
|
|
230
246
|
|
|
231
247
|
{step === 'configure-generation' && context && (
|
|
232
248
|
<ConfigureGenerationStep
|
|
233
|
-
|
|
234
|
-
locale={locale}
|
|
249
|
+
{...(generationAgent ? { generationAgent } : {})}
|
|
235
250
|
context={context}
|
|
251
|
+
config={generationDraft}
|
|
252
|
+
onConfigChange={setGenerationDraft}
|
|
236
253
|
onBack={() => setStep('review')}
|
|
237
|
-
onCancel={onClose}
|
|
238
254
|
onGenerate={handleGenerate}
|
|
239
255
|
translations={{
|
|
240
256
|
resourceTitle: t.resourceTitle,
|
|
@@ -248,7 +264,7 @@ export function ResourceGenerateModal({
|
|
|
248
264
|
creativityCreative: t.creativityCreative,
|
|
249
265
|
maxLength: t.maxLength,
|
|
250
266
|
maxLengthHelp: t.maxLengthHelp,
|
|
251
|
-
|
|
267
|
+
maxLengthCeiling: t.maxLengthCeiling,
|
|
252
268
|
back: t.back,
|
|
253
269
|
generate: t.generate,
|
|
254
270
|
}}
|
|
@@ -77,7 +77,7 @@ export function ResourceSearchModal({
|
|
|
77
77
|
(q) =>
|
|
78
78
|
semiontRef.current!.browse.resources({ search: q, limit: SEARCH_LIMIT }).pipe(
|
|
79
79
|
map((st) => {
|
|
80
|
-
const resources = readyValue(st);
|
|
80
|
+
const resources = readyValue(st)?.resources;
|
|
81
81
|
if (resources === undefined) return undefined;
|
|
82
82
|
return resources
|
|
83
83
|
.map(toSearchResult)
|
|
@@ -503,10 +503,6 @@
|
|
|
503
503
|
font-weight: 500;
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
-
[data-theme="dark"] .semiont-gather__loading-text {
|
|
507
|
-
color: var(--semiont-text-secondary);
|
|
508
|
-
}
|
|
509
|
-
|
|
510
506
|
.semiont-gather__loading-dot {
|
|
511
507
|
display: inline-block;
|
|
512
508
|
width: 0.625rem;
|
|
@@ -599,10 +595,6 @@
|
|
|
599
595
|
margin-bottom: 0.5rem;
|
|
600
596
|
}
|
|
601
597
|
|
|
602
|
-
[data-theme="dark"] .semiont-gather__footer-label {
|
|
603
|
-
color: var(--semiont-text-tertiary);
|
|
604
|
-
}
|
|
605
|
-
|
|
606
598
|
.semiont-gather__actions {
|
|
607
599
|
display: flex;
|
|
608
600
|
flex-flow: row nowrap;
|
|
@@ -665,10 +657,6 @@
|
|
|
665
657
|
color: var(--semiont-color-primary-600);
|
|
666
658
|
}
|
|
667
659
|
|
|
668
|
-
[data-theme="dark"] .semiont-gather__expand-btn {
|
|
669
|
-
color: var(--semiont-text-tertiary);
|
|
670
|
-
}
|
|
671
|
-
|
|
672
660
|
[data-theme="dark"] .semiont-gather__expand-btn:hover {
|
|
673
661
|
color: var(--semiont-color-primary-400);
|
|
674
662
|
}
|