solace-agent-mesh 1.7.1__py3-none-any.whl → 1.7.2__py3-none-any.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.
Potentially problematic release.
This version of solace-agent-mesh might be problematic. Click here for more details.
- solace_agent_mesh/agent/proxies/base/component.py +11 -8
- solace_agent_mesh/agent/utils/artifact_helpers.py +45 -0
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/60702c0e.f9a9923a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.5d2e116a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.d98a6526.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.cc09c4ff.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.9232f4b5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{e6f9706b.045d0fa1.js → e6f9706b.4488e34c.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.c7ffdd82.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.60cfcf1b.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.ec22999d.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +4 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +4 -18
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +10 -5
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +31 -29
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +90 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +3 -3
- solace_agent_mesh/assets/docs/lunr-index-1762293572268.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1762293572268.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/eval_cmd.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +2 -2
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +2 -1
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +3 -3
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-tcIFZLis.js → authCallback-CaZrPAYy.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-CRYdKo2Q.js → client-cVxTmrt6.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-BGZP_riA.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-CBFhYdbQ.js +349 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CINwxvwV.js → vendor-BzZcWrf0.js} +83 -88
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
- solace_agent_mesh/common/sac/sam_component_base.py +44 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{_index-ByU1X1HD.js → _index-Ch6HyL-d.js} +21 -16
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-61038fc6.js → manifest-27eb8c5f.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-B17tZKK7.css +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/index.html +2 -2
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +2 -43
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +2 -2
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +8 -103
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +1 -0
- solace_agent_mesh/gateway/http_sse/routers/projects.py +40 -16
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/project_service.py +47 -1
- solace_agent_mesh/gateway/http_sse/services/session_service.py +3 -3
- solace_agent_mesh/llm_detail.txt +3 -3
- solace_agent_mesh/templates/logging_config_template.yaml +43 -0
- solace_agent_mesh/templates/main_orchestrator.yaml +12 -1
- solace_agent_mesh/templates/plugin_readme_template.md +3 -25
- solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.7.2.dist-info}/METADATA +3 -2
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.7.2.dist-info}/RECORD +115 -113
- solace_agent_mesh/assets/docs/assets/js/15e40e79.36003774.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/66d4869e.830d443f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5099c51e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.f213fe0c.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d9606d6a.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1762283454666.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1762283454666.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-CojeY_1w.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-ILja9MCG.js +0 -353
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-DxRwaWiE.css +0 -1
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_fulltext_search_indexes.py +0 -92
- solace_agent_mesh/templates/logging_config_template.ini +0 -45
- /solace_agent_mesh/assets/docs/assets/js/{main.f213fe0c.js.LICENSE.txt → main.60cfcf1b.js.LICENSE.txt} +0 -0
- /solace_agent_mesh/config_portal/frontend/static/client/assets/{root-BWvk5-gF.js → root-V2BeTIUc.js} +0 -0
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.7.2.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.7.2.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.7.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
window.__remixManifest={"entry":{"module":"/assets/entry.client-mvZjNKiz.js","imports":["/assets/index-DzNKzXrc.js","/assets/components-Rk0n-9cK.js"],"css":[]},"routes":{"root":{"id":"root","path":"","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/root-
|
|
1
|
+
window.__remixManifest={"entry":{"module":"/assets/entry.client-mvZjNKiz.js","imports":["/assets/index-DzNKzXrc.js","/assets/components-Rk0n-9cK.js"],"css":[]},"routes":{"root":{"id":"root","path":"","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/root-V2BeTIUc.js","imports":["/assets/index-DzNKzXrc.js","/assets/components-Rk0n-9cK.js"],"css":["/assets/root-B17tZKK7.css"]},"routes/_index":{"id":"routes/_index","parentId":"root","index":true,"hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_index-Ch6HyL-d.js","imports":["/assets/index-DzNKzXrc.js"],"css":[]}},"url":"/assets/manifest-27eb8c5f.js","version":"27eb8c5f"};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.bottom-0{bottom:0}.left-0{left:0}.left-1{left:.25rem}.right-0{right:0}.right-3{right:.75rem}.top-0{top:0}.top-1{top:.25rem}.top-1\/2{top:50%}.top-5{top:1.25rem}.z-10{z-index:10}.z-50{z-index:50}.col-span-2{grid-column:span 2 / span 2}.-m-6{margin:-1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.-mb-10{margin-bottom:-2.5rem}.-ml-1{margin-left:-.25rem}.-ml-10{margin-left:-2.5rem}.-mr-10{margin-right:-2.5rem}.-mt-10{margin-top:-2.5rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-9{margin-left:2.25rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.mr-9{margin-right:2.25rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-2\.5{margin-top:.625rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-1{height:.25rem}.h-10{height:2.5rem}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-\[280px\]{height:280px}.h-full{height:100%}.max-h-60{max-height:15rem}.max-h-8{max-height:2rem}.max-h-96{max-height:24rem}.max-h-\[70vh\]{max-height:70vh}.max-h-\[90vh\]{max-height:90vh}.min-h-\[300px\]{min-height:300px}.min-h-\[400px\]{min-height:400px}.min-h-\[40px\]{min-height:40px}.min-h-\[500px\]{min-height:500px}.min-h-screen{min-height:100vh}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-20{width:5rem}.w-24{width:6rem}.w-3\/4{width:75%}.w-32{width:8rem}.w-4{width:1rem}.w-40{width:10rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[100px\]{min-width:100px}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-md{max-width:28rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-5{--tw-translate-x: 1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.75rem * var(--tw-space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-current{border-color:currentColor}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-green-500\/50{border-color:#22c55e80}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-red-500\/50{border-color:#ef444480}.border-slate-200{--tw-border-opacity: 1;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1))}.border-solace-blue{--tw-border-opacity: 1;border-color:rgb(32 52 74 / var(--tw-border-opacity, 1))}.border-solace-green{--tw-border-opacity: 1;border-color:rgb(0 175 131 / var(--tw-border-opacity, 1))}.border-t-transparent{border-top-color:transparent}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/60{background-color:#0009}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-300{--tw-bg-opacity: 1;background-color:rgb(209 213 219 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-200{--tw-bg-opacity: 1;background-color:rgb(187 247 208 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-slate-50{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.bg-solace-blue{--tw-bg-opacity: 1;background-color:rgb(32 52 74 / var(--tw-bg-opacity, 1))}.bg-solace-dark-green{--tw-bg-opacity: 1;background-color:rgb(6 143 108 / var(--tw-bg-opacity, 1))}.bg-solace-green{--tw-bg-opacity: 1;background-color:rgb(0 175 131 / var(--tw-bg-opacity, 1))}.bg-solace-light-blue\/10{background-color:#0320341a}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-50{--tw-bg-opacity: 1;background-color:rgb(254 252 232 / var(--tw-bg-opacity, 1))}.bg-opacity-10{--tw-bg-opacity: .1}.bg-opacity-50{--tw-bg-opacity: .5}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-green-50{--tw-gradient-from: #f0fdf4 var(--tw-gradient-from-position);--tw-gradient-to: rgb(240 253 244 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-blue-50{--tw-gradient-to: #eff6ff var(--tw-gradient-to-position)}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-10{padding:2.5rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-1{padding-left:.25rem}.pl-4{padding-left:1rem}.pr-10{padding-right:2.5rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:Inter,ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.text-solace-blue{--tw-text-opacity: 1;color:rgb(32 52 74 / var(--tw-text-opacity, 1))}.text-solace-dark-green{--tw-text-opacity: 1;color:rgb(6 143 108 / var(--tw-text-opacity, 1))}.text-solace-green{--tw-text-opacity: 1;color:rgb(0 175 131 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-800{--tw-text-opacity: 1;color:rgb(133 77 14 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.opacity-100{opacity:1}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}html,body{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));color-scheme:light}.placeholder\:text-gray-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.placeholder\:text-gray-400::placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.last\:mb-0:last-child{margin-bottom:0}.last\:border-0:last-child{border-width:0px}.last\:pb-0:last-child{padding-bottom:0}.hover\:border-solace-blue\/30:hover{border-color:#20344a4d}.hover\:border-solace-blue\/50:hover{border-color:#20344a80}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-300:hover{--tw-bg-opacity: 1;background-color:rgb(209 213 219 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-green-600:hover{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.hover\:bg-green-700:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.hover\:bg-indigo-700:hover{--tw-bg-opacity: 1;background-color:rgb(67 56 202 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-solace-blue:hover{--tw-bg-opacity: 1;background-color:rgb(32 52 74 / var(--tw-bg-opacity, 1))}.hover\:bg-solace-dark-green:hover{--tw-bg-opacity: 1;background-color:rgb(6 143 108 / var(--tw-bg-opacity, 1))}.hover\:bg-stone-300:hover{--tw-bg-opacity: 1;background-color:rgb(214 211 209 / var(--tw-bg-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-gray-900:hover{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.hover\:text-red-800:hover{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.hover\:text-solace-blue:hover{--tw-text-opacity: 1;color:rgb(32 52 74 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:border-blue-500:focus{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.focus\:border-solace-blue:focus{--tw-border-opacity: 1;border-color:rgb(32 52 74 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.focus\:ring-gray-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(156 163 175 / var(--tw-ring-opacity, 1))}.focus\:ring-gray-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity, 1))}.focus\:ring-green-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(34 197 94 / var(--tw-ring-opacity, 1))}.focus\:ring-solace-blue:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(32 52 74 / var(--tw-ring-opacity, 1))}.focus\:ring-solace-green:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(0 175 131 / var(--tw-ring-opacity, 1))}.focus\:ring-opacity-50:focus{--tw-ring-opacity: .5}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-blue-500:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.focus-visible\:ring-offset-1:focus-visible{--tw-ring-offset-width: 1px}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-100:disabled{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.disabled\:bg-solace-green\/50:disabled{background-color:#00af8380}.disabled\:text-gray-400:disabled{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.disabled\:text-gray-500:disabled{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:bg-opacity-20{--tw-bg-opacity: .2}.group:hover .group-hover\:text-solace-blue{--tw-text-opacity: 1;color:rgb(32 52 74 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.sm\:col-span-2{grid-column:span 2 / span 2}.sm\:mt-0{margin-top:0}.sm\:grid{display:grid}.sm\:w-1\/2{width:50%}.sm\:w-auto{width:auto}.sm\:min-w-\[140px\]{min-width:140px}.sm\:flex-grow{flex-grow:1}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:gap-4{gap:1rem}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}@media (min-width: 768px){.md\:hidden{display:none}.md\:flex-grow{flex-grow:1}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:p-6{padding:1.5rem}.md\:p-8{padding:2rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}}@media (min-width: 1024px){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:p-8{padding:2rem}}@media (min-width: 1280px){.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (prefers-color-scheme: dark){.dark\:border-gray-600{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))}.dark\:border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.dark\:border-slate-600{--tw-border-opacity: 1;border-color:rgb(71 85 105 / var(--tw-border-opacity, 1))}.dark\:bg-black\/70{background-color:#000000b3}.dark\:bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-700{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-700\/30{background-color:#3741514d}.dark\:bg-gray-700\/50{background-color:#37415180}.dark\:bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.dark\:bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.dark\:bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.dark\:bg-green-900\/30{background-color:#14532d4d}.dark\:bg-indigo-500{--tw-bg-opacity: 1;background-color:rgb(99 102 241 / var(--tw-bg-opacity, 1))}.dark\:bg-red-900\/30{background-color:#7f1d1d4d}.dark\:bg-slate-700\/50{background-color:#33415580}.dark\:text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.dark\:text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.dark\:text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.dark\:text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.dark\:text-green-300{--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.dark\:text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.dark\:text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:placeholder\:text-gray-500::-moz-placeholder{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.dark\:placeholder\:text-gray-500::placeholder{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.dark\:hover\:bg-blue-600:hover{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-gray-500:hover{--tw-bg-opacity: 1;background-color:rgb(107 114 128 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-gray-600:hover{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-green-600:hover{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-green-700:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-indigo-600:hover{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.dark\:hover\:text-gray-300:hover{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.dark\:focus-visible\:ring-blue-400:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(96 165 250 / var(--tw-ring-opacity, 1))}.dark\:focus-visible\:ring-offset-gray-800:focus-visible{--tw-ring-offset-color: #1f2937}}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/assets/root-
|
|
3
|
-
import * as route0 from "/assets/root-
|
|
2
|
+
<html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/assets/root-B17tZKK7.css"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"/></head><body><p>Loading...</p><link rel="modulepreload" href="/assets/manifest-27eb8c5f.js"/><link rel="modulepreload" href="/assets/entry.client-mvZjNKiz.js"/><link rel="modulepreload" href="/assets/index-DzNKzXrc.js"/><link rel="modulepreload" href="/assets/components-Rk0n-9cK.js"/><link rel="modulepreload" href="/assets/root-V2BeTIUc.js"/><script>window.__remixContext = {"basename":"/","future":{"v3_fetcherPersist":false,"v3_relativeSplatPath":false,"v3_throwAbortReason":false,"v3_routeConfig":false,"v3_singleFetch":false,"v3_lazyRouteDiscovery":false,"unstable_optimizeDeps":false},"isSpaMode":true,"state":{"loaderData":{"root":null,"routes/_index":null},"actionData":null,"errors":null}};</script><script type="module" async="">import "/assets/manifest-27eb8c5f.js";
|
|
3
|
+
import * as route0 from "/assets/root-V2BeTIUc.js";
|
|
4
4
|
|
|
5
5
|
window.__remixRouteModules = {"root":route0};
|
|
6
6
|
|
|
@@ -65,56 +65,15 @@ def upgrade() -> None:
|
|
|
65
65
|
op.create_index('ix_projects_user_deleted', 'projects', ['user_id', 'deleted_at'])
|
|
66
66
|
except Exception:
|
|
67
67
|
pass
|
|
68
|
-
|
|
69
|
-
# Enable pg_trgm extension for fuzzy text search (PostgreSQL only)
|
|
70
|
-
try:
|
|
71
|
-
op.execute('CREATE EXTENSION IF NOT EXISTS pg_trgm')
|
|
72
|
-
except Exception:
|
|
73
|
-
# Not PostgreSQL or extension already exists
|
|
74
|
-
pass
|
|
75
|
-
|
|
76
|
-
# Create GIN indexes for text search on sessions
|
|
77
|
-
if 'sessions' in inspector.get_table_names():
|
|
78
|
-
try:
|
|
79
|
-
# Index on session name for fuzzy search
|
|
80
|
-
op.execute(
|
|
81
|
-
'CREATE INDEX IF NOT EXISTS ix_sessions_name_trgm ON sessions '
|
|
82
|
-
'USING gin (name gin_trgm_ops)'
|
|
83
|
-
)
|
|
84
|
-
except Exception:
|
|
85
|
-
pass
|
|
86
|
-
|
|
87
|
-
# Create GIN indexes for text search on chat_tasks
|
|
88
|
-
if 'chat_tasks' in inspector.get_table_names():
|
|
89
|
-
try:
|
|
90
|
-
# Index on user_message for content search
|
|
91
|
-
op.execute(
|
|
92
|
-
'CREATE INDEX IF NOT EXISTS ix_chat_tasks_user_message_trgm ON chat_tasks '
|
|
93
|
-
'USING gin (user_message gin_trgm_ops)'
|
|
94
|
-
)
|
|
95
|
-
except Exception:
|
|
96
|
-
pass
|
|
97
68
|
|
|
98
69
|
|
|
99
70
|
def downgrade() -> None:
|
|
100
71
|
"""Remove soft delete columns and search indexes."""
|
|
101
72
|
bind = op.get_bind()
|
|
102
73
|
inspector = inspect(bind)
|
|
103
|
-
|
|
104
|
-
# Drop
|
|
105
|
-
if 'chat_tasks' in inspector.get_table_names():
|
|
106
|
-
try:
|
|
107
|
-
op.execute('DROP INDEX IF EXISTS ix_chat_tasks_user_message_trgm')
|
|
108
|
-
except Exception:
|
|
109
|
-
pass
|
|
110
|
-
|
|
111
|
-
# Drop search indexes from sessions
|
|
74
|
+
|
|
75
|
+
# Drop soft delete indexes from sessions
|
|
112
76
|
if 'sessions' in inspector.get_table_names():
|
|
113
|
-
try:
|
|
114
|
-
op.execute('DROP INDEX IF EXISTS ix_sessions_name_trgm')
|
|
115
|
-
except Exception:
|
|
116
|
-
pass
|
|
117
|
-
|
|
118
77
|
try:
|
|
119
78
|
op.drop_index('ix_sessions_user_deleted', table_name='sessions')
|
|
120
79
|
except Exception:
|
solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""add default agent to projects
|
|
2
2
|
|
|
3
3
|
Revision ID: default_agent_001
|
|
4
|
-
Revises:
|
|
4
|
+
Revises: soft_del_search_001
|
|
5
5
|
Create Date: 2025-01-24 01:13:00.000000
|
|
6
6
|
|
|
7
7
|
"""
|
|
@@ -11,7 +11,7 @@ import sqlalchemy as sa
|
|
|
11
11
|
|
|
12
12
|
# revision identifiers, used by Alembic.
|
|
13
13
|
revision = 'default_agent_001'
|
|
14
|
-
down_revision = '
|
|
14
|
+
down_revision = 'soft_del_search_001'
|
|
15
15
|
branch_labels = None
|
|
16
16
|
depends_on = None
|
|
17
17
|
|
|
@@ -12,7 +12,6 @@ from ..shared import now_epoch_ms
|
|
|
12
12
|
from .entities import Session
|
|
13
13
|
from .interfaces import ISessionRepository
|
|
14
14
|
from .models import CreateSessionModel, SessionModel, UpdateSessionModel
|
|
15
|
-
from .models.chat_task_model import ChatTaskModel
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepository):
|
|
@@ -217,10 +216,7 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
217
216
|
project_id: str | None = None
|
|
218
217
|
) -> list[Session]:
|
|
219
218
|
"""
|
|
220
|
-
Search sessions by name
|
|
221
|
-
|
|
222
|
-
Uses PostgreSQL full-text search when available (for queries >= 3 chars),
|
|
223
|
-
falls back to ILIKE for SQLite or short queries.
|
|
219
|
+
Search sessions by name/title only using ILIKE.
|
|
224
220
|
"""
|
|
225
221
|
# Base query - only non-deleted sessions for the user
|
|
226
222
|
base_query = db_session.query(SessionModel).filter(
|
|
@@ -232,54 +228,9 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
232
228
|
if project_id is not None:
|
|
233
229
|
base_query = base_query.filter(SessionModel.project_id == project_id)
|
|
234
230
|
|
|
235
|
-
#
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if use_fts:
|
|
240
|
-
# PostgreSQL full-text search for better performance
|
|
241
|
-
matching_chat_tasks = (
|
|
242
|
-
db_session.query(ChatTaskModel.session_id)
|
|
243
|
-
.filter(
|
|
244
|
-
or_(
|
|
245
|
-
func.to_tsvector('english', func.coalesce(ChatTaskModel.user_message, ''))
|
|
246
|
-
.op('@@')(func.plainto_tsquery('english', query)),
|
|
247
|
-
func.to_tsvector('english', ChatTaskModel.message_bubbles)
|
|
248
|
-
.op('@@')(func.plainto_tsquery('english', query))
|
|
249
|
-
)
|
|
250
|
-
)
|
|
251
|
-
.distinct()
|
|
252
|
-
.subquery()
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
search_query = base_query.filter(
|
|
256
|
-
or_(
|
|
257
|
-
func.to_tsvector('english', func.coalesce(SessionModel.name, ''))
|
|
258
|
-
.op('@@')(func.plainto_tsquery('english', query)),
|
|
259
|
-
SessionModel.id.in_(matching_chat_tasks)
|
|
260
|
-
)
|
|
261
|
-
)
|
|
262
|
-
else:
|
|
263
|
-
# ILIKE search for SQLite or short queries
|
|
264
|
-
search_pattern = f"%{query}%"
|
|
265
|
-
matching_chat_tasks = (
|
|
266
|
-
db_session.query(ChatTaskModel.session_id)
|
|
267
|
-
.filter(
|
|
268
|
-
or_(
|
|
269
|
-
ChatTaskModel.user_message.ilike(search_pattern),
|
|
270
|
-
ChatTaskModel.message_bubbles.ilike(search_pattern)
|
|
271
|
-
)
|
|
272
|
-
)
|
|
273
|
-
.distinct()
|
|
274
|
-
.subquery()
|
|
275
|
-
)
|
|
276
|
-
|
|
277
|
-
search_query = base_query.filter(
|
|
278
|
-
or_(
|
|
279
|
-
SessionModel.name.ilike(search_pattern),
|
|
280
|
-
SessionModel.id.in_(matching_chat_tasks)
|
|
281
|
-
)
|
|
282
|
-
)
|
|
231
|
+
# ILIKE search on session name
|
|
232
|
+
search_pattern = f"%{query}%"
|
|
233
|
+
search_query = base_query.filter(SessionModel.name.ilike(search_pattern))
|
|
283
234
|
|
|
284
235
|
# Eager load project relationship
|
|
285
236
|
search_query = search_query.options(joinedload(SessionModel.project))
|
|
@@ -299,9 +250,7 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
299
250
|
project_id: str | None = None
|
|
300
251
|
) -> int:
|
|
301
252
|
"""
|
|
302
|
-
Count search results for pagination.
|
|
303
|
-
|
|
304
|
-
Uses same database-agnostic logic as search() method for consistency.
|
|
253
|
+
Count search results for pagination (title-only search).
|
|
305
254
|
"""
|
|
306
255
|
# Base query - only non-deleted sessions for the user
|
|
307
256
|
base_query = db_session.query(SessionModel).filter(
|
|
@@ -312,52 +261,8 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
312
261
|
if project_id is not None:
|
|
313
262
|
base_query = base_query.filter(SessionModel.project_id == project_id)
|
|
314
263
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if use_fts:
|
|
319
|
-
# PostgreSQL full-text search
|
|
320
|
-
matching_chat_tasks = (
|
|
321
|
-
db_session.query(ChatTaskModel.session_id)
|
|
322
|
-
.filter(
|
|
323
|
-
or_(
|
|
324
|
-
func.to_tsvector('english', func.coalesce(ChatTaskModel.user_message, ''))
|
|
325
|
-
.op('@@')(func.plainto_tsquery('english', query)),
|
|
326
|
-
func.to_tsvector('english', ChatTaskModel.message_bubbles)
|
|
327
|
-
.op('@@')(func.plainto_tsquery('english', query))
|
|
328
|
-
)
|
|
329
|
-
)
|
|
330
|
-
.distinct()
|
|
331
|
-
.subquery()
|
|
332
|
-
)
|
|
333
|
-
|
|
334
|
-
search_query = base_query.filter(
|
|
335
|
-
or_(
|
|
336
|
-
func.to_tsvector('english', func.coalesce(SessionModel.name, ''))
|
|
337
|
-
.op('@@')(func.plainto_tsquery('english', query)),
|
|
338
|
-
SessionModel.id.in_(matching_chat_tasks)
|
|
339
|
-
)
|
|
340
|
-
)
|
|
341
|
-
else:
|
|
342
|
-
# ILIKE search for SQLite or short queries
|
|
343
|
-
search_pattern = f"%{query}%"
|
|
344
|
-
matching_chat_tasks = (
|
|
345
|
-
db_session.query(ChatTaskModel.session_id)
|
|
346
|
-
.filter(
|
|
347
|
-
or_(
|
|
348
|
-
ChatTaskModel.user_message.ilike(search_pattern),
|
|
349
|
-
ChatTaskModel.message_bubbles.ilike(search_pattern)
|
|
350
|
-
)
|
|
351
|
-
)
|
|
352
|
-
.distinct()
|
|
353
|
-
.subquery()
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
search_query = base_query.filter(
|
|
357
|
-
or_(
|
|
358
|
-
SessionModel.name.ilike(search_pattern),
|
|
359
|
-
SessionModel.id.in_(matching_chat_tasks)
|
|
360
|
-
)
|
|
361
|
-
)
|
|
264
|
+
# ILIKE search on session name
|
|
265
|
+
search_pattern = f"%{query}%"
|
|
266
|
+
search_query = base_query.filter(SessionModel.name.ilike(search_pattern))
|
|
362
267
|
|
|
363
268
|
return search_query.count()
|
|
@@ -17,6 +17,7 @@ class ProjectResponse(BaseTimestampResponse):
|
|
|
17
17
|
description: Optional[str] = None
|
|
18
18
|
system_prompt: Optional[str] = Field(default=None, alias="systemPrompt")
|
|
19
19
|
default_agent_id: Optional[str] = Field(default=None, alias="defaultAgentId")
|
|
20
|
+
artifact_count: Optional[int] = Field(default=None, alias="artifactCount")
|
|
20
21
|
created_at: int = Field(alias="createdAt")
|
|
21
22
|
updated_at: Optional[int] = Field(default=None, alias="updatedAt")
|
|
22
23
|
|
|
@@ -165,6 +165,7 @@ async def create_project(
|
|
|
165
165
|
|
|
166
166
|
@router.get("/projects", response_model=ProjectListResponse)
|
|
167
167
|
async def get_user_projects(
|
|
168
|
+
include_artifact_count: bool = False,
|
|
168
169
|
user: dict = Depends(get_current_user),
|
|
169
170
|
project_service: ProjectService = Depends(get_project_service),
|
|
170
171
|
db: Session = Depends(get_db),
|
|
@@ -172,28 +173,51 @@ async def get_user_projects(
|
|
|
172
173
|
):
|
|
173
174
|
"""
|
|
174
175
|
Get all projects owned by the authenticated user.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
include_artifact_count: If True, includes artifact count for each project
|
|
175
179
|
"""
|
|
176
180
|
user_id = user.get("id")
|
|
177
|
-
log.info(f"Fetching projects for user_id: {user_id}")
|
|
181
|
+
log.info(f"Fetching projects for user_id: {user_id}, include_artifact_count: {include_artifact_count}")
|
|
178
182
|
|
|
179
183
|
try:
|
|
180
184
|
request_dto = GetProjectsRequest(user_id=user_id)
|
|
181
185
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
186
|
+
if include_artifact_count:
|
|
187
|
+
# Fetch projects with artifact counts
|
|
188
|
+
projects_with_counts = await project_service.get_user_projects_with_counts(db, request_dto.user_id)
|
|
189
|
+
|
|
190
|
+
project_responses = [
|
|
191
|
+
ProjectResponse(
|
|
192
|
+
id=p.id,
|
|
193
|
+
name=p.name,
|
|
194
|
+
user_id=p.user_id,
|
|
195
|
+
description=p.description,
|
|
196
|
+
system_prompt=p.system_prompt,
|
|
197
|
+
default_agent_id=p.default_agent_id,
|
|
198
|
+
artifact_count=count,
|
|
199
|
+
created_at=p.created_at,
|
|
200
|
+
updated_at=p.updated_at,
|
|
201
|
+
)
|
|
202
|
+
for p, count in projects_with_counts
|
|
203
|
+
]
|
|
204
|
+
else:
|
|
205
|
+
# Fetch projects without counts (faster)
|
|
206
|
+
projects = project_service.get_user_projects(db, request_dto.user_id)
|
|
207
|
+
|
|
208
|
+
project_responses = [
|
|
209
|
+
ProjectResponse(
|
|
210
|
+
id=p.id,
|
|
211
|
+
name=p.name,
|
|
212
|
+
user_id=p.user_id,
|
|
213
|
+
description=p.description,
|
|
214
|
+
system_prompt=p.system_prompt,
|
|
215
|
+
default_agent_id=p.default_agent_id,
|
|
216
|
+
created_at=p.created_at,
|
|
217
|
+
updated_at=p.updated_at,
|
|
218
|
+
)
|
|
219
|
+
for p in projects
|
|
220
|
+
]
|
|
197
221
|
|
|
198
222
|
return ProjectListResponse(
|
|
199
223
|
projects=project_responses,
|
|
@@ -7,7 +7,7 @@ import logging
|
|
|
7
7
|
from fastapi import UploadFile
|
|
8
8
|
from datetime import datetime, timezone
|
|
9
9
|
|
|
10
|
-
from ....agent.utils.artifact_helpers import get_artifact_info_list, save_artifact_with_metadata
|
|
10
|
+
from ....agent.utils.artifact_helpers import get_artifact_info_list, save_artifact_with_metadata, get_artifact_counts_batch
|
|
11
11
|
|
|
12
12
|
try:
|
|
13
13
|
from google.adk.artifacts import BaseArtifactService
|
|
@@ -162,6 +162,52 @@ class ProjectService:
|
|
|
162
162
|
db_projects = project_repository.get_user_projects(user_id)
|
|
163
163
|
return db_projects
|
|
164
164
|
|
|
165
|
+
async def get_user_projects_with_counts(self, db, user_id: str) -> List[tuple[Project, int]]:
|
|
166
|
+
"""
|
|
167
|
+
Get all projects owned by a specific user with artifact counts.
|
|
168
|
+
Uses batch counting for efficiency.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
db: Database session
|
|
172
|
+
user_id: The user ID
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
List[tuple[Project, int]]: List of tuples (project, artifact_count)
|
|
176
|
+
"""
|
|
177
|
+
self.logger.debug(f"Retrieving projects with artifact counts for user {user_id}")
|
|
178
|
+
projects = self.get_user_projects(db, user_id)
|
|
179
|
+
|
|
180
|
+
if not self.artifact_service or not projects:
|
|
181
|
+
# If no artifact service or no projects, return projects with 0 counts
|
|
182
|
+
return [(project, 0) for project in projects]
|
|
183
|
+
|
|
184
|
+
# Build list of session IDs for batch counting
|
|
185
|
+
session_ids = [f"project-{project.id}" for project in projects]
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
# Get all counts in a single batch operation
|
|
189
|
+
counts_by_session = await get_artifact_counts_batch(
|
|
190
|
+
artifact_service=self.artifact_service,
|
|
191
|
+
app_name=self.app_name,
|
|
192
|
+
user_id=user_id,
|
|
193
|
+
session_ids=session_ids,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# Map counts back to projects
|
|
197
|
+
projects_with_counts = []
|
|
198
|
+
for project in projects:
|
|
199
|
+
storage_session_id = f"project-{project.id}"
|
|
200
|
+
artifact_count = counts_by_session.get(storage_session_id, 0)
|
|
201
|
+
projects_with_counts.append((project, artifact_count))
|
|
202
|
+
|
|
203
|
+
self.logger.debug(f"Retrieved artifact counts for {len(projects)} projects in batch")
|
|
204
|
+
return projects_with_counts
|
|
205
|
+
|
|
206
|
+
except Exception as e:
|
|
207
|
+
self.logger.error(f"Failed to get artifact counts in batch: {e}")
|
|
208
|
+
# Fallback to 0 counts on error
|
|
209
|
+
return [(project, 0) for project in projects]
|
|
210
|
+
|
|
165
211
|
async def get_project_artifacts(self, db, project_id: str, user_id: str) -> List[ArtifactInfo]:
|
|
166
212
|
"""
|
|
167
213
|
Get a list of artifacts for a given project.
|
|
@@ -291,15 +291,15 @@ class SessionService:
|
|
|
291
291
|
project_id: str | None = None
|
|
292
292
|
) -> PaginatedResponse[Session]:
|
|
293
293
|
"""
|
|
294
|
-
Search sessions by name
|
|
295
|
-
|
|
294
|
+
Search sessions by name/title only.
|
|
295
|
+
|
|
296
296
|
Args:
|
|
297
297
|
db: Database session
|
|
298
298
|
user_id: User ID to filter sessions by
|
|
299
299
|
query: Search query string
|
|
300
300
|
pagination: Pagination parameters
|
|
301
301
|
project_id: Optional project ID to filter sessions by
|
|
302
|
-
|
|
302
|
+
|
|
303
303
|
Returns:
|
|
304
304
|
PaginatedResponse[Session]: Paginated search results
|
|
305
305
|
"""
|
solace_agent_mesh/llm_detail.txt
CHANGED
|
@@ -789,7 +789,7 @@ The `client` directory provides a Python-based client library for Agent-to-Agent
|
|
|
789
789
|
**Import:** `from src.solace_agent_mesh.common.client import A2ACardResolver`
|
|
790
790
|
|
|
791
791
|
**Classes:**
|
|
792
|
-
- `A2ACardResolver(base_url: str, agent_card_path: str = "/.well-known/agent.json")` - A client to discover and fetch an agent's capability card.
|
|
792
|
+
- `A2ACardResolver(base_url: str, agent_card_path: str = "/.well-known/agent-card.json")` - A client to discover and fetch an agent's capability card.
|
|
793
793
|
- `get_agent_card() -> AgentCard` - Makes an HTTP GET request to the constructed agent card URL, parses the JSON response, and returns it as an `AgentCard` object. Raises `A2AClientHTTPError` on network/status errors and `A2AClientJSONError` on parsing errors.
|
|
794
794
|
|
|
795
795
|
**Usage Examples:**
|
|
@@ -803,7 +803,7 @@ resolver = A2ACardResolver(base_url="https://some-agent.ai")
|
|
|
803
803
|
|
|
804
804
|
try:
|
|
805
805
|
# Fetch the agent's capability card from the default path
|
|
806
|
-
# (https://some-agent.ai/.well-known/agent.json)
|
|
806
|
+
# (https://some-agent.ai/.well-known/agent-card.json)
|
|
807
807
|
agent_card: AgentCard = resolver.get_agent_card()
|
|
808
808
|
print(f"Successfully fetched card for agent: {agent_card.name}")
|
|
809
809
|
print(f"Agent API URL: {agent_card.url}")
|
|
@@ -1265,7 +1265,7 @@ The `server` directory provides a complete, stand-alone Agent-to-Agent (A2A) com
|
|
|
1265
1265
|
- `port: int` - The port the server will listen on.
|
|
1266
1266
|
- `endpoint: str` - The main API endpoint path for receiving JSON-RPC requests.
|
|
1267
1267
|
- `task_manager: TaskManager` - The handler responsible for all task-related business logic.
|
|
1268
|
-
- `agent_card: AgentCard` - The metadata for the agent, served at `/.well-known/agent.json`.
|
|
1268
|
+
- `agent_card: AgentCard` - The metadata for the agent, served at `/.well-known/agent-card.json`.
|
|
1269
1269
|
|
|
1270
1270
|
**Usage Examples:**
|
|
1271
1271
|
```python
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
disable_existing_loggers: false
|
|
3
|
+
|
|
4
|
+
formatters:
|
|
5
|
+
simpleFormatter:
|
|
6
|
+
format: "%(asctime)s | %(levelname)-5s | %(threadName)s | %(name)s | %(message)s"
|
|
7
|
+
|
|
8
|
+
jsonFormatter:
|
|
9
|
+
"()": pythonjsonlogger.jsonlogger.JsonFormatter
|
|
10
|
+
format: "%(asctime)s %(levelname)s %(threadName)s %(name)s %(message)s"
|
|
11
|
+
|
|
12
|
+
handlers:
|
|
13
|
+
streamHandler:
|
|
14
|
+
class: logging.StreamHandler
|
|
15
|
+
formatter: simpleFormatter
|
|
16
|
+
stream: ext://sys.stdout
|
|
17
|
+
|
|
18
|
+
rotatingFileHandler:
|
|
19
|
+
class: logging.handlers.RotatingFileHandler
|
|
20
|
+
formatter: simpleFormatter
|
|
21
|
+
filename: sam.log
|
|
22
|
+
mode: a
|
|
23
|
+
maxBytes: 52428800
|
|
24
|
+
backupCount: 10
|
|
25
|
+
|
|
26
|
+
loggers:
|
|
27
|
+
solace_ai_connector:
|
|
28
|
+
level: ${LOGGING_SAC_LEVEL, INFO}
|
|
29
|
+
handlers: []
|
|
30
|
+
|
|
31
|
+
solace_agent_mesh:
|
|
32
|
+
level: ${LOGGING_SAM_LEVEL, INFO}
|
|
33
|
+
handlers: []
|
|
34
|
+
|
|
35
|
+
sam_trace:
|
|
36
|
+
level: ${LOGGING_SAM_TRACE_LEVEL, INFO}
|
|
37
|
+
handlers: []
|
|
38
|
+
|
|
39
|
+
root:
|
|
40
|
+
level: ${LOGGING_ROOT_LEVEL, WARNING}
|
|
41
|
+
handlers:
|
|
42
|
+
- streamHandler
|
|
43
|
+
- rotatingFileHandler
|
|
@@ -43,7 +43,18 @@ apps:
|
|
|
43
43
|
description: "__AGENT_CARD_DESCRIPTION__"
|
|
44
44
|
defaultInputModes: __DEFAULT_INPUT_MODES__
|
|
45
45
|
defaultOutputModes: __DEFAULT_OUTPUT_MODES__
|
|
46
|
-
skills:
|
|
46
|
+
skills:
|
|
47
|
+
- id: strategic_planning
|
|
48
|
+
name: Strategic Planning
|
|
49
|
+
description: Analyzes complex requests and creates structured execution plans, breaking down multi-step goals into logical sequences with clear checkpoints and progress tracking.
|
|
50
|
+
|
|
51
|
+
- id: agent_coordination
|
|
52
|
+
name: Agent Coordination
|
|
53
|
+
description: Identifies the most suitable specialized agents for specific tasks and coordinates multi-agent workflows, managing data handoffs and execution sequences to achieve complex objectives efficiently.
|
|
54
|
+
|
|
55
|
+
- id: artifact_management
|
|
56
|
+
name: Artifact Management
|
|
57
|
+
description: Creates, transforms, and manages various artifact types including documents, reports, and data files, with capabilities for content generation, formatting, embedding dynamic data, and applying sophisticated data transformations.
|
|
47
58
|
|
|
48
59
|
agent_card_publishing:
|
|
49
60
|
interval_seconds: __AGENT_CARD_PUBLISHING_INTERVAL__
|
|
@@ -1,34 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# __PLUGIN_PASCAL_CASE_NAME__ SAM Plugin
|
|
2
2
|
|
|
3
3
|
__PLUGIN_DESCRIPTION__
|
|
4
4
|
|
|
5
5
|
This is a plugin for Solace Agent Mesh (SAM).
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
The `config.yaml` in this plugin serves as a template. When you use `sam plugin add <component_name> --plugin __PLUGIN_KEBAB_CASE_NAME__`, the following placeholders in the YAML structure will be replaced with variations of `<component_name>`:
|
|
10
|
-
- `__COMPONENT_UPPER_SNAKE_CASE_NAME__`
|
|
11
|
-
- `__COMPONENT_KEBAB_CASE_NAME__`
|
|
12
|
-
- `__COMPONENT_PASCAL_CASE_NAME__`
|
|
13
|
-
|
|
14
|
-
Customize the `config.yaml` in this plugin directory to define the base configuration for components created from it.
|
|
15
|
-
|
|
16
|
-
## Source Code (`src/`)
|
|
17
|
-
The `src/` directory contains the Python source code for your plugin.
|
|
18
|
-
|
|
19
|
-
## Installation (as a developer of this plugin)
|
|
20
|
-
|
|
21
|
-
To build and install this plugin locally for testing:
|
|
22
|
-
```bash
|
|
23
|
-
sam plugin build
|
|
24
|
-
pip install dist/*.whl
|
|
25
|
-
```
|
|
26
|
-
(Or `pip install .` if preferred, `sam plugin build` is for creating the distributable wheel)
|
|
27
|
-
|
|
28
|
-
## Usage (as a user of this plugin)
|
|
7
|
+
## Installation
|
|
29
8
|
|
|
30
9
|
Once the plugin is installed (e.g., from PyPI or a local wheel file):
|
|
31
10
|
```bash
|
|
32
11
|
sam plugin add <your-new-component-name> --plugin __PLUGIN_KEBAB_CASE_NAME__
|
|
33
|
-
```
|
|
34
|
-
This will create a new component configuration at `configs/plugins/<your-new-component-name-kebab-case>.yaml`.
|
|
12
|
+
```
|