Skip to content

Phase 4 production hardening - #18

Merged
FarhadShariatzadeh merged 14 commits into
mainfrom
phase-4-production-hardening
May 3, 2026
Merged

FarhadShariatzadeh merged 14 commits into
mainfrom
phase-4-production-hardening

Conversation

@FarhadShariatzadeh

Copy link
Copy Markdown
Owner

No description provided.

Farhad Shariatzadeh and others added 14 commits May 1, 2026 16:26
Without this, published binaries fall back to port 5000 since
launchSettings.json is dev-only and not included in publish output.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…se zip

- Program.cs reads .env from exe directory before host builds, so users
  never need to set environment variables manually in a terminal
- .env.example variables corrected to ASP.NET Core format (OpenAI__ApiKey
  not OPENAI_API_KEY) so they map to the right config sections
- Release workflow copies .env.example as .env into every zip artifact
- Release notes updated with the new 4-step double-click flow

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
AppContext.BaseDirectory resolves to the temp extraction directory for
single-file apps, not the exe location. Use Environment.ProcessPath to
get the actual exe path so .env is found next to the binary.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…root

- StackPilot.UI: React 18 + Vite + Tailwind CSS dark-theme SPA
- Chat page: stateful multi-turn conversation with session management
- Playground page: document ingestion + RAG Q&A with source display
- Agent page: single-shot and reasoning-loop modes with collapsible trace
- Sidebar: navigation + live health indicator
- Vite builds directly into StackPilot.Api/wwwroot
- Program.cs: UseDefaultFiles + UseStaticFiles + MapFallbackToFile
- Release workflow: Node 20 + npm ci + npm run build before dotnet publish
- .gitignore: exclude node_modules and wwwroot build output

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…tructure

- WebApplicationOptions.ContentRootPath/WebRootPath set to exe directory
  so ASP.NET Core finds wwwroot next to the binary instead of temp dir
- Release workflow zip changed from -j (flatten) to -r (recursive) so
  wwwroot/ directory structure is preserved inside the archive

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…imit

Single large ingestion requests were hitting the max_tokens_per_request
limit. Batching at 96 keeps each request well under the cap regardless
of chunk size.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- LogsPage: dedicated log ingestion tab with drag-and-drop file zone,
  file picker (txt/log/csv/json/yaml/md), paste fallback
- Immediate mode: POST /store, shows chunk count on success
- Background mode: POST /store/async, polls /jobs/{jobId} every 1.5s
  with live status badge (Queued → Processing → Completed/Failed)
- Sidebar: Logs tab added between Playground and Agent
- api/client.ts: storeAsync + pollJob calls, corrected StoreResult type
- PlaygroundPage: fixed StoreResult display to use .stored/.ids
- EmbeddingService: batch at 96 chunks to stay under OpenAI 300k limit

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…ation

- IVectorStore.Clear() method + InMemory and Qdrant implementations
- DELETE /store endpoint returns { cleared: N } chunk count
- Logs page: ClearStorePanel with two-step confirmation (click → confirm)
  shows chunk count cleared on success, red-bordered danger zone styling

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- AppStateContext: shared React context holding chat state and ingest history
- ChatPage: reads/writes from context — messages survive tab navigation
- LogsPage: records each successful ingest (filename, size, chunks, time)
  and displays them in a history list; clear history button available
- App.tsx: wrapped with AppStateProvider

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Backend:
- StoreRequest now accepts optional Source field; stored as metadata[source]
- IngestionJob + IngestionWorker thread Source through to metadata
- New DELETE /store/by-source/{source} endpoint — deletes all chunks with matching source

Frontend:
- api/client.ts: store/storeAsync accept optional source, add deleteBySource()
- AppState: IngestRecord gets source field, new removeIngestRecord(id) function
- LogsPage: pass filename as source on ingest; per-history-item delete button with
  inline Yes/No confirmation; ClearStorePanel now calls clearIngestHistory() so the
  UI list clears when the vector store is wiped
- ChatPage: fix stale closure bug — user message was overwritten by assistant reply
  because the second setChat used the pre-await snapshot of chat.messages

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@FarhadShariatzadeh
FarhadShariatzadeh merged commit 4cf9320 into main May 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant