ai-parrot 0.17.2__cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
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.
- agentui/.prettierrc +15 -0
- agentui/QUICKSTART.md +272 -0
- agentui/README.md +59 -0
- agentui/env.example +16 -0
- agentui/jsconfig.json +14 -0
- agentui/package-lock.json +4242 -0
- agentui/package.json +34 -0
- agentui/scripts/postinstall/apply-patches.mjs +260 -0
- agentui/src/app.css +61 -0
- agentui/src/app.d.ts +13 -0
- agentui/src/app.html +12 -0
- agentui/src/components/LoadingSpinner.svelte +64 -0
- agentui/src/components/ThemeSwitcher.svelte +159 -0
- agentui/src/components/index.js +4 -0
- agentui/src/lib/api/bots.ts +60 -0
- agentui/src/lib/api/chat.ts +22 -0
- agentui/src/lib/api/http.ts +25 -0
- agentui/src/lib/components/BotCard.svelte +33 -0
- agentui/src/lib/components/ChatBubble.svelte +63 -0
- agentui/src/lib/components/Toast.svelte +21 -0
- agentui/src/lib/config.ts +20 -0
- agentui/src/lib/stores/auth.svelte.ts +73 -0
- agentui/src/lib/stores/theme.svelte.js +64 -0
- agentui/src/lib/stores/toast.svelte.ts +31 -0
- agentui/src/lib/utils/conversation.ts +39 -0
- agentui/src/routes/+layout.svelte +20 -0
- agentui/src/routes/+page.svelte +232 -0
- agentui/src/routes/login/+page.svelte +200 -0
- agentui/src/routes/talk/[agentId]/+page.svelte +297 -0
- agentui/src/routes/talk/[agentId]/+page.ts +7 -0
- agentui/static/README.md +1 -0
- agentui/svelte.config.js +11 -0
- agentui/tailwind.config.ts +53 -0
- agentui/tsconfig.json +3 -0
- agentui/vite.config.ts +10 -0
- ai_parrot-0.17.2.dist-info/METADATA +472 -0
- ai_parrot-0.17.2.dist-info/RECORD +535 -0
- ai_parrot-0.17.2.dist-info/WHEEL +6 -0
- ai_parrot-0.17.2.dist-info/entry_points.txt +2 -0
- ai_parrot-0.17.2.dist-info/licenses/LICENSE +21 -0
- ai_parrot-0.17.2.dist-info/top_level.txt +6 -0
- crew-builder/.prettierrc +15 -0
- crew-builder/QUICKSTART.md +259 -0
- crew-builder/README.md +113 -0
- crew-builder/env.example +17 -0
- crew-builder/jsconfig.json +14 -0
- crew-builder/package-lock.json +4182 -0
- crew-builder/package.json +37 -0
- crew-builder/scripts/postinstall/apply-patches.mjs +260 -0
- crew-builder/src/app.css +62 -0
- crew-builder/src/app.d.ts +13 -0
- crew-builder/src/app.html +12 -0
- crew-builder/src/components/LoadingSpinner.svelte +64 -0
- crew-builder/src/components/ThemeSwitcher.svelte +149 -0
- crew-builder/src/components/index.js +9 -0
- crew-builder/src/lib/api/bots.ts +60 -0
- crew-builder/src/lib/api/chat.ts +80 -0
- crew-builder/src/lib/api/client.ts +56 -0
- crew-builder/src/lib/api/crew/crew.ts +136 -0
- crew-builder/src/lib/api/index.ts +5 -0
- crew-builder/src/lib/api/o365/auth.ts +65 -0
- crew-builder/src/lib/auth/auth.ts +54 -0
- crew-builder/src/lib/components/AgentNode.svelte +43 -0
- crew-builder/src/lib/components/BotCard.svelte +33 -0
- crew-builder/src/lib/components/ChatBubble.svelte +67 -0
- crew-builder/src/lib/components/ConfigPanel.svelte +278 -0
- crew-builder/src/lib/components/JsonTreeNode.svelte +76 -0
- crew-builder/src/lib/components/JsonViewer.svelte +24 -0
- crew-builder/src/lib/components/MarkdownEditor.svelte +48 -0
- crew-builder/src/lib/components/ThemeToggle.svelte +36 -0
- crew-builder/src/lib/components/Toast.svelte +67 -0
- crew-builder/src/lib/components/Toolbar.svelte +157 -0
- crew-builder/src/lib/components/index.ts +10 -0
- crew-builder/src/lib/config.ts +8 -0
- crew-builder/src/lib/stores/auth.svelte.ts +228 -0
- crew-builder/src/lib/stores/crewStore.ts +369 -0
- crew-builder/src/lib/stores/theme.svelte.js +145 -0
- crew-builder/src/lib/stores/toast.svelte.ts +69 -0
- crew-builder/src/lib/utils/conversation.ts +39 -0
- crew-builder/src/lib/utils/markdown.ts +122 -0
- crew-builder/src/lib/utils/talkHistory.ts +47 -0
- crew-builder/src/routes/+layout.svelte +20 -0
- crew-builder/src/routes/+page.svelte +539 -0
- crew-builder/src/routes/agents/+page.svelte +247 -0
- crew-builder/src/routes/agents/[agentId]/+page.svelte +288 -0
- crew-builder/src/routes/agents/[agentId]/+page.ts +7 -0
- crew-builder/src/routes/builder/+page.svelte +204 -0
- crew-builder/src/routes/crew/ask/+page.svelte +1052 -0
- crew-builder/src/routes/crew/ask/+page.ts +1 -0
- crew-builder/src/routes/integrations/o365/+page.svelte +304 -0
- crew-builder/src/routes/login/+page.svelte +197 -0
- crew-builder/src/routes/talk/[agentId]/+page.svelte +487 -0
- crew-builder/src/routes/talk/[agentId]/+page.ts +7 -0
- crew-builder/static/README.md +1 -0
- crew-builder/svelte.config.js +11 -0
- crew-builder/tailwind.config.ts +53 -0
- crew-builder/tsconfig.json +3 -0
- crew-builder/vite.config.ts +10 -0
- mcp_servers/calculator_server.py +309 -0
- parrot/__init__.py +27 -0
- parrot/__pycache__/__init__.cpython-310.pyc +0 -0
- parrot/__pycache__/version.cpython-310.pyc +0 -0
- parrot/_version.py +34 -0
- parrot/a2a/__init__.py +48 -0
- parrot/a2a/client.py +658 -0
- parrot/a2a/discovery.py +89 -0
- parrot/a2a/mixin.py +257 -0
- parrot/a2a/models.py +376 -0
- parrot/a2a/server.py +770 -0
- parrot/agents/__init__.py +29 -0
- parrot/bots/__init__.py +12 -0
- parrot/bots/a2a_agent.py +19 -0
- parrot/bots/abstract.py +3139 -0
- parrot/bots/agent.py +1129 -0
- parrot/bots/basic.py +9 -0
- parrot/bots/chatbot.py +669 -0
- parrot/bots/data.py +1618 -0
- parrot/bots/database/__init__.py +5 -0
- parrot/bots/database/abstract.py +3071 -0
- parrot/bots/database/cache.py +286 -0
- parrot/bots/database/models.py +468 -0
- parrot/bots/database/prompts.py +154 -0
- parrot/bots/database/retries.py +98 -0
- parrot/bots/database/router.py +269 -0
- parrot/bots/database/sql.py +41 -0
- parrot/bots/db/__init__.py +6 -0
- parrot/bots/db/abstract.py +556 -0
- parrot/bots/db/bigquery.py +602 -0
- parrot/bots/db/cache.py +85 -0
- parrot/bots/db/documentdb.py +668 -0
- parrot/bots/db/elastic.py +1014 -0
- parrot/bots/db/influx.py +898 -0
- parrot/bots/db/mock.py +96 -0
- parrot/bots/db/multi.py +783 -0
- parrot/bots/db/prompts.py +185 -0
- parrot/bots/db/sql.py +1255 -0
- parrot/bots/db/tools.py +212 -0
- parrot/bots/document.py +680 -0
- parrot/bots/hrbot.py +15 -0
- parrot/bots/kb.py +170 -0
- parrot/bots/mcp.py +36 -0
- parrot/bots/orchestration/README.md +463 -0
- parrot/bots/orchestration/__init__.py +1 -0
- parrot/bots/orchestration/agent.py +155 -0
- parrot/bots/orchestration/crew.py +3330 -0
- parrot/bots/orchestration/fsm.py +1179 -0
- parrot/bots/orchestration/hr.py +434 -0
- parrot/bots/orchestration/storage/__init__.py +4 -0
- parrot/bots/orchestration/storage/memory.py +100 -0
- parrot/bots/orchestration/storage/mixin.py +119 -0
- parrot/bots/orchestration/verify.py +202 -0
- parrot/bots/product.py +204 -0
- parrot/bots/prompts/__init__.py +96 -0
- parrot/bots/prompts/agents.py +155 -0
- parrot/bots/prompts/data.py +216 -0
- parrot/bots/prompts/output_generation.py +8 -0
- parrot/bots/scraper/__init__.py +3 -0
- parrot/bots/scraper/models.py +122 -0
- parrot/bots/scraper/scraper.py +1173 -0
- parrot/bots/scraper/templates.py +115 -0
- parrot/bots/stores/__init__.py +5 -0
- parrot/bots/stores/local.py +172 -0
- parrot/bots/webdev.py +81 -0
- parrot/cli.py +17 -0
- parrot/clients/__init__.py +16 -0
- parrot/clients/base.py +1491 -0
- parrot/clients/claude.py +1191 -0
- parrot/clients/factory.py +129 -0
- parrot/clients/google.py +4567 -0
- parrot/clients/gpt.py +1975 -0
- parrot/clients/grok.py +432 -0
- parrot/clients/groq.py +986 -0
- parrot/clients/hf.py +582 -0
- parrot/clients/models.py +18 -0
- parrot/conf.py +395 -0
- parrot/embeddings/__init__.py +9 -0
- parrot/embeddings/base.py +157 -0
- parrot/embeddings/google.py +98 -0
- parrot/embeddings/huggingface.py +74 -0
- parrot/embeddings/openai.py +84 -0
- parrot/embeddings/processor.py +88 -0
- parrot/exceptions.c +13868 -0
- parrot/exceptions.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/exceptions.pxd +22 -0
- parrot/exceptions.pxi +15 -0
- parrot/exceptions.pyx +44 -0
- parrot/generators/__init__.py +29 -0
- parrot/generators/base.py +200 -0
- parrot/generators/html.py +293 -0
- parrot/generators/react.py +205 -0
- parrot/generators/streamlit.py +203 -0
- parrot/generators/template.py +105 -0
- parrot/handlers/__init__.py +4 -0
- parrot/handlers/agent.py +861 -0
- parrot/handlers/agents/__init__.py +1 -0
- parrot/handlers/agents/abstract.py +900 -0
- parrot/handlers/bots.py +338 -0
- parrot/handlers/chat.py +915 -0
- parrot/handlers/creation.sql +192 -0
- parrot/handlers/crew/ARCHITECTURE.md +362 -0
- parrot/handlers/crew/README_BOTMANAGER_PERSISTENCE.md +303 -0
- parrot/handlers/crew/README_REDIS_PERSISTENCE.md +366 -0
- parrot/handlers/crew/__init__.py +0 -0
- parrot/handlers/crew/handler.py +801 -0
- parrot/handlers/crew/models.py +229 -0
- parrot/handlers/crew/redis_persistence.py +523 -0
- parrot/handlers/jobs/__init__.py +10 -0
- parrot/handlers/jobs/job.py +384 -0
- parrot/handlers/jobs/mixin.py +627 -0
- parrot/handlers/jobs/models.py +115 -0
- parrot/handlers/jobs/worker.py +31 -0
- parrot/handlers/models.py +596 -0
- parrot/handlers/o365_auth.py +105 -0
- parrot/handlers/stream.py +337 -0
- parrot/interfaces/__init__.py +6 -0
- parrot/interfaces/aws.py +143 -0
- parrot/interfaces/credentials.py +113 -0
- parrot/interfaces/database.py +27 -0
- parrot/interfaces/google.py +1123 -0
- parrot/interfaces/hierarchy.py +1227 -0
- parrot/interfaces/http.py +651 -0
- parrot/interfaces/images/__init__.py +0 -0
- parrot/interfaces/images/plugins/__init__.py +24 -0
- parrot/interfaces/images/plugins/abstract.py +58 -0
- parrot/interfaces/images/plugins/analisys.py +148 -0
- parrot/interfaces/images/plugins/classify.py +150 -0
- parrot/interfaces/images/plugins/classifybase.py +182 -0
- parrot/interfaces/images/plugins/detect.py +150 -0
- parrot/interfaces/images/plugins/exif.py +1103 -0
- parrot/interfaces/images/plugins/hash.py +52 -0
- parrot/interfaces/images/plugins/vision.py +104 -0
- parrot/interfaces/images/plugins/yolo.py +66 -0
- parrot/interfaces/images/plugins/zerodetect.py +197 -0
- parrot/interfaces/o365.py +978 -0
- parrot/interfaces/onedrive.py +822 -0
- parrot/interfaces/sharepoint.py +1435 -0
- parrot/interfaces/soap.py +257 -0
- parrot/loaders/__init__.py +8 -0
- parrot/loaders/abstract.py +1131 -0
- parrot/loaders/audio.py +199 -0
- parrot/loaders/basepdf.py +53 -0
- parrot/loaders/basevideo.py +1568 -0
- parrot/loaders/csv.py +409 -0
- parrot/loaders/docx.py +116 -0
- parrot/loaders/epubloader.py +316 -0
- parrot/loaders/excel.py +199 -0
- parrot/loaders/factory.py +55 -0
- parrot/loaders/files/__init__.py +0 -0
- parrot/loaders/files/abstract.py +39 -0
- parrot/loaders/files/html.py +26 -0
- parrot/loaders/files/text.py +63 -0
- parrot/loaders/html.py +152 -0
- parrot/loaders/markdown.py +442 -0
- parrot/loaders/pdf.py +373 -0
- parrot/loaders/pdfmark.py +320 -0
- parrot/loaders/pdftables.py +506 -0
- parrot/loaders/ppt.py +476 -0
- parrot/loaders/qa.py +63 -0
- parrot/loaders/splitters/__init__.py +10 -0
- parrot/loaders/splitters/base.py +138 -0
- parrot/loaders/splitters/md.py +228 -0
- parrot/loaders/splitters/token.py +143 -0
- parrot/loaders/txt.py +26 -0
- parrot/loaders/video.py +89 -0
- parrot/loaders/videolocal.py +218 -0
- parrot/loaders/videounderstanding.py +377 -0
- parrot/loaders/vimeo.py +167 -0
- parrot/loaders/web.py +599 -0
- parrot/loaders/youtube.py +504 -0
- parrot/manager/__init__.py +5 -0
- parrot/manager/manager.py +1030 -0
- parrot/mcp/__init__.py +28 -0
- parrot/mcp/adapter.py +105 -0
- parrot/mcp/cli.py +174 -0
- parrot/mcp/client.py +119 -0
- parrot/mcp/config.py +75 -0
- parrot/mcp/integration.py +842 -0
- parrot/mcp/oauth.py +933 -0
- parrot/mcp/server.py +225 -0
- parrot/mcp/transports/__init__.py +3 -0
- parrot/mcp/transports/base.py +279 -0
- parrot/mcp/transports/grpc_session.py +163 -0
- parrot/mcp/transports/http.py +312 -0
- parrot/mcp/transports/mcp.proto +108 -0
- parrot/mcp/transports/quic.py +1082 -0
- parrot/mcp/transports/sse.py +330 -0
- parrot/mcp/transports/stdio.py +309 -0
- parrot/mcp/transports/unix.py +395 -0
- parrot/mcp/transports/websocket.py +547 -0
- parrot/memory/__init__.py +16 -0
- parrot/memory/abstract.py +209 -0
- parrot/memory/agent.py +32 -0
- parrot/memory/cache.py +175 -0
- parrot/memory/core.py +555 -0
- parrot/memory/file.py +153 -0
- parrot/memory/mem.py +131 -0
- parrot/memory/redis.py +613 -0
- parrot/models/__init__.py +46 -0
- parrot/models/basic.py +118 -0
- parrot/models/compliance.py +208 -0
- parrot/models/crew.py +395 -0
- parrot/models/detections.py +654 -0
- parrot/models/generation.py +85 -0
- parrot/models/google.py +223 -0
- parrot/models/groq.py +23 -0
- parrot/models/openai.py +30 -0
- parrot/models/outputs.py +285 -0
- parrot/models/responses.py +938 -0
- parrot/notifications/__init__.py +743 -0
- parrot/openapi/__init__.py +3 -0
- parrot/openapi/components.yaml +641 -0
- parrot/openapi/config.py +322 -0
- parrot/outputs/__init__.py +32 -0
- parrot/outputs/formats/__init__.py +108 -0
- parrot/outputs/formats/altair.py +359 -0
- parrot/outputs/formats/application.py +122 -0
- parrot/outputs/formats/base.py +351 -0
- parrot/outputs/formats/bokeh.py +356 -0
- parrot/outputs/formats/card.py +424 -0
- parrot/outputs/formats/chart.py +436 -0
- parrot/outputs/formats/d3.py +255 -0
- parrot/outputs/formats/echarts.py +310 -0
- parrot/outputs/formats/generators/__init__.py +0 -0
- parrot/outputs/formats/generators/abstract.py +61 -0
- parrot/outputs/formats/generators/panel.py +145 -0
- parrot/outputs/formats/generators/streamlit.py +86 -0
- parrot/outputs/formats/generators/terminal.py +63 -0
- parrot/outputs/formats/holoviews.py +310 -0
- parrot/outputs/formats/html.py +147 -0
- parrot/outputs/formats/jinja2.py +46 -0
- parrot/outputs/formats/json.py +87 -0
- parrot/outputs/formats/map.py +933 -0
- parrot/outputs/formats/markdown.py +172 -0
- parrot/outputs/formats/matplotlib.py +237 -0
- parrot/outputs/formats/mixins/__init__.py +0 -0
- parrot/outputs/formats/mixins/emaps.py +855 -0
- parrot/outputs/formats/plotly.py +341 -0
- parrot/outputs/formats/seaborn.py +310 -0
- parrot/outputs/formats/table.py +397 -0
- parrot/outputs/formats/template_report.py +138 -0
- parrot/outputs/formats/yaml.py +125 -0
- parrot/outputs/formatter.py +152 -0
- parrot/outputs/templates/__init__.py +95 -0
- parrot/pipelines/__init__.py +0 -0
- parrot/pipelines/abstract.py +210 -0
- parrot/pipelines/detector.py +124 -0
- parrot/pipelines/models.py +90 -0
- parrot/pipelines/planogram.py +3002 -0
- parrot/pipelines/table.sql +97 -0
- parrot/plugins/__init__.py +106 -0
- parrot/plugins/importer.py +80 -0
- parrot/py.typed +0 -0
- parrot/registry/__init__.py +18 -0
- parrot/registry/registry.py +594 -0
- parrot/scheduler/__init__.py +1189 -0
- parrot/scheduler/models.py +60 -0
- parrot/security/__init__.py +16 -0
- parrot/security/prompt_injection.py +268 -0
- parrot/security/security_events.sql +25 -0
- parrot/services/__init__.py +1 -0
- parrot/services/mcp/__init__.py +8 -0
- parrot/services/mcp/config.py +13 -0
- parrot/services/mcp/server.py +295 -0
- parrot/services/o365_remote_auth.py +235 -0
- parrot/stores/__init__.py +7 -0
- parrot/stores/abstract.py +352 -0
- parrot/stores/arango.py +1090 -0
- parrot/stores/bigquery.py +1377 -0
- parrot/stores/cache.py +106 -0
- parrot/stores/empty.py +10 -0
- parrot/stores/faiss_store.py +1157 -0
- parrot/stores/kb/__init__.py +9 -0
- parrot/stores/kb/abstract.py +68 -0
- parrot/stores/kb/cache.py +165 -0
- parrot/stores/kb/doc.py +325 -0
- parrot/stores/kb/hierarchy.py +346 -0
- parrot/stores/kb/local.py +457 -0
- parrot/stores/kb/prompt.py +28 -0
- parrot/stores/kb/redis.py +659 -0
- parrot/stores/kb/store.py +115 -0
- parrot/stores/kb/user.py +374 -0
- parrot/stores/models.py +59 -0
- parrot/stores/pgvector.py +3 -0
- parrot/stores/postgres.py +2853 -0
- parrot/stores/utils/__init__.py +0 -0
- parrot/stores/utils/chunking.py +197 -0
- parrot/telemetry/__init__.py +3 -0
- parrot/telemetry/mixin.py +111 -0
- parrot/template/__init__.py +3 -0
- parrot/template/engine.py +259 -0
- parrot/tools/__init__.py +23 -0
- parrot/tools/abstract.py +644 -0
- parrot/tools/agent.py +363 -0
- parrot/tools/arangodbsearch.py +537 -0
- parrot/tools/arxiv_tool.py +188 -0
- parrot/tools/calculator/__init__.py +3 -0
- parrot/tools/calculator/operations/__init__.py +38 -0
- parrot/tools/calculator/operations/calculus.py +80 -0
- parrot/tools/calculator/operations/statistics.py +76 -0
- parrot/tools/calculator/tool.py +150 -0
- parrot/tools/cloudwatch.py +988 -0
- parrot/tools/codeinterpreter/__init__.py +127 -0
- parrot/tools/codeinterpreter/executor.py +371 -0
- parrot/tools/codeinterpreter/internals.py +473 -0
- parrot/tools/codeinterpreter/models.py +643 -0
- parrot/tools/codeinterpreter/prompts.py +224 -0
- parrot/tools/codeinterpreter/tool.py +664 -0
- parrot/tools/company_info/__init__.py +6 -0
- parrot/tools/company_info/tool.py +1138 -0
- parrot/tools/correlationanalysis.py +437 -0
- parrot/tools/database/abstract.py +286 -0
- parrot/tools/database/bq.py +115 -0
- parrot/tools/database/cache.py +284 -0
- parrot/tools/database/models.py +95 -0
- parrot/tools/database/pg.py +343 -0
- parrot/tools/databasequery.py +1159 -0
- parrot/tools/db.py +1800 -0
- parrot/tools/ddgo.py +370 -0
- parrot/tools/decorators.py +271 -0
- parrot/tools/dftohtml.py +282 -0
- parrot/tools/document.py +549 -0
- parrot/tools/ecs.py +819 -0
- parrot/tools/edareport.py +368 -0
- parrot/tools/elasticsearch.py +1049 -0
- parrot/tools/employees.py +462 -0
- parrot/tools/epson/__init__.py +96 -0
- parrot/tools/excel.py +683 -0
- parrot/tools/file/__init__.py +13 -0
- parrot/tools/file/abstract.py +76 -0
- parrot/tools/file/gcs.py +378 -0
- parrot/tools/file/local.py +284 -0
- parrot/tools/file/s3.py +511 -0
- parrot/tools/file/tmp.py +309 -0
- parrot/tools/file/tool.py +501 -0
- parrot/tools/file_reader.py +129 -0
- parrot/tools/flowtask/__init__.py +19 -0
- parrot/tools/flowtask/tool.py +761 -0
- parrot/tools/gittoolkit.py +508 -0
- parrot/tools/google/__init__.py +18 -0
- parrot/tools/google/base.py +169 -0
- parrot/tools/google/tools.py +1251 -0
- parrot/tools/googlelocation.py +5 -0
- parrot/tools/googleroutes.py +5 -0
- parrot/tools/googlesearch.py +5 -0
- parrot/tools/googlesitesearch.py +5 -0
- parrot/tools/googlevoice.py +2 -0
- parrot/tools/gvoice.py +695 -0
- parrot/tools/ibisworld/README.md +225 -0
- parrot/tools/ibisworld/__init__.py +11 -0
- parrot/tools/ibisworld/tool.py +366 -0
- parrot/tools/jiratoolkit.py +1718 -0
- parrot/tools/manager.py +1098 -0
- parrot/tools/math.py +152 -0
- parrot/tools/metadata.py +476 -0
- parrot/tools/msteams.py +1621 -0
- parrot/tools/msword.py +635 -0
- parrot/tools/multidb.py +580 -0
- parrot/tools/multistoresearch.py +369 -0
- parrot/tools/networkninja.py +167 -0
- parrot/tools/nextstop/__init__.py +4 -0
- parrot/tools/nextstop/base.py +286 -0
- parrot/tools/nextstop/employee.py +733 -0
- parrot/tools/nextstop/store.py +462 -0
- parrot/tools/notification.py +435 -0
- parrot/tools/o365/__init__.py +42 -0
- parrot/tools/o365/base.py +295 -0
- parrot/tools/o365/bundle.py +522 -0
- parrot/tools/o365/events.py +554 -0
- parrot/tools/o365/mail.py +992 -0
- parrot/tools/o365/onedrive.py +497 -0
- parrot/tools/o365/sharepoint.py +641 -0
- parrot/tools/openapi_toolkit.py +904 -0
- parrot/tools/openweather.py +527 -0
- parrot/tools/pdfprint.py +1001 -0
- parrot/tools/powerbi.py +518 -0
- parrot/tools/powerpoint.py +1113 -0
- parrot/tools/pricestool.py +146 -0
- parrot/tools/products/__init__.py +246 -0
- parrot/tools/prophet_tool.py +171 -0
- parrot/tools/pythonpandas.py +630 -0
- parrot/tools/pythonrepl.py +910 -0
- parrot/tools/qsource.py +436 -0
- parrot/tools/querytoolkit.py +395 -0
- parrot/tools/quickeda.py +827 -0
- parrot/tools/resttool.py +553 -0
- parrot/tools/retail/__init__.py +0 -0
- parrot/tools/retail/bby.py +528 -0
- parrot/tools/sandboxtool.py +703 -0
- parrot/tools/sassie/__init__.py +352 -0
- parrot/tools/scraping/__init__.py +7 -0
- parrot/tools/scraping/docs/select.md +466 -0
- parrot/tools/scraping/documentation.md +1278 -0
- parrot/tools/scraping/driver.py +436 -0
- parrot/tools/scraping/models.py +576 -0
- parrot/tools/scraping/options.py +85 -0
- parrot/tools/scraping/orchestrator.py +517 -0
- parrot/tools/scraping/readme.md +740 -0
- parrot/tools/scraping/tool.py +3115 -0
- parrot/tools/seasonaldetection.py +642 -0
- parrot/tools/shell_tool/__init__.py +5 -0
- parrot/tools/shell_tool/actions.py +408 -0
- parrot/tools/shell_tool/engine.py +155 -0
- parrot/tools/shell_tool/models.py +322 -0
- parrot/tools/shell_tool/tool.py +442 -0
- parrot/tools/site_search.py +214 -0
- parrot/tools/textfile.py +418 -0
- parrot/tools/think.py +378 -0
- parrot/tools/toolkit.py +298 -0
- parrot/tools/webapp_tool.py +187 -0
- parrot/tools/whatif.py +1279 -0
- parrot/tools/workday/MULTI_WSDL_EXAMPLE.md +249 -0
- parrot/tools/workday/__init__.py +6 -0
- parrot/tools/workday/models.py +1389 -0
- parrot/tools/workday/tool.py +1293 -0
- parrot/tools/yfinance_tool.py +306 -0
- parrot/tools/zipcode.py +217 -0
- parrot/utils/__init__.py +2 -0
- parrot/utils/helpers.py +73 -0
- parrot/utils/parsers/__init__.py +5 -0
- parrot/utils/parsers/toml.c +12078 -0
- parrot/utils/parsers/toml.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/utils/parsers/toml.pyx +21 -0
- parrot/utils/toml.py +11 -0
- parrot/utils/types.cpp +20936 -0
- parrot/utils/types.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/utils/types.pyx +213 -0
- parrot/utils/uv.py +11 -0
- parrot/version.py +10 -0
- parrot/yaml-rs/Cargo.lock +350 -0
- parrot/yaml-rs/Cargo.toml +19 -0
- parrot/yaml-rs/pyproject.toml +19 -0
- parrot/yaml-rs/python/yaml_rs/__init__.py +81 -0
- parrot/yaml-rs/src/lib.rs +222 -0
- requirements/docker-compose.yml +24 -0
- requirements/requirements-dev.txt +21 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
2
|
+
from typing import List, Dict, Any
|
|
3
|
+
|
|
4
|
+
class KnowledgeBaseStore:
|
|
5
|
+
"""Lightweight in-memory store for validated facts."""
|
|
6
|
+
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
embedding_model: str = "all-MiniLM-L6-v2", # 384D model
|
|
10
|
+
dimension: int = 384,
|
|
11
|
+
index_type: str = "Flat", # or "HNSW" for larger KBs
|
|
12
|
+
):
|
|
13
|
+
try:
|
|
14
|
+
from sentence_transformers import SentenceTransformer
|
|
15
|
+
import faiss
|
|
16
|
+
except ImportError as e:
|
|
17
|
+
raise ImportError(
|
|
18
|
+
"Please install 'sentence-transformers' and 'faiss-cpu' to use KnowledgeBaseStore."
|
|
19
|
+
) from e
|
|
20
|
+
self.embeddings = SentenceTransformer(embedding_model)
|
|
21
|
+
self.dimension = dimension
|
|
22
|
+
self.score_threshold = 0.5
|
|
23
|
+
# FAISS index
|
|
24
|
+
if index_type == "FlatIP":
|
|
25
|
+
self.index = faiss.IndexFlatIP(dimension)
|
|
26
|
+
else:
|
|
27
|
+
# HNSW with IP metric
|
|
28
|
+
self.index = faiss.IndexHNSWFlat(dimension, 32, faiss.METRIC_INNER_PRODUCT)
|
|
29
|
+
|
|
30
|
+
# Store facts and metadata
|
|
31
|
+
self.facts: List[str] = []
|
|
32
|
+
self.fact_metadata: List[dict] = []
|
|
33
|
+
self.category_index = defaultdict(list) # Fast category lookup
|
|
34
|
+
self.entity_index = defaultdict(list) # Entity-based retrieval
|
|
35
|
+
|
|
36
|
+
async def add_fact(self, fact: Dict[str, Any]):
|
|
37
|
+
"""Add a single validated fact to the KB."""
|
|
38
|
+
await self.add_facts([fact])
|
|
39
|
+
|
|
40
|
+
async def add_facts(self, facts: List[Dict[str, Any]]):
|
|
41
|
+
"""Add validated facts to the KB."""
|
|
42
|
+
if not facts:
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
texts = []
|
|
46
|
+
for fact in facts:
|
|
47
|
+
fact_id = len(self.facts)
|
|
48
|
+
self.facts.append(fact)
|
|
49
|
+
texts.append(fact['content'])
|
|
50
|
+
if category := fact.get('metadata', {}).get('category'):
|
|
51
|
+
self.category_index[category].append(fact_id)
|
|
52
|
+
# Index by entities
|
|
53
|
+
for key in ['subject', 'object']:
|
|
54
|
+
if entity := fact.get('metadata', {}).get(key):
|
|
55
|
+
self.entity_index[entity].append(fact_id)
|
|
56
|
+
|
|
57
|
+
embeddings = self.embeddings.encode(texts, normalize_embeddings=True)
|
|
58
|
+
self.index.add(embeddings)
|
|
59
|
+
|
|
60
|
+
self.fact_metadata.extend(
|
|
61
|
+
[f.get('metadata', {}) for f in facts]
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def _tokenize(self, text: str) -> set:
|
|
65
|
+
return {t.lower() for t in text.split()}
|
|
66
|
+
|
|
67
|
+
async def search_facts(
|
|
68
|
+
self,
|
|
69
|
+
query: str,
|
|
70
|
+
k: int = 5,
|
|
71
|
+
score_threshold: float = 0.5
|
|
72
|
+
) -> List[Dict[str, Any]]:
|
|
73
|
+
"""Ultra-fast fact retrieval."""
|
|
74
|
+
query_embedding = self.embeddings.encode(
|
|
75
|
+
[query],
|
|
76
|
+
normalize_embeddings=True
|
|
77
|
+
)
|
|
78
|
+
# Important: k should not exceed number of facts
|
|
79
|
+
actual_k = min(k, len(self.facts))
|
|
80
|
+
scores, indices = self.index.search(query_embedding, actual_k)
|
|
81
|
+
threshold = score_threshold or self.score_threshold
|
|
82
|
+
|
|
83
|
+
results = []
|
|
84
|
+
for score, idx in zip(scores[0], indices[0]):
|
|
85
|
+
if idx == -1:
|
|
86
|
+
continue
|
|
87
|
+
if float(score) >= threshold:
|
|
88
|
+
results.append({
|
|
89
|
+
'fact': self.facts[idx],
|
|
90
|
+
'score': float(score),
|
|
91
|
+
'metadata': self.fact_metadata[idx]
|
|
92
|
+
})
|
|
93
|
+
# doing a re-ranking based on token overlap
|
|
94
|
+
# after collecting FAISS candidates as `results` with "score" = cosine
|
|
95
|
+
q_tokens = self._tokenize(query)
|
|
96
|
+
for r in results:
|
|
97
|
+
tags = set((r["metadata"].get("tags") or []))
|
|
98
|
+
overlap = len(q_tokens & {t.lower() for t in tags})
|
|
99
|
+
r["score"] += 0.05 * overlap # tiny boost per overlapping tag
|
|
100
|
+
results.sort(key=lambda x: x["score"], reverse=True)
|
|
101
|
+
return results
|
|
102
|
+
|
|
103
|
+
def get_facts_by_category(self, category: str) -> List[Dict]:
|
|
104
|
+
"""Retrieve all facts in a category."""
|
|
105
|
+
indices = self.category_index.get(category, [])
|
|
106
|
+
return [self.facts[i] for i in indices]
|
|
107
|
+
|
|
108
|
+
def get_entity_facts(self, entity: str) -> List[Dict]:
|
|
109
|
+
"""Get all facts related to an entity."""
|
|
110
|
+
indices = self.entity_index.get(entity, [])
|
|
111
|
+
return [self.facts[i] for i in indices]
|
|
112
|
+
|
|
113
|
+
async def close(self):
|
|
114
|
+
"""Cleanup resources if needed."""
|
|
115
|
+
pass
|
parrot/stores/kb/user.py
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
from typing import Tuple, List, Dict, Any, Optional
|
|
2
|
+
from asyncdb import AsyncDB
|
|
3
|
+
from querysource.conf import default_dsn
|
|
4
|
+
from .abstract import AbstractKnowledgeBase
|
|
5
|
+
from .redis import RedisKnowledgeBase
|
|
6
|
+
from ...utils.helpers import RequestContext
|
|
7
|
+
from .cache import TTLCache
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class UserInfo(AbstractKnowledgeBase):
|
|
11
|
+
"""Class to manage user information."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, **kwargs):
|
|
14
|
+
super().__init__(
|
|
15
|
+
name="User Info",
|
|
16
|
+
category="user_context",
|
|
17
|
+
always_active=True,
|
|
18
|
+
activation_patterns=[
|
|
19
|
+
"about me"
|
|
20
|
+
],
|
|
21
|
+
priority=10, # High priority
|
|
22
|
+
**kwargs
|
|
23
|
+
)
|
|
24
|
+
self.db = AsyncDB('pg', dsn=default_dsn)
|
|
25
|
+
self.cache = TTLCache(
|
|
26
|
+
max_size=500,
|
|
27
|
+
default_ttl=600 # 10 minutes for user data
|
|
28
|
+
)
|
|
29
|
+
self._initialized = False
|
|
30
|
+
|
|
31
|
+
async def _lazy_init(self):
|
|
32
|
+
"""Lazy initialization of resources."""
|
|
33
|
+
if not self._initialized:
|
|
34
|
+
await self.cache.start()
|
|
35
|
+
self._initialized = True
|
|
36
|
+
|
|
37
|
+
async def should_activate(self, query: str, context: dict) -> Tuple[bool, float]:
|
|
38
|
+
# Implement activation logic based on user info
|
|
39
|
+
return True, 1.0 # Always activate with high confidence
|
|
40
|
+
|
|
41
|
+
async def search(self, query: str, user_id: int, **kwargs) -> List[Dict]:
|
|
42
|
+
"""Query Database for User Information."""
|
|
43
|
+
if not user_id:
|
|
44
|
+
return []
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
async with await self.db.connection() as conn: # pylint: disable=E1101 # noqa
|
|
48
|
+
result = await conn.fetch_one(
|
|
49
|
+
"""
|
|
50
|
+
SELECT user_id, display_name, username, email, job_code, associate_id as employee_id,
|
|
51
|
+
associate_id, associate_oid, title, worker_type, manager_id
|
|
52
|
+
FROM auth.vw_users WHERE user_id = $1
|
|
53
|
+
""",
|
|
54
|
+
user_id
|
|
55
|
+
)
|
|
56
|
+
# Ok, Result is an asyncpg Record object, iterate over the columns:
|
|
57
|
+
# iterate over the result and convert in a list of facts:
|
|
58
|
+
facts = []
|
|
59
|
+
user = dict(result)
|
|
60
|
+
for key, value in user.items():
|
|
61
|
+
if value:
|
|
62
|
+
facts.append({
|
|
63
|
+
"content": f"{key.replace('_', ' ').title()}: {value}",
|
|
64
|
+
"metadata": {
|
|
65
|
+
"category": "user_info",
|
|
66
|
+
"entity_type": key,
|
|
67
|
+
"confidence": 1.0,
|
|
68
|
+
"tags": ["user", "profile", key]
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
return facts
|
|
72
|
+
except Exception as e:
|
|
73
|
+
print(f"Error fetching user info: {e}")
|
|
74
|
+
return []
|
|
75
|
+
|
|
76
|
+
class UserProfileKB(AbstractKnowledgeBase):
|
|
77
|
+
"""KB that queries database for user information."""
|
|
78
|
+
|
|
79
|
+
def __init__(self, **kwargs):
|
|
80
|
+
super().__init__(
|
|
81
|
+
name="User Profile",
|
|
82
|
+
category="user_context",
|
|
83
|
+
activation_patterns=[
|
|
84
|
+
"my preferences", "my profile", "my settings",
|
|
85
|
+
"about me", "my role", "my permissions"
|
|
86
|
+
],
|
|
87
|
+
priority=10 # High priority
|
|
88
|
+
)
|
|
89
|
+
self.db = AsyncDB('pg', dsn=default_dsn)
|
|
90
|
+
|
|
91
|
+
async def should_activate(self, query: str, context: Dict) -> Tuple[bool, float]:
|
|
92
|
+
"""Check if query references user-specific information."""
|
|
93
|
+
query_lower = query.lower()
|
|
94
|
+
|
|
95
|
+
# Direct patterns
|
|
96
|
+
for pattern in self.activation_patterns:
|
|
97
|
+
if pattern in query_lower:
|
|
98
|
+
return True, 1.0
|
|
99
|
+
|
|
100
|
+
# Heuristic checks
|
|
101
|
+
personal_indicators = ["my", "me", "i", "our"]
|
|
102
|
+
if any(word in query_lower.split() for word in personal_indicators):
|
|
103
|
+
return True, 0.7
|
|
104
|
+
|
|
105
|
+
return False, 0.0
|
|
106
|
+
|
|
107
|
+
async def search(self, query: str, user_id: str = None, **kwargs) -> List[Dict]:
|
|
108
|
+
"""Query database for user information."""
|
|
109
|
+
if not user_id:
|
|
110
|
+
return []
|
|
111
|
+
|
|
112
|
+
async with await self.db.connection() as conn: # pylint: disable=E1101 # noqa
|
|
113
|
+
user_data = await conn.fetch_one("""
|
|
114
|
+
SELECT
|
|
115
|
+
first_name, last_name, email,
|
|
116
|
+
job_code, title, department_code,
|
|
117
|
+
groups,
|
|
118
|
+
programs
|
|
119
|
+
FROM auth.vw_users u
|
|
120
|
+
WHERE u.user_id = $1
|
|
121
|
+
""", user_id)
|
|
122
|
+
|
|
123
|
+
if not user_data:
|
|
124
|
+
return []
|
|
125
|
+
|
|
126
|
+
# Convert to facts
|
|
127
|
+
facts = [
|
|
128
|
+
{
|
|
129
|
+
'content': f"User's name is {user_data['first_name']} {user_data['last_name']}",
|
|
130
|
+
'metadata': {'field': 'name'},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
'content': f"User's job title is {user_data['job_code']} in {user_data['department_code']}",
|
|
134
|
+
'metadata': {'field': 'position'},
|
|
135
|
+
},
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
if user_data['groups']:
|
|
139
|
+
facts.append({
|
|
140
|
+
'content': f"User has groups: {', '.join(user_data['groups'])}",
|
|
141
|
+
'metadata': {'field': 'groups'}
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
if user_data['programs']:
|
|
145
|
+
facts.append({
|
|
146
|
+
'content': f"User is enrolled in programs: {', '.join(user_data['programs'])}",
|
|
147
|
+
'metadata': {'field': 'programs'}
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
return facts
|
|
151
|
+
|
|
152
|
+
class SessionStateKB(AbstractKnowledgeBase):
|
|
153
|
+
"""KB that retrieves from session state."""
|
|
154
|
+
def __init__(self, **kwargs):
|
|
155
|
+
super().__init__(
|
|
156
|
+
name="User Session",
|
|
157
|
+
category="session",
|
|
158
|
+
activation_patterns=[
|
|
159
|
+
"preferences", "prefer", "like", "favorite",
|
|
160
|
+
"based on what I like"
|
|
161
|
+
]
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
async def search(self, query: str, ctx: RequestContext = None, **kwargs) -> List[Dict]:
|
|
165
|
+
"""Extract relevant session state."""
|
|
166
|
+
if not ctx or not ctx.request:
|
|
167
|
+
return []
|
|
168
|
+
|
|
169
|
+
session = ctx.request.session
|
|
170
|
+
facts = []
|
|
171
|
+
|
|
172
|
+
# Extract current workflow state
|
|
173
|
+
if 'current_workflow' in session:
|
|
174
|
+
facts.append({
|
|
175
|
+
'content': f"User is currently working on: {session['current_workflow']}",
|
|
176
|
+
'metadata': {'source': 'session'}
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
return facts
|
|
180
|
+
|
|
181
|
+
class UserPreferences(RedisKnowledgeBase):
|
|
182
|
+
"""KB for user preferences stored in Redis."""
|
|
183
|
+
|
|
184
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
185
|
+
super().__init__(
|
|
186
|
+
name="User Preferences",
|
|
187
|
+
category="preferences",
|
|
188
|
+
activation_patterns=[
|
|
189
|
+
"preferences", "prefer", "like", "favorite",
|
|
190
|
+
"based on what I like", "my preferences"
|
|
191
|
+
],
|
|
192
|
+
namespace="user_prefs",
|
|
193
|
+
use_hash_storage=True,
|
|
194
|
+
ttl=86400 * 365, # 1 year expiration
|
|
195
|
+
**kwargs,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
async def search(
|
|
199
|
+
self,
|
|
200
|
+
query: str,
|
|
201
|
+
user_id: Optional[str] = None,
|
|
202
|
+
**kwargs
|
|
203
|
+
) -> List[Dict[str, Any]]:
|
|
204
|
+
"""
|
|
205
|
+
Retrieve user preferences matching the query.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
query: Search query
|
|
209
|
+
user_id: User identifier (required)
|
|
210
|
+
**kwargs: Additional parameters
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
List of preference facts
|
|
214
|
+
"""
|
|
215
|
+
if not user_id:
|
|
216
|
+
return []
|
|
217
|
+
|
|
218
|
+
# Get all preferences for user
|
|
219
|
+
prefs = await self.get(user_id)
|
|
220
|
+
|
|
221
|
+
if not prefs:
|
|
222
|
+
return []
|
|
223
|
+
|
|
224
|
+
facts = []
|
|
225
|
+
query_lower = query.lower()
|
|
226
|
+
|
|
227
|
+
for key, value in prefs.items():
|
|
228
|
+
# Check if query matches key or value
|
|
229
|
+
if query_lower in key.lower() or query_lower in str(value).lower():
|
|
230
|
+
# Calculate relevance
|
|
231
|
+
relevance = 1.0 if query_lower == key.lower() else 0.5
|
|
232
|
+
if query_lower in str(value).lower():
|
|
233
|
+
relevance += 0.3
|
|
234
|
+
|
|
235
|
+
facts.append({
|
|
236
|
+
'content': f"User prefers {key}: {value}",
|
|
237
|
+
'metadata': {
|
|
238
|
+
'preference': key,
|
|
239
|
+
'value': value,
|
|
240
|
+
'user_id': user_id
|
|
241
|
+
},
|
|
242
|
+
'source': 'user_preferences',
|
|
243
|
+
'relevance': min(relevance, 1.0) # Cap at 1.0
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
# Sort by relevance
|
|
247
|
+
facts.sort(key=lambda x: x['relevance'], reverse=True)
|
|
248
|
+
return facts
|
|
249
|
+
|
|
250
|
+
async def set_preference(
|
|
251
|
+
self,
|
|
252
|
+
user_id: str,
|
|
253
|
+
preference: str,
|
|
254
|
+
value: Any
|
|
255
|
+
) -> bool:
|
|
256
|
+
"""
|
|
257
|
+
Set a single user preference.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
user_id: User identifier
|
|
261
|
+
preference: Preference name
|
|
262
|
+
value: Preference value
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
True if successful
|
|
266
|
+
"""
|
|
267
|
+
return await self.insert(user_id, value, field=preference)
|
|
268
|
+
|
|
269
|
+
async def get_preference(
|
|
270
|
+
self,
|
|
271
|
+
user_id: str,
|
|
272
|
+
preference: str,
|
|
273
|
+
default: Any = None
|
|
274
|
+
) -> Any:
|
|
275
|
+
"""
|
|
276
|
+
Get a single user preference.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
user_id: User identifier
|
|
280
|
+
preference: Preference name
|
|
281
|
+
default: Default value if not found
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
Preference value or default
|
|
285
|
+
"""
|
|
286
|
+
return await self.get(user_id, field=preference, default=default)
|
|
287
|
+
|
|
288
|
+
async def delete_preference(
|
|
289
|
+
self,
|
|
290
|
+
user_id: str,
|
|
291
|
+
preference: str
|
|
292
|
+
) -> bool:
|
|
293
|
+
"""
|
|
294
|
+
Delete a single user preference.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
user_id: User identifier
|
|
298
|
+
preference: Preference name
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
True if successful
|
|
302
|
+
"""
|
|
303
|
+
return await self.delete(user_id, field=preference)
|
|
304
|
+
|
|
305
|
+
async def get_all_preferences(self, user_id: str) -> Dict[str, Any]:
|
|
306
|
+
"""
|
|
307
|
+
Get all preferences for a user.
|
|
308
|
+
|
|
309
|
+
Args:
|
|
310
|
+
user_id: User identifier
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
Dict of all preferences
|
|
314
|
+
"""
|
|
315
|
+
return await self.get(user_id, default={})
|
|
316
|
+
|
|
317
|
+
async def clear_all_preferences(self, user_id: str) -> bool:
|
|
318
|
+
"""
|
|
319
|
+
Clear all preferences for a user.
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
user_id: User identifier
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
True if successful
|
|
326
|
+
"""
|
|
327
|
+
return await self.delete(user_id)
|
|
328
|
+
|
|
329
|
+
async def update_preferences(
|
|
330
|
+
self,
|
|
331
|
+
user_id: str,
|
|
332
|
+
preferences: Dict[str, Any]
|
|
333
|
+
) -> bool:
|
|
334
|
+
"""
|
|
335
|
+
Update multiple preferences at once.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
user_id: User identifier
|
|
339
|
+
preferences: Dictionary of preferences to update
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
True if successful
|
|
343
|
+
"""
|
|
344
|
+
return await self.update(user_id, preferences)
|
|
345
|
+
|
|
346
|
+
async def has_preference(
|
|
347
|
+
self,
|
|
348
|
+
user_id: str,
|
|
349
|
+
preference: str
|
|
350
|
+
) -> bool:
|
|
351
|
+
"""
|
|
352
|
+
Check if a user has a specific preference set.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
user_id: User identifier
|
|
356
|
+
preference: Preference name
|
|
357
|
+
|
|
358
|
+
Returns:
|
|
359
|
+
True if preference exists
|
|
360
|
+
"""
|
|
361
|
+
return await self.exists(user_id, field=preference)
|
|
362
|
+
|
|
363
|
+
async def list_user_preference_keys(self, user_id: str) -> List[str]:
|
|
364
|
+
"""
|
|
365
|
+
Get list of all preference keys for a user.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
user_id: User identifier
|
|
369
|
+
|
|
370
|
+
Returns:
|
|
371
|
+
List of preference keys
|
|
372
|
+
"""
|
|
373
|
+
prefs = await self.get_all_preferences(user_id)
|
|
374
|
+
return list(prefs.keys()) if prefs else []
|
parrot/stores/models.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from typing import Dict, Any, Optional, Union
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SearchResult(BaseModel):
|
|
8
|
+
"""
|
|
9
|
+
Data model for a single document returned from a vector search.
|
|
10
|
+
"""
|
|
11
|
+
id: str
|
|
12
|
+
content: str
|
|
13
|
+
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
14
|
+
score: float
|
|
15
|
+
ensemble_score: float = None
|
|
16
|
+
search_source: str = None
|
|
17
|
+
similarity_rank: Optional[int] = None
|
|
18
|
+
mmr_rank: Optional[int] = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Document(BaseModel):
|
|
22
|
+
"""
|
|
23
|
+
A simple document model for adding data to the vector store.
|
|
24
|
+
This replaces langchain.docstore.document.Document.
|
|
25
|
+
"""
|
|
26
|
+
page_content: str
|
|
27
|
+
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class DistanceStrategy(str, Enum):
|
|
31
|
+
"""Enumerator of the Distance strategies for calculating distances
|
|
32
|
+
between vectors."""
|
|
33
|
+
|
|
34
|
+
EUCLIDEAN_DISTANCE = "EUCLIDEAN_DISTANCE"
|
|
35
|
+
MAX_INNER_PRODUCT = "MAX_INNER_PRODUCT"
|
|
36
|
+
DOT_PRODUCT = "DOT_PRODUCT"
|
|
37
|
+
JACCARD = "JACCARD"
|
|
38
|
+
COSINE = "COSINE"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class StoreConfig:
|
|
43
|
+
"""Vector Store configuration dataclass."""
|
|
44
|
+
vector_store: str = 'postgres' # postgres, faiss, arango, etc.
|
|
45
|
+
table: Optional[str] = None
|
|
46
|
+
schema: str = 'public'
|
|
47
|
+
embedding_model: Union[str, dict] = field(
|
|
48
|
+
default_factory=lambda: {
|
|
49
|
+
"model": "sentence-transformers/all-mpnet-base-v2",
|
|
50
|
+
"model_type": "huggingface"
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
dimension: int = 768
|
|
54
|
+
dsn: Optional[str] = None
|
|
55
|
+
distance_strategy: str = 'COSINE'
|
|
56
|
+
metric_type: str = 'COSINE'
|
|
57
|
+
index_type: str = 'IVF_FLAT'
|
|
58
|
+
auto_create: bool = False # Auto-create collection on configure
|
|
59
|
+
extra: Dict[str, Any] = field(default_factory=dict)
|