1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-10-09 12:55:00 +02:00

Merge branch 'summary-images-ui' into integration-all-three

This commit is contained in:
archivr-qa 2026-08-23 21:48:12 +02:00
commit ecc25af05a
No known key found for this signature in database
3 changed files with 62 additions and 2 deletions

View file

@ -42,13 +42,13 @@ export async function fetchEntrySummary(archiveId, entryUid) {
// caller polls fetchEntrySummary either way.
// The server returns 400 with the exact missing env var name when a provider is
// unconfigured, so its body is surfaced verbatim rather than replaced.
export async function requestEntrySummary(archiveId, entryUid, { provider, force = false } = {}) {
export async function requestEntrySummary(archiveId, entryUid, { provider, force = false, includeImages = false } = {}) {
const resp = await fetch(
`/api/archives/${archiveId}/entries/${entryUid}/summary`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ provider, force }),
body: JSON.stringify({ provider, force, include_images: includeImages }),
}
);
if (!resp.ok) {

View file

@ -69,6 +69,7 @@ export default function ContextRail({ archiveId, selectedEntry, selectedUids, se
return sessionStorage.getItem(SUMMARY_PROVIDER_KEY) || SUMMARY_PROVIDERS[0].value
} catch { return SUMMARY_PROVIDERS[0].value }
})
const [includeSummaryImages, setIncludeSummaryImages] = useState(false)
const summaryPollRef = useRef(null)
// ── Bulk-panel state ────────────────────────────────────────────────────
@ -129,6 +130,7 @@ export default function ContextRail({ archiveId, selectedEntry, selectedUids, se
setSummary(detail?.latest_summary ?? null)
setSummaryError('')
setSummaryBusy(false)
setIncludeSummaryImages(false)
}, [detail?.summary?.entry_uid])
// Poll only while the latest summary is non-terminal. Anchoring the effect on
@ -173,6 +175,7 @@ export default function ContextRail({ archiveId, selectedEntry, selectedUids, se
const res = await requestEntrySummary(archiveId, detail.summary.entry_uid, {
provider: summaryProvider,
force,
includeImages: includeSummaryImages,
})
if (res.status === 'completed') {
// 200 cache hit: the response *is* the row, no polling needed.
@ -192,6 +195,7 @@ export default function ContextRail({ archiveId, selectedEntry, selectedUids, se
function handleProviderChange(value) {
setSummaryProvider(value)
if (value === 'claude_cli') setIncludeSummaryImages(false)
try { sessionStorage.setItem(SUMMARY_PROVIDER_KEY, value) } catch { /* private mode */ }
}
@ -615,6 +619,22 @@ export default function ContextRail({ archiveId, selectedEntry, selectedUids, se
<option key={p.value} value={p.value}>{p.label}</option>
))}
</select>
<div className={`rail-summary-image-option${summaryProvider === 'claude_cli' ? ' rail-summary-image-option--disabled' : ''}`}>
<label className="rail-summary-image-option__label">
<input
type="checkbox"
checked={includeSummaryImages}
disabled={summaryProvider === 'claude_cli'}
onChange={e => setIncludeSummaryImages(e.target.checked)}
/>
Include attached images
</label>
<p className="rail-summary-image-option__note">
{summaryProvider === 'claude_cli'
? 'Claude CLI cannot attach local images. Choose an HTTP provider or Codex CLI.'
: 'Selected archived images are sent to the chosen provider. Up to 4 supported images (5 MiB each, 12 MiB total) can be attached; unsupported or oversized artifacts are skipped.'}
</p>
</div>
<button
className="rail-rearchive-btn"
onClick={() => handleGenerateSummary(!!parsed)}

View file

@ -3285,6 +3285,46 @@ body.has-audio-bar { padding-bottom: 56px; }
border: 1px solid var(--line);
border-radius: 4px;
}
.rail-summary-image-option {
padding: 7px 8px;
color: var(--muted);
background: var(--paper);
border: 1px solid var(--line);
border-radius: 4px;
}
.rail-summary-image-option__label {
display: flex;
align-items: center;
gap: 6px;
color: var(--ink);
font-size: 12.5px;
cursor: pointer;
}
.rail-summary-image-option__label input[type="checkbox"] {
margin: 0;
accent-color: var(--accent);
cursor: pointer;
}
.rail-summary-image-option__label input[type="checkbox"]:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.rail-summary-image-option__note {
margin: 5px 0 0;
font-size: 11px;
line-height: 1.4;
}
.rail-summary-image-option--disabled {
color: var(--muted-2);
background: var(--paper);
}
.rail-summary-image-option--disabled .rail-summary-image-option__label {
color: var(--muted-2);
cursor: not-allowed;
}
.rail-summary-image-option--disabled .rail-summary-image-option__label input[type="checkbox"] {
cursor: not-allowed;
}
/* ── Text / Markdown preview ────────────────────────────────────────────── */
.text-preview {