wadi 1.0.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/.agent/workflows/auto_sync.md +19 -0
- package/.agent/workflows/kivo_pipeline.md +27 -0
- package/.devcontainer/devcontainer.json +27 -0
- package/.github/workflows/kivo-cicd.yml +45 -0
- package/.github/workflows/monorepo-ci.yml +51 -0
- package/.github/workflows/wadi-ci.yml +38 -0
- package/.husky/pre-commit +2 -0
- package/.prettierignore +12 -0
- package/.prettierrc +9 -0
- package/.vscode/settings.json +19 -0
- package/CHANGELOG.md +56 -0
- package/CODE_OF_CONDUCT.md +43 -0
- package/CONTRIBUTING.md +42 -0
- package/DEPLOY_GUIDE.md +143 -0
- package/GO_LIVE_CHECKLIST.md +41 -0
- package/GO_LIVE_COMPLETE_REPORT.md +58 -0
- package/GO_LIVE_VALIDATION.md +39 -0
- package/LEGAL.md +38 -0
- package/MANIFESTO.md +40 -0
- package/MANUAL.md +82 -0
- package/OPS_PLAN.md +90 -0
- package/README.md +126 -0
- package/RELEASE_NOTES.md +51 -0
- package/ROADMAP.md +51 -0
- package/api_listado.txt +2197 -0
- package/apps/api/WADI_PROTOCOL.md +52 -0
- package/apps/api/debug-brain.js +11 -0
- package/apps/api/package.json +21 -0
- package/apps/api/src/core/analisis.js +17 -0
- package/apps/api/src/core/errors.js +31 -0
- package/apps/api/src/core/logger.js +32 -0
- package/apps/api/src/core/prompt-kivo.js +62 -0
- package/apps/api/src/index.js +212 -0
- package/apps/api/src/layers/human_pattern/composeResponse.js +35 -0
- package/apps/api/src/layers/human_pattern/detectPattern.js +39 -0
- package/apps/api/src/layers/human_pattern/heuristics.js +28 -0
- package/apps/api/src/layers/human_pattern/index.js +28 -0
- package/apps/api/src/layers/human_pattern/socialMemory.js +35 -0
- package/apps/api/src/middleware/errorHandler.js +24 -0
- package/apps/api/src/middleware/rateLimiter.js +38 -0
- package/apps/api/src/middleware/requestLogger.js +31 -0
- package/apps/api/src/middleware/upload.js +21 -0
- package/apps/api/src/middleware/validation.js +70 -0
- package/apps/api/src/modules/data.js +25 -0
- package/apps/api/src/modules/marketing.js +54 -0
- package/apps/api/src/modules/projects.js +40 -0
- package/apps/api/src/openai.js +16 -0
- package/apps/api/src/preferences/index.js +20 -0
- package/apps/api/src/register_user.js +22 -0
- package/apps/api/src/routes/kivo.js +58 -0
- package/apps/api/src/routes/monitoring.js +55 -0
- package/apps/api/src/routes.js +656 -0
- package/apps/api/src/supabase.js +17 -0
- package/apps/api/src/tools/index.js +57 -0
- package/apps/api/src/wadi-brain.js +171 -0
- package/apps/api/supabase/migrations/20251218_audit_logs.sql +27 -0
- package/apps/api/supabase/migrations/v2-chat-persistence.sql +83 -0
- package/apps/api/supabase/migrations/v3-cascade-delete.sql +11 -0
- package/apps/api/supabase/migrations/v3-security-fix.sql +90 -0
- package/apps/api/supabase/migrations/v3-storage.sql +36 -0
- package/apps/api/supabase/migrations/v4-gamification.sql +83 -0
- package/apps/api/supabase/migrations/v5-smoke-index.sql +6 -0
- package/apps/api/supabase/migrations/v6-schema-integrity-fix.sql +98 -0
- package/apps/api/supabase/migrations/v7-performance-indexes.sql +5 -0
- package/apps/api/supabase/migrations/v7-security-hardening.sql +132 -0
- package/apps/api/supabase/migrations/v8-security-hardening.sql +79 -0
- package/apps/api/test_human_pattern.js +30 -0
- package/apps/api/test_human_pattern_vague.js +30 -0
- package/apps/api/test_output.txt +76 -0
- package/apps/api/test_vague.js +30 -0
- package/apps/api/test_vague_block.js +30 -0
- package/apps/api/test_wadi.js +31 -0
- package/apps/api/tsconfig.json +13 -0
- package/apps/frontend/.env.local +3 -0
- package/apps/frontend/README.md +73 -0
- package/apps/frontend/eslint.config.js +27 -0
- package/apps/frontend/index.html +49 -0
- package/apps/frontend/package.json +41 -0
- package/apps/frontend/postcss.config.cjs +6 -0
- package/apps/frontend/public/cursors/wadi-neutral.svg +1 -0
- package/apps/frontend/public/cursors/wadi-select.svg +1 -0
- package/apps/frontend/public/icon-192.svg +1 -0
- package/apps/frontend/public/icon-512.svg +1 -0
- package/apps/frontend/public/manifest.webmanifest +23 -0
- package/apps/frontend/public/sw.js +57 -0
- package/apps/frontend/public/vite.svg +1 -0
- package/apps/frontend/public/wadi.svg +5 -0
- package/apps/frontend/src/assets/react.svg +1 -0
- package/apps/frontend/src/components/AuthLoader.tsx +50 -0
- package/apps/frontend/src/components/ChatInput.tsx +272 -0
- package/apps/frontend/src/components/ChatInterface.tsx +202 -0
- package/apps/frontend/src/components/ErrorBoundary.tsx +52 -0
- package/apps/frontend/src/components/InputArea.tsx +201 -0
- package/apps/frontend/src/components/Layout.tsx +73 -0
- package/apps/frontend/src/components/MessageBubble.tsx +66 -0
- package/apps/frontend/src/components/OnboardingModal.tsx +108 -0
- package/apps/frontend/src/components/SettingsModal.tsx +187 -0
- package/apps/frontend/src/components/Sidebar.tsx +171 -0
- package/apps/frontend/src/components/WadiOnboarding.tsx +71 -0
- package/apps/frontend/src/components/auditor/AuditReport.tsx +166 -0
- package/apps/frontend/src/components/auditor/AuditorHeader.tsx +34 -0
- package/apps/frontend/src/components/auditor/ContextPanel.tsx +138 -0
- package/apps/frontend/src/components/auditor/DataDeconstructor.tsx +85 -0
- package/apps/frontend/src/components/auditor/DecisionWall.tsx +65 -0
- package/apps/frontend/src/components/auditor/Dropzone.tsx +137 -0
- package/apps/frontend/src/components/common/Button.tsx +97 -0
- package/apps/frontend/src/components/common/Card.tsx +43 -0
- package/apps/frontend/src/components/common/Input.tsx +73 -0
- package/apps/frontend/src/components/common/Modal.tsx +53 -0
- package/apps/frontend/src/components/ui/Button.tsx +68 -0
- package/apps/frontend/src/components/ui/Card.tsx +86 -0
- package/apps/frontend/src/components/ui/Input.tsx +28 -0
- package/apps/frontend/src/components/ui/LogItem.tsx +64 -0
- package/apps/frontend/src/components/ui/MondayButton.tsx +40 -0
- package/apps/frontend/src/components/ui/MondayCard.tsx +24 -0
- package/apps/frontend/src/components/ui/Scouter.tsx +208 -0
- package/apps/frontend/src/components/ui/TerminalInput.tsx +202 -0
- package/apps/frontend/src/components/ui/Tooltip.tsx +67 -0
- package/apps/frontend/src/config/chatShortcuts.ts +20 -0
- package/apps/frontend/src/config/supabase.ts +6 -0
- package/apps/frontend/src/final_status.txt +3 -0
- package/apps/frontend/src/hooks/useScouter.ts +28 -0
- package/apps/frontend/src/hooks/useStoreHydration.ts +24 -0
- package/apps/frontend/src/improvement_status.txt +5 -0
- package/apps/frontend/src/index.css +88 -0
- package/apps/frontend/src/main.tsx +62 -0
- package/apps/frontend/src/monday_status.txt +7 -0
- package/apps/frontend/src/pages/ChatPage.tsx +201 -0
- package/apps/frontend/src/pages/DashboardPage.tsx +375 -0
- package/apps/frontend/src/pages/IntroWadi.tsx +114 -0
- package/apps/frontend/src/pages/LandingPage.tsx +103 -0
- package/apps/frontend/src/pages/Login.tsx +190 -0
- package/apps/frontend/src/pages/PrivacyPage.tsx +213 -0
- package/apps/frontend/src/pages/ProjectDetail.tsx +80 -0
- package/apps/frontend/src/pages/Projects.tsx +247 -0
- package/apps/frontend/src/pages/TermsPage.tsx +202 -0
- package/apps/frontend/src/router.tsx +83 -0
- package/apps/frontend/src/store/authStore.ts +152 -0
- package/apps/frontend/src/store/chatStore.ts +837 -0
- package/apps/frontend/src/store/documentStore.ts +89 -0
- package/apps/frontend/src/store/projectsStore.ts +111 -0
- package/apps/frontend/src/store/runsStore.ts +98 -0
- package/apps/frontend/src/utils/api.ts +34 -0
- package/apps/frontend/src/vite-env.d.ts +7 -0
- package/apps/frontend/tailwind.config.cjs +32 -0
- package/apps/frontend/tsconfig.app.json +27 -0
- package/apps/frontend/tsconfig.json +7 -0
- package/apps/frontend/tsconfig.node.json +26 -0
- package/apps/frontend/vite.config.ts +25 -0
- package/apps/kivo/.firebase/hosting.d3d3.cache +11 -0
- package/apps/kivo/.firebaserc +5 -0
- package/apps/kivo/BRANDING_GUIDE.md +71 -0
- package/apps/kivo/DEPLOYMENT_READY.md +46 -0
- package/apps/kivo/DEPLOY_URL.md +12 -0
- package/apps/kivo/IMPLEMENTATION_REPORT.md +35 -0
- package/apps/kivo/IMPLEMENTATION_REPORT_FINAL.md +49 -0
- package/apps/kivo/PLAN_MOBILE_2.0.md +44 -0
- package/apps/kivo/PWA_VERIFICATION_GUIDE.md +77 -0
- package/apps/kivo/README.md +28 -0
- package/apps/kivo/REBUILD_REPORT.md +34 -0
- package/apps/kivo/UPGRADE_REPORT.md +35 -0
- package/apps/kivo/android/app/build.gradle +54 -0
- package/apps/kivo/android/app/capacitor.build.gradle +19 -0
- package/apps/kivo/android/app/proguard-rules.pro +21 -0
- package/apps/kivo/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +26 -0
- package/apps/kivo/android/app/src/main/AndroidManifest.xml +35 -0
- package/apps/kivo/android/app/src/main/java/com/kivo/app/MainActivity.java +5 -0
- package/apps/kivo/android/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
- package/apps/kivo/android/app/src/main/res/drawable/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-ldpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-night-hdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-night-ldpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-night-mdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-night-xhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-night-xxhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-night/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-ldpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-night-hdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-night-ldpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-night-mdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-night-xhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-night-xxhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
- package/apps/kivo/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +34 -0
- package/apps/kivo/android/app/src/main/res/layout/activity_main.xml +12 -0
- package/apps/kivo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +9 -0
- package/apps/kivo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +9 -0
- package/apps/kivo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-ldpi/ic_launcher.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/apps/kivo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/apps/kivo/android/app/src/main/res/values/ic_launcher_background.xml +4 -0
- package/apps/kivo/android/app/src/main/res/values/strings.xml +7 -0
- package/apps/kivo/android/app/src/main/res/values/styles.xml +22 -0
- package/apps/kivo/android/app/src/main/res/xml/file_paths.xml +5 -0
- package/apps/kivo/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +18 -0
- package/apps/kivo/android/build.gradle +29 -0
- package/apps/kivo/android/capacitor.settings.gradle +3 -0
- package/apps/kivo/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/apps/kivo/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/apps/kivo/android/gradle.properties +22 -0
- package/apps/kivo/android/gradlew +252 -0
- package/apps/kivo/android/gradlew.bat +94 -0
- package/apps/kivo/android/settings.gradle +5 -0
- package/apps/kivo/android/variables.gradle +16 -0
- package/apps/kivo/assets/icon.png +0 -0
- package/apps/kivo/assets/splash.png +0 -0
- package/apps/kivo/capacitor.config.json +16 -0
- package/apps/kivo/firebase.json +6 -0
- package/apps/kivo/jest.config.js +4 -0
- package/apps/kivo/package.json +26 -0
- package/apps/kivo/tests_disabled/logic.test.js +34 -0
- package/apps/kivo/www/assets/icon-192.png +0 -0
- package/apps/kivo/www/assets/icon-512.png +0 -0
- package/apps/kivo/www/assets/kivo-icon.png +0 -0
- package/apps/kivo/www/assets/pop.mp3 +0 -0
- package/apps/kivo/www/favicon.ico +0 -0
- package/apps/kivo/www/firebase-config.js +75 -0
- package/apps/kivo/www/index.html +38 -0
- package/apps/kivo/www/manifest.json +29 -0
- package/apps/kivo/www/script.js +72 -0
- package/apps/kivo/www/style.css +82 -0
- package/apps/kivo/www/sw.js +46 -0
- package/apps/kivo-brain-api/.env.example +2 -0
- package/apps/kivo-brain-api/KIVO_BACKEND_SETUP.md +27 -0
- package/apps/kivo-brain-api/controllers/kivoController.js +31 -0
- package/apps/kivo-brain-api/index.js +24 -0
- package/apps/kivo-brain-api/package.json +17 -0
- package/apps/kivo-brain-api/routes/message.js +8 -0
- package/apps/kivo-brain-api/services/openaiService.js +64 -0
- package/apps/tests/wadi-tests.js +155 -0
- package/apps/wadi-brain/docs/README_REMOVE_OPTIONS.md +26 -0
- package/cli/commands/deploy.js +10 -0
- package/cli/commands/docs.js +16 -0
- package/cli/commands/explain.js +29 -0
- package/cli/commands/lint.js +14 -0
- package/cli/index.js +26 -0
- package/cli/package.json +12 -0
- package/docs/CNAME +1 -0
- package/docs/README.md +38 -0
- package/docs/USO.md +30 -0
- package/docs/index.html +46 -0
- package/eslint.config.js +101 -0
- package/final_validation.json +27 -0
- package/frontend_listado.txt +33387 -0
- package/listado.txt +12591 -0
- package/package.json +46 -0
- package/packages/logger/index.js +43 -0
- package/packages/logger/package.json +19 -0
- package/packages/logger/test-logger.js +7 -0
- package/packages_listado.txt +801 -0
- package/pnpm-workspace.yaml +6 -0
- package/reseteador_existencial.ps1 +40 -0
- package/scripts/bump-version.js +26 -0
- package/scripts/env.ps1 +13 -0
- package/scripts/setup_android.ps1 +25 -0
- package/scripts/setup_virtual_env.ps1 +77 -0
- package/scripts/smoke-test.js +84 -0
- package/scripts/trigger_render_deploy.ps1 +3 -0
- package/scripts/validate-release.js +34 -0
- package/temp_check.js +57 -0
- package/tsconfig.json +5 -0
- package/validation_report.json +27 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"appId": "com.kivo.chat",
|
|
3
|
+
"appName": "Kivo",
|
|
4
|
+
"webDir": "www",
|
|
5
|
+
"bundledWebRuntime": false,
|
|
6
|
+
"server": {
|
|
7
|
+
"androidScheme": "https"
|
|
8
|
+
},
|
|
9
|
+
"plugins": {
|
|
10
|
+
"SplashScreen": {
|
|
11
|
+
"launchShowDuration": 1500,
|
|
12
|
+
"backgroundColor": "#ffffff",
|
|
13
|
+
"showSpinner": false
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kivo",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Kivo - Tu compañero emocional inteligente",
|
|
5
|
+
"main": "script.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo tests disabled",
|
|
8
|
+
"build": "echo 'No build step required for Kivo PWA'",
|
|
9
|
+
"start": "npx serve www"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@capacitor/android": "^7.4.4",
|
|
16
|
+
"@capacitor/cli": "^7.4.4",
|
|
17
|
+
"@capacitor/core": "^7.4.4",
|
|
18
|
+
"firebase": "^9.23.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@capacitor/assets": "^3.0.5",
|
|
22
|
+
"jest": "^30.2.0",
|
|
23
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
24
|
+
"serve": "^14.2.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* eslint-env jest */
|
|
2
|
+
const { detectarModo, detectarSubmodo } = require("../www/script.js");
|
|
3
|
+
|
|
4
|
+
describe("Kivo Logic Tests", () => {
|
|
5
|
+
describe("detectarModo", () => {
|
|
6
|
+
test("should detect technical mode", () => {
|
|
7
|
+
expect(detectarModo("validar sistema")).toBe("tecnico");
|
|
8
|
+
expect(detectarModo("debug error")).toBe("tecnico");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("should detect emotional mode", () => {
|
|
12
|
+
expect(detectarModo("me siento triste")).toBe("emocional");
|
|
13
|
+
expect(detectarModo("tengo ansiedad")).toBe("emocional");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("should return neutral for other inputs", () => {
|
|
17
|
+
expect(detectarModo("hola que tal")).toBe("neutro");
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe("detectarSubmodo", () => {
|
|
22
|
+
test("should detect reflexive submode", () => {
|
|
23
|
+
expect(detectarSubmodo("estuve pensando mucho")).toBe("reflexivo");
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("should detect creative submode", () => {
|
|
27
|
+
expect(detectarSubmodo("tengo una idea nueva")).toBe("creativo");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("should return null for other inputs", () => {
|
|
31
|
+
expect(detectarSubmodo("nada especial")).toBeNull();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// =============================
|
|
2
|
+
// CONFIGURACIÓN DE FIREBASE
|
|
3
|
+
// =============================
|
|
4
|
+
const firebaseConfig = {
|
|
5
|
+
apiKey: "AIzaSyAweaSvXfHYyArsnjI-G7NhP82YP5Azu-g",
|
|
6
|
+
authDomain: "kivo-8c62e.firebaseapp.com",
|
|
7
|
+
projectId: "kivo-8c62e",
|
|
8
|
+
storageBucket: "kivo-8c62e.appspot.com",
|
|
9
|
+
messagingSenderId: "118749642871",
|
|
10
|
+
appId: "1:118749642871:web:28a152eccf323981c64672",
|
|
11
|
+
measurementId: "G-HQ4WK0N2XT",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// Inicializar Firebase
|
|
15
|
+
firebase.initializeApp(firebaseConfig);
|
|
16
|
+
|
|
17
|
+
// Firestore y Auth
|
|
18
|
+
const db = firebase.firestore();
|
|
19
|
+
const auth = firebase.auth();
|
|
20
|
+
|
|
21
|
+
// =============================
|
|
22
|
+
// AUTENTICACIÓN ANÓNIMA
|
|
23
|
+
// =============================
|
|
24
|
+
auth.signInAnonymously().catch((error) => {
|
|
25
|
+
console.error("Error en autenticación anónima:", error);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// =============================
|
|
29
|
+
// INICIALIZACIÓN FIRESTORE
|
|
30
|
+
// =============================
|
|
31
|
+
async function inicializarFirestore(uid) {
|
|
32
|
+
try {
|
|
33
|
+
const docRef = db.collection("usuarios").doc(uid);
|
|
34
|
+
|
|
35
|
+
await docRef.set(
|
|
36
|
+
{
|
|
37
|
+
perfil: { voz: "emocional" },
|
|
38
|
+
historialEmocional: [
|
|
39
|
+
{
|
|
40
|
+
mensaje: "Inicio de historial emocional.",
|
|
41
|
+
emocion: "neutral",
|
|
42
|
+
modo: "emocional",
|
|
43
|
+
etiqueta: "normal",
|
|
44
|
+
timestamp: new Date().toISOString(),
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
{ merge: true }
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
console.log("Documento inicial creado correctamente.");
|
|
52
|
+
} catch (err) {
|
|
53
|
+
console.error("Error inicializando Firestore:", err);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// =============================
|
|
58
|
+
// LISTENER DE AUTH
|
|
59
|
+
// =============================
|
|
60
|
+
auth.onAuthStateChanged((user) => {
|
|
61
|
+
if (user) {
|
|
62
|
+
console.log("Usuario autenticado:", user.uid);
|
|
63
|
+
|
|
64
|
+
db.collection("usuarios")
|
|
65
|
+
.doc(user.uid)
|
|
66
|
+
.get()
|
|
67
|
+
.then((doc) => {
|
|
68
|
+
if (!doc.exists) inicializarFirestore(user.uid);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
if (typeof cargarUsuario === "function") {
|
|
72
|
+
cargarUsuario(user.uid);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="es">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Kivo</title>
|
|
7
|
+
<link rel="stylesheet" href="./style.css" />
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
|
|
12
|
+
<!-- Pantalla de Inicio -->
|
|
13
|
+
<div id="intro-screen" class="inicio-container">
|
|
14
|
+
<h1>Kivo</h1>
|
|
15
|
+
<p>Del caos al orden.</p>
|
|
16
|
+
<button id="start-btn">Empezar</button>
|
|
17
|
+
<a href="#">Política de Privacidad</a>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<!-- Pantalla del Chat -->
|
|
21
|
+
<div id="chat-screen" class="chat-section-container" style="display: none;">
|
|
22
|
+
<div id="chat-window" class="chat-window"></div>
|
|
23
|
+
|
|
24
|
+
<div class="input-section">
|
|
25
|
+
<input id="user-input" type="text" placeholder="Escribe algo..." />
|
|
26
|
+
<button id="send-btn">➤</button>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<!-- Firebase -->
|
|
31
|
+
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>
|
|
32
|
+
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-auth.js"></script>
|
|
33
|
+
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-firestore.js"></script>
|
|
34
|
+
|
|
35
|
+
<script src="./firebase-config.js"></script>
|
|
36
|
+
<script src="./script.js"></script>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Kivo",
|
|
3
|
+
"short_name": "Kivo",
|
|
4
|
+
"start_url": "./index.html",
|
|
5
|
+
"display": "standalone",
|
|
6
|
+
"background_color": "#F7F6F2",
|
|
7
|
+
"theme_color": "#F7F6F2",
|
|
8
|
+
"orientation": "portrait",
|
|
9
|
+
"icons": [
|
|
10
|
+
{
|
|
11
|
+
"src": "./assets/icon-192.png",
|
|
12
|
+
"sizes": "192x192",
|
|
13
|
+
"type": "image/png",
|
|
14
|
+
"purpose": "any maskable"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"src": "./assets/icon-512.png",
|
|
18
|
+
"sizes": "512x512",
|
|
19
|
+
"type": "image/png",
|
|
20
|
+
"purpose": "any maskable"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"src": "./assets/kivo-icon.png",
|
|
24
|
+
"sizes": "192x192",
|
|
25
|
+
"type": "image/png",
|
|
26
|
+
"purpose": "any"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
2
|
+
const API_ENDPOINT = "https://wadi-wxg7.onrender.com/api/kivo/chat";
|
|
3
|
+
|
|
4
|
+
const startBtn = document.getElementById("start-btn");
|
|
5
|
+
const introScreen = document.getElementById("intro-screen");
|
|
6
|
+
const chatScreen = document.getElementById("chat-screen");
|
|
7
|
+
|
|
8
|
+
const chatWindow = document.getElementById("chat-window");
|
|
9
|
+
const sendBtn = document.getElementById("send-btn");
|
|
10
|
+
const userInput = document.getElementById("user-input");
|
|
11
|
+
|
|
12
|
+
if (!startBtn || !introScreen || !chatScreen) {
|
|
13
|
+
console.error("ERROR: elementos esenciales no encontrados en DOM.");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
startBtn.onclick = () => {
|
|
18
|
+
introScreen.style.display = "none";
|
|
19
|
+
chatScreen.style.display = "flex";
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
sendBtn.onclick = sendMessage;
|
|
23
|
+
userInput.addEventListener("keypress", (e) => {
|
|
24
|
+
if (e.key === "Enter") sendMessage();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
function addMessage(text, sender = "user") {
|
|
28
|
+
const msg = document.createElement("div");
|
|
29
|
+
msg.classList.add("message", sender);
|
|
30
|
+
msg.textContent = text;
|
|
31
|
+
chatWindow.appendChild(msg);
|
|
32
|
+
chatWindow.scrollTop = chatWindow.scrollHeight;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function sendMessage() {
|
|
36
|
+
const text = userInput.value.trim();
|
|
37
|
+
if (!text) return;
|
|
38
|
+
|
|
39
|
+
addMessage(text, "user");
|
|
40
|
+
userInput.value = "";
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const response = await fetch(API_ENDPOINT, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: { "Content-Type": "application/json" },
|
|
46
|
+
body: JSON.stringify({ message: text }),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const data = await response.json().catch(() => ({}));
|
|
50
|
+
|
|
51
|
+
if (!response.ok) throw new Error(data.error || "Error en el servidor");
|
|
52
|
+
addMessage(data.reply || "Sin respuesta del servidor", "kivo");
|
|
53
|
+
} catch (err) {
|
|
54
|
+
addMessage(`Error: ${err.message}`, "kivo");
|
|
55
|
+
console.error(err);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if ("serviceWorker" in navigator) {
|
|
60
|
+
navigator.serviceWorker.register("./sw.js").catch(console.error);
|
|
61
|
+
}
|
|
62
|
+
// Keep-alive pinger due to Render free tier sleep
|
|
63
|
+
const KEEP_ALIVE_URL = "https://wadi-wxg7.onrender.com/system/health";
|
|
64
|
+
setInterval(
|
|
65
|
+
() => {
|
|
66
|
+
fetch(KEEP_ALIVE_URL)
|
|
67
|
+
.then((res) => console.log(`Keep-alive ping: ${res.status}`))
|
|
68
|
+
.catch((err) => console.error("Keep-alive failed", err));
|
|
69
|
+
},
|
|
70
|
+
4 * 60 * 1000
|
|
71
|
+
); // 4 minutes
|
|
72
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
body {
|
|
2
|
+
margin: 0;
|
|
3
|
+
padding: 0;
|
|
4
|
+
font-family: Arial, sans-serif;
|
|
5
|
+
background: #111;
|
|
6
|
+
color: #fff;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.screen {
|
|
10
|
+
width: 100%;
|
|
11
|
+
height: 100vh;
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
align-items: center;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#start-btn {
|
|
19
|
+
margin-top: 20px;
|
|
20
|
+
padding: 12px 25px;
|
|
21
|
+
font-size: 18px;
|
|
22
|
+
border: none;
|
|
23
|
+
background: #0af;
|
|
24
|
+
color: #000;
|
|
25
|
+
border-radius: 8px;
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#chat-window {
|
|
30
|
+
width: 100%;
|
|
31
|
+
height: calc(100vh - 70px);
|
|
32
|
+
padding: 20px;
|
|
33
|
+
overflow-y: auto;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
gap: 12px;
|
|
37
|
+
box-sizing: border-box;
|
|
38
|
+
background: #1b1b1b;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.message {
|
|
42
|
+
max-width: 75%;
|
|
43
|
+
padding: 12px 15px;
|
|
44
|
+
border-radius: 10px;
|
|
45
|
+
font-size: 16px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.message.user {
|
|
49
|
+
align-self: flex-end;
|
|
50
|
+
background: #0af;
|
|
51
|
+
color: #000;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.message.kivo {
|
|
55
|
+
align-self: flex-start;
|
|
56
|
+
background: #333;
|
|
57
|
+
color: #fff;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
#input-box {
|
|
61
|
+
width: 100%;
|
|
62
|
+
height: 70px;
|
|
63
|
+
display: flex;
|
|
64
|
+
border-top: 2px solid #222;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#user-input {
|
|
68
|
+
flex: 1;
|
|
69
|
+
padding: 10px;
|
|
70
|
+
background: #222;
|
|
71
|
+
color: white;
|
|
72
|
+
border: none;
|
|
73
|
+
font-size: 16px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
#send-btn {
|
|
77
|
+
width: 80px;
|
|
78
|
+
background: #0af;
|
|
79
|
+
color: #000;
|
|
80
|
+
border: none;
|
|
81
|
+
cursor: pointer;
|
|
82
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const CACHE_NAME = "kivo-v9";
|
|
2
|
+
const urlsToCache = [
|
|
3
|
+
"./",
|
|
4
|
+
"./index.html",
|
|
5
|
+
"./style.css",
|
|
6
|
+
"./script.js",
|
|
7
|
+
"./firebase-config.js",
|
|
8
|
+
"./manifest.json",
|
|
9
|
+
"./favicon.ico",
|
|
10
|
+
"./assets/icon-192.png",
|
|
11
|
+
"./assets/icon-512.png",
|
|
12
|
+
"./assets/kivo-icon.png",
|
|
13
|
+
"./assets/pop.mp3",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
self.addEventListener("install", (event) => {
|
|
17
|
+
self.skipWaiting(); // Force waiting service worker to become active
|
|
18
|
+
event.waitUntil(
|
|
19
|
+
caches.open(CACHE_NAME).then((cache) => {
|
|
20
|
+
return cache.addAll(urlsToCache);
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
self.addEventListener("fetch", (event) => {
|
|
26
|
+
event.respondWith(
|
|
27
|
+
caches.match(event.request).then((response) => {
|
|
28
|
+
return response || fetch(event.request);
|
|
29
|
+
})
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
self.addEventListener("activate", (event) => {
|
|
34
|
+
const cacheWhitelist = [CACHE_NAME];
|
|
35
|
+
event.waitUntil(
|
|
36
|
+
caches.keys().then((cacheNames) => {
|
|
37
|
+
return Promise.all(
|
|
38
|
+
cacheNames.map((cacheName) => {
|
|
39
|
+
if (cacheWhitelist.indexOf(cacheName) === -1) {
|
|
40
|
+
return caches.delete(cacheName);
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
).then(() => self.clients.claim()); // Take control of all clients immediately
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Kivo Backend Setup
|
|
2
|
+
|
|
3
|
+
## Configuración Local
|
|
4
|
+
|
|
5
|
+
1. Copiar `.env.example` a `.env`
|
|
6
|
+
2. Agregar `OPENAI_API_KEY`
|
|
7
|
+
3. `npm install`
|
|
8
|
+
4. `npm start`
|
|
9
|
+
|
|
10
|
+
## Testear Backend
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
curl -X POST http://localhost:3000/kivo/message \
|
|
14
|
+
-H "Content-Type: application/json" \
|
|
15
|
+
-d '{"mensajeUsuario": "Hola Kivo", "personalidad": "barrio"}'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Personalidades
|
|
19
|
+
|
|
20
|
+
- normal
|
|
21
|
+
- barrio
|
|
22
|
+
- tecnico
|
|
23
|
+
- reflexivo
|
|
24
|
+
|
|
25
|
+
## Deploy
|
|
26
|
+
|
|
27
|
+
El proyecto está configurado para desplegarse automáticamente en Railway al hacer push a la rama principal.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { generateResponse } from "../services/openaiService.js";
|
|
2
|
+
|
|
3
|
+
export const handleMessage = async (req, res) => {
|
|
4
|
+
try {
|
|
5
|
+
const { mensajeUsuario, historial, tono, personalidad } = req.body;
|
|
6
|
+
|
|
7
|
+
if (!mensajeUsuario) {
|
|
8
|
+
return res.json({
|
|
9
|
+
respuestaKivo: "Hola, soy Kivo. ¿En qué puedo ayudarte hoy?",
|
|
10
|
+
emocion: "neutral",
|
|
11
|
+
modo: "normal",
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const response = await generateResponse({
|
|
16
|
+
message: mensajeUsuario,
|
|
17
|
+
history: historial || [],
|
|
18
|
+
tone: tono || "neutral",
|
|
19
|
+
personality: personalidad || "normal",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
res.json(response);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error("Error in kivoController:", error);
|
|
25
|
+
res.status(500).json({
|
|
26
|
+
error: "Error interno del cerebro de Kivo",
|
|
27
|
+
respuestaKivo:
|
|
28
|
+
"Lo siento, tuve un problema procesando eso. ¿Podemos intentar de nuevo?",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import cors from "cors";
|
|
3
|
+
import dotenv from "dotenv";
|
|
4
|
+
import messageRoutes from "./routes/message.js";
|
|
5
|
+
|
|
6
|
+
dotenv.config();
|
|
7
|
+
|
|
8
|
+
const app = express();
|
|
9
|
+
const PORT = process.env.PORT || 3000;
|
|
10
|
+
|
|
11
|
+
app.use(cors());
|
|
12
|
+
app.use(express.json());
|
|
13
|
+
|
|
14
|
+
// Routes
|
|
15
|
+
app.use("/kivo", messageRoutes);
|
|
16
|
+
|
|
17
|
+
// Health check
|
|
18
|
+
app.get("/", (req, res) => {
|
|
19
|
+
res.json({ status: "online", service: "kivo-brain-api" });
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
app.listen(PORT, () => {
|
|
23
|
+
console.log(`Kivo Brain API running on port ${PORT}`);
|
|
24
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kivo-brain-api",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Backend API for Kivo AI",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node index.js",
|
|
9
|
+
"dev": "node --watch index.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"cors": "^2.8.5",
|
|
13
|
+
"dotenv": "^16.4.5",
|
|
14
|
+
"express": "^4.19.2",
|
|
15
|
+
"openai": "^4.28.4"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
|
|
4
|
+
dotenv.config();
|
|
5
|
+
|
|
6
|
+
const openai = new OpenAI({
|
|
7
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const SYSTEM_PROMPTS = {
|
|
11
|
+
normal: "Eres Kivo, un asistente emocional inteligente, empático y claro.",
|
|
12
|
+
barrio:
|
|
13
|
+
"Eres Kivo, un amigo del barrio, usas jerga argentina suave (che, viste, tranqui), sos cercano y directo.",
|
|
14
|
+
tecnico:
|
|
15
|
+
"Eres Kivo, un asistente técnico preciso, lógico y analítico. Usas terminología de sistemas.",
|
|
16
|
+
reflexivo:
|
|
17
|
+
"Eres Kivo, un pensador profundo. Ayudas al usuario a cuestionar sus creencias y reflexionar.",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const generateResponse = async ({
|
|
21
|
+
message,
|
|
22
|
+
history,
|
|
23
|
+
tone,
|
|
24
|
+
personality,
|
|
25
|
+
}) => {
|
|
26
|
+
const systemPrompt = SYSTEM_PROMPTS[personality] || SYSTEM_PROMPTS.normal;
|
|
27
|
+
|
|
28
|
+
const messages = [
|
|
29
|
+
{
|
|
30
|
+
role: "system",
|
|
31
|
+
content: `${systemPrompt} Tono actual: ${tone}. Responde de forma concisa.`,
|
|
32
|
+
},
|
|
33
|
+
...history.map((msg) => ({
|
|
34
|
+
role: msg.role || "user",
|
|
35
|
+
content: msg.content || msg.mensaje || "",
|
|
36
|
+
})),
|
|
37
|
+
{ role: "user", content: message },
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const completion = await openai.chat.completions.create({
|
|
41
|
+
model: "gpt-4o-mini",
|
|
42
|
+
messages: messages,
|
|
43
|
+
temperature: 0.7,
|
|
44
|
+
max_tokens: 150,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const reply = completion.choices[0].message.content;
|
|
48
|
+
|
|
49
|
+
// Simple emotion detection based on reply content
|
|
50
|
+
let emotion = "neutral";
|
|
51
|
+
if (reply.includes("?")) emotion = "curioso";
|
|
52
|
+
if (reply.includes("!")) emotion = "contento";
|
|
53
|
+
if (
|
|
54
|
+
reply.toLowerCase().includes("lo siento") ||
|
|
55
|
+
reply.toLowerCase().includes("triste")
|
|
56
|
+
)
|
|
57
|
+
emotion = "empatico";
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
respuestaKivo: reply,
|
|
61
|
+
emocion: emotion,
|
|
62
|
+
modo: personality,
|
|
63
|
+
};
|
|
64
|
+
};
|