Files
chat_web_app/llm-fe/package.json
T
westfarn 3858b97104
Deploy Beta / unit-tests (push) Successful in 11s
Unit Tests / test (push) Successful in 12s
Deploy Beta / deploy-beta (push) Failing after 2m10s
Message actions + citation Sources (#97, #98) (#101)
## Summary
- Closes [#97](#97) — message action row: copy (raw markdown + code-block copy), thumbs up/down with optimistic updates + down-reason popover, and export menu (PDF / DOCX / CSV / XLSX / TXT) for a single message plus conversation-level export in the chat toolbar.
- Closes [#98](#98) — versioned WS `citations` frame parsing, Sources list under assistant bubbles, clickable `[n]` markers, and history hydrate from `Prompt.citations`.
- Backend companion for ratings: [chat_backend#67](ai_ml_operations/chat_backend#67). Thumbs UI posts to `prompt_feedback` once that lands; votes rehydrate from `conversation_details.feedback`.
- Export libs (`pdfmake`, `docx`, `papaparse`, `xlsx`) are dynamically imported so they stay out of the main path until used.

## Test plan
- [ ] Stream a grounded answer → Sources appear after stream; inline `[n]` highlights the matching source; reload keeps Sources.
- [ ] Non-grounded turn → no Sources header.
- [ ] Copy message + code block; confirm checkmark ~2s; failure path shows toast.
- [ ] Thumbs up/down optimistic UI; clear by re-click; down opens reason popover without blocking the vote (needs chat_backend#67).
- [ ] Export one message and whole conversation in all five formats; check searchable PDF text and DOCX structure.
- [ ] Action row: hover reveal on desktop, always visible on last/touch; hidden while streaming.
- [ ] `npm test -- --testPathPattern='wsFrames|clipboard|exportChat|promptFeedback|ConversationDetailCard'`Reviewed-on: #101
2026-08-04 03:32:17 -07:00

120 lines
3.8 KiB
JSON

{
"name": "llm-fe",
"version": "0.1.0",
"private": true,
"dependencies": {
"@capacitor/android": "^7.6.8",
"@capacitor/app": "^7.1.2",
"@capacitor/cli": "^7.6.8",
"@capacitor/core": "^7.6.8",
"@capacitor/ios": "^7.6.8",
"@capacitor/keyboard": "^7.0.6",
"@capacitor/preferences": "^7.0.4",
"@capacitor/status-bar": "^7.0.6",
"@emotion/cache": "^11.14.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@mui/icons-material": "^5.16.11",
"@mui/material": "^5.16.11",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0",
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.14",
"@types/node": "^22.10.2",
"@types/papaparse": "^5.5.2",
"@types/pdfmake": "^0.3.3",
"axios": "^1.13.2",
"babel-loader": "^9.2.1",
"bootstrap": "^5.3.3",
"brace-expansion": "file:vendor/brace-expansion-compat",
"chroma-js": "^3.1.2",
"docx": "^9.7.1",
"formik": "^2.4.6",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
"markdown-to-jsx": "^7.7.2",
"mini.css": "^3.0.1",
"papaparse": "^5.5.4",
"pdfmake": "^0.3.11",
"react-bootstrap": "^2.10.6",
"react-code-blocks": "^0.1.6",
"react-github-btn": "^1.4.0",
"react-router-dom": "^6.30.2",
"react-scripts": "^5.0.1",
"react-syntax-highlighter": "^15.6.1",
"recharts": "^2.15.1",
"styled-components": "6.1.15",
"stylis-plugin-rtl": "^2.1.1",
"web-vitals": "^4.2.4",
"webpack": "^5.97.1",
"webpack-cli": "^5.1.4",
"xlsx": "^0.18.5",
"yup": "^1.5.0"
},
"scripts": {
"start": "NODE_ENV=development react-scripts start",
"build": "NODE_ENV=production react-scripts build",
"build:prod": "NODE_ENV=production react-scripts build && mkdir -p /var/www/prod.chat.aimloperations/html && cp -r ./build/* /var/www/prod.chat.aimloperations/html/",
"build:beta": "bash -c 'set -a; source .env.beta; set +a; NODE_ENV=production react-scripts build' && mkdir -p /var/www/beta.chat.aimloperations/html && cp -r ./build/* /var/www/beta.chat.aimloperations/html/",
"build:mobile": "bash -c 'set -a; source .env.mobile; set +a; NODE_ENV=production react-scripts build' && npx cap sync",
"android:open": "npx cap open android",
"android:sync": "npx cap sync android",
"ios:open": "npx cap open ios",
"ios:sync": "npx cap sync ios",
"assets:generate": "npx capacitor-assets generate --ios --android",
"test": "NODE_ENV=development react-scripts test",
"test:ci": "CI=true NODE_ENV=development react-scripts test --watchAll=false --coverage=false",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@capacitor/assets": "^3.0.5",
"@testing-library/dom": "^10.4.1",
"@types/bootstrap": "~5.2.10",
"@types/lodash": "~4.17.13",
"@types/react": "^18.3.16",
"@types/react-dom": "^18.3.5",
"@types/react-google-recaptcha": "^2.1.9",
"@types/react-syntax-highlighter": "^15.5.13",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-google-recaptcha": "^3.1.0",
"typescript": "^4.9.5"
},
"overrides": {
"tar": "7.5.22",
"underscore": "1.13.8",
"nth-check": "2.1.1",
"postcss": "8.5.25",
"serialize-javascript": "7.0.7",
"svgo": "2.8.3",
"sharp": "0.35.3",
"brace-expansion": "file:vendor/brace-expansion-compat",
"minimatch": "3.1.5",
"uuid": "11.1.1",
"prismjs": "1.30.0",
"bfj": "9.1.3",
"form-data": "4.0.6",
"ws": "8.21.1",
"flatted": "3.4.3",
"@tootallnate/once": "3.0.1"
}
}