@xopcai/xopcbot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -0
- package/README.zh-CN.md +130 -0
- package/dist/__tests__/core.test.d.ts +1 -0
- package/dist/__tests__/core.test.js +72 -0
- package/dist/__tests__/core.test.js.map +1 -0
- package/dist/agent/fallback/__tests__/index.test.d.ts +1 -0
- package/dist/agent/fallback/__tests__/index.test.js +111 -0
- package/dist/agent/fallback/__tests__/index.test.js.map +1 -0
- package/dist/agent/fallback/candidates.d.ts +23 -0
- package/dist/agent/fallback/candidates.js +62 -0
- package/dist/agent/fallback/candidates.js.map +1 -0
- package/dist/agent/fallback/error.d.ts +22 -0
- package/dist/agent/fallback/error.js +27 -0
- package/dist/agent/fallback/error.js.map +1 -0
- package/dist/agent/fallback/index.d.ts +6 -0
- package/dist/agent/fallback/index.js +5 -0
- package/dist/agent/fallback/index.js.map +1 -0
- package/dist/agent/fallback/reason.d.ts +7 -0
- package/dist/agent/fallback/reason.js +78 -0
- package/dist/agent/fallback/reason.js.map +1 -0
- package/dist/agent/fallback/runner.d.ts +22 -0
- package/dist/agent/fallback/runner.js +34 -0
- package/dist/agent/fallback/runner.js.map +1 -0
- package/dist/agent/helpers.d.ts +38 -0
- package/dist/agent/helpers.js +122 -0
- package/dist/agent/helpers.js.map +1 -0
- package/dist/agent/index.d.ts +7 -0
- package/dist/agent/index.js +7 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/memory/compaction.d.ts +63 -0
- package/dist/agent/memory/compaction.js +233 -0
- package/dist/agent/memory/compaction.js.map +1 -0
- package/dist/agent/memory/window.d.ts +29 -0
- package/dist/agent/memory/window.js +64 -0
- package/dist/agent/memory/window.js.map +1 -0
- package/dist/agent/model-manager.d.ts +80 -0
- package/dist/agent/model-manager.js +213 -0
- package/dist/agent/model-manager.js.map +1 -0
- package/dist/agent/prompt/heartbeat.d.ts +97 -0
- package/dist/agent/prompt/heartbeat.js +313 -0
- package/dist/agent/prompt/heartbeat.js.map +1 -0
- package/dist/agent/prompt/index.d.ts +65 -0
- package/dist/agent/prompt/index.js +215 -0
- package/dist/agent/prompt/index.js.map +1 -0
- package/dist/agent/prompt/memory/index.d.ts +37 -0
- package/dist/agent/prompt/memory/index.js +241 -0
- package/dist/agent/prompt/memory/index.js.map +1 -0
- package/dist/agent/prompt/modes.d.ts +44 -0
- package/dist/agent/prompt/modes.js +167 -0
- package/dist/agent/prompt/modes.js.map +1 -0
- package/dist/agent/prompt/safety.d.ts +88 -0
- package/dist/agent/prompt/safety.js +290 -0
- package/dist/agent/prompt/safety.js.map +1 -0
- package/dist/agent/service.d.ts +91 -0
- package/dist/agent/service.js +641 -0
- package/dist/agent/service.js.map +1 -0
- package/dist/agent/session-tracker.d.ts +73 -0
- package/dist/agent/session-tracker.js +137 -0
- package/dist/agent/session-tracker.js.map +1 -0
- package/dist/agent/skills/__tests__/test-framework.test.d.ts +4 -0
- package/dist/agent/skills/__tests__/test-framework.test.js +343 -0
- package/dist/agent/skills/__tests__/test-framework.test.js.map +1 -0
- package/dist/agent/skills/config.d.ts +58 -0
- package/dist/agent/skills/config.js +212 -0
- package/dist/agent/skills/config.js.map +1 -0
- package/dist/agent/skills/index.d.ts +25 -0
- package/dist/agent/skills/index.js +349 -0
- package/dist/agent/skills/index.js.map +1 -0
- package/dist/agent/skills/installer.d.ts +38 -0
- package/dist/agent/skills/installer.js +352 -0
- package/dist/agent/skills/installer.js.map +1 -0
- package/dist/agent/skills/scanner.d.ts +32 -0
- package/dist/agent/skills/scanner.js +265 -0
- package/dist/agent/skills/scanner.js.map +1 -0
- package/dist/agent/skills/test-framework.d.ts +107 -0
- package/dist/agent/skills/test-framework.js +607 -0
- package/dist/agent/skills/test-framework.js.map +1 -0
- package/dist/agent/skills/types.d.ts +181 -0
- package/dist/agent/skills/types.js +7 -0
- package/dist/agent/skills/types.js.map +1 -0
- package/dist/agent/skills/watcher.d.ts +37 -0
- package/dist/agent/skills/watcher.js +124 -0
- package/dist/agent/skills/watcher.js.map +1 -0
- package/dist/agent/tools/communication.d.ts +18 -0
- package/dist/agent/tools/communication.js +56 -0
- package/dist/agent/tools/communication.js.map +1 -0
- package/dist/agent/tools/edit-diff.d.ts +21 -0
- package/dist/agent/tools/edit-diff.js +69 -0
- package/dist/agent/tools/edit-diff.js.map +1 -0
- package/dist/agent/tools/edit.d.ts +13 -0
- package/dist/agent/tools/edit.js +65 -0
- package/dist/agent/tools/edit.js.map +1 -0
- package/dist/agent/tools/find.d.ts +24 -0
- package/dist/agent/tools/find.js +99 -0
- package/dist/agent/tools/find.js.map +1 -0
- package/dist/agent/tools/grep.d.ts +33 -0
- package/dist/agent/tools/grep.js +183 -0
- package/dist/agent/tools/grep.js.map +1 -0
- package/dist/agent/tools/index.d.ts +13 -0
- package/dist/agent/tools/index.js +18 -0
- package/dist/agent/tools/index.js.map +1 -0
- package/dist/agent/tools/list-dir.d.ts +6 -0
- package/dist/agent/tools/list-dir.js +37 -0
- package/dist/agent/tools/list-dir.js.map +1 -0
- package/dist/agent/tools/memory-tool.d.ts +14 -0
- package/dist/agent/tools/memory-tool.js +81 -0
- package/dist/agent/tools/memory-tool.js.map +1 -0
- package/dist/agent/tools/path-utils.d.ts +4 -0
- package/dist/agent/tools/path-utils.js +13 -0
- package/dist/agent/tools/path-utils.js.map +1 -0
- package/dist/agent/tools/read.d.ts +7 -0
- package/dist/agent/tools/read.js +47 -0
- package/dist/agent/tools/read.js.map +1 -0
- package/dist/agent/tools/send-media.d.ts +18 -0
- package/dist/agent/tools/send-media.js +104 -0
- package/dist/agent/tools/send-media.js.map +1 -0
- package/dist/agent/tools/shell.d.ts +13 -0
- package/dist/agent/tools/shell.js +114 -0
- package/dist/agent/tools/shell.js.map +1 -0
- package/dist/agent/tools/truncate.d.ts +36 -0
- package/dist/agent/tools/truncate.js +98 -0
- package/dist/agent/tools/truncate.js.map +1 -0
- package/dist/agent/tools/web.d.ts +14 -0
- package/dist/agent/tools/web.js +109 -0
- package/dist/agent/tools/web.js.map +1 -0
- package/dist/agent/tools/write.d.ts +7 -0
- package/dist/agent/tools/write.js +35 -0
- package/dist/agent/tools/write.js.map +1 -0
- package/dist/agent/types.d.ts +8 -0
- package/dist/agent/types.js +2 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/agent/typing.d.ts +9 -0
- package/dist/agent/typing.js +32 -0
- package/dist/agent/typing.js.map +1 -0
- package/dist/auth/index.d.ts +12 -0
- package/dist/auth/index.js +14 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth/anthropic.d.ts +7 -0
- package/dist/auth/oauth/anthropic.js +89 -0
- package/dist/auth/oauth/anthropic.js.map +1 -0
- package/dist/auth/oauth/github-copilot.d.ts +8 -0
- package/dist/auth/oauth/github-copilot.js +35 -0
- package/dist/auth/oauth/github-copilot.js.map +1 -0
- package/dist/auth/oauth/google-antigravity.d.ts +7 -0
- package/dist/auth/oauth/google-antigravity.js +27 -0
- package/dist/auth/oauth/google-antigravity.js.map +1 -0
- package/dist/auth/oauth/google-gemini-cli.d.ts +7 -0
- package/dist/auth/oauth/google-gemini-cli.js +28 -0
- package/dist/auth/oauth/google-gemini-cli.js.map +1 -0
- package/dist/auth/oauth/index.d.ts +14 -0
- package/dist/auth/oauth/index.js +15 -0
- package/dist/auth/oauth/index.js.map +1 -0
- package/dist/auth/oauth/kimi.d.ts +8 -0
- package/dist/auth/oauth/kimi.js +104 -0
- package/dist/auth/oauth/kimi.js.map +1 -0
- package/dist/auth/oauth/minimax.d.ts +8 -0
- package/dist/auth/oauth/minimax.js +109 -0
- package/dist/auth/oauth/minimax.js.map +1 -0
- package/dist/auth/oauth/openai-codex.d.ts +7 -0
- package/dist/auth/oauth/openai-codex.js +33 -0
- package/dist/auth/oauth/openai-codex.js.map +1 -0
- package/dist/auth/oauth/pkce.d.ts +8 -0
- package/dist/auth/oauth/pkce.js +22 -0
- package/dist/auth/oauth/pkce.js.map +1 -0
- package/dist/auth/oauth/qwen.d.ts +7 -0
- package/dist/auth/oauth/qwen.js +114 -0
- package/dist/auth/oauth/qwen.js.map +1 -0
- package/dist/auth/oauth/types.d.ts +46 -0
- package/dist/auth/oauth/types.js +7 -0
- package/dist/auth/oauth/types.js.map +1 -0
- package/dist/auth/profiles/index.d.ts +16 -0
- package/dist/auth/profiles/index.js +17 -0
- package/dist/auth/profiles/index.js.map +1 -0
- package/dist/auth/profiles/oauth.d.ts +12 -0
- package/dist/auth/profiles/oauth.js +106 -0
- package/dist/auth/profiles/oauth.js.map +1 -0
- package/dist/auth/profiles/order.d.ts +19 -0
- package/dist/auth/profiles/order.js +63 -0
- package/dist/auth/profiles/order.js.map +1 -0
- package/dist/auth/profiles/profiles.d.ts +27 -0
- package/dist/auth/profiles/profiles.js +110 -0
- package/dist/auth/profiles/profiles.js.map +1 -0
- package/dist/auth/profiles/store.d.ts +17 -0
- package/dist/auth/profiles/store.js +234 -0
- package/dist/auth/profiles/store.js.map +1 -0
- package/dist/auth/profiles/types.d.ts +64 -0
- package/dist/auth/profiles/types.js +7 -0
- package/dist/auth/profiles/types.js.map +1 -0
- package/dist/auth/profiles/usage.d.ts +24 -0
- package/dist/auth/profiles/usage.js +99 -0
- package/dist/auth/profiles/usage.js.map +1 -0
- package/dist/auth/storage.d.ts +99 -0
- package/dist/auth/storage.js +315 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/bus/index.d.ts +3 -0
- package/dist/bus/index.js +2 -0
- package/dist/bus/index.js.map +1 -0
- package/dist/bus/queue.d.ts +20 -0
- package/dist/bus/queue.js +57 -0
- package/dist/bus/queue.js.map +1 -0
- package/dist/channels/__tests__/access-control.test.d.ts +4 -0
- package/dist/channels/__tests__/access-control.test.js +310 -0
- package/dist/channels/__tests__/access-control.test.js.map +1 -0
- package/dist/channels/__tests__/draft-stream.test.d.ts +4 -0
- package/dist/channels/__tests__/draft-stream.test.js +243 -0
- package/dist/channels/__tests__/draft-stream.test.js.map +1 -0
- package/dist/channels/__tests__/format.test.d.ts +4 -0
- package/dist/channels/__tests__/format.test.js +146 -0
- package/dist/channels/__tests__/format.test.js.map +1 -0
- package/dist/channels/__tests__/manager.test.d.ts +6 -0
- package/dist/channels/__tests__/manager.test.js +34 -0
- package/dist/channels/__tests__/manager.test.js.map +1 -0
- package/dist/channels/__tests__/typing-controller.test.d.ts +4 -0
- package/dist/channels/__tests__/typing-controller.test.js +109 -0
- package/dist/channels/__tests__/typing-controller.test.js.map +1 -0
- package/dist/channels/__tests__/update-offset-store.test.d.ts +7 -0
- package/dist/channels/__tests__/update-offset-store.test.js +35 -0
- package/dist/channels/__tests__/update-offset-store.test.js.map +1 -0
- package/dist/channels/access-control.d.ts +93 -0
- package/dist/channels/access-control.js +201 -0
- package/dist/channels/access-control.js.map +1 -0
- package/dist/channels/draft-stream.d.ts +55 -0
- package/dist/channels/draft-stream.js +211 -0
- package/dist/channels/draft-stream.js.map +1 -0
- package/dist/channels/format.d.ts +38 -0
- package/dist/channels/format.js +187 -0
- package/dist/channels/format.js.map +1 -0
- package/dist/channels/index.d.ts +22 -0
- package/dist/channels/index.js +23 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/manager.d.ts +30 -0
- package/dist/channels/manager.js +125 -0
- package/dist/channels/manager.js.map +1 -0
- package/dist/channels/telegram/__tests__/index.test.d.ts +4 -0
- package/dist/channels/telegram/__tests__/index.test.js +153 -0
- package/dist/channels/telegram/__tests__/index.test.js.map +1 -0
- package/dist/channels/telegram/__tests__/inline-keyboards.test.d.ts +4 -0
- package/dist/channels/telegram/__tests__/inline-keyboards.test.js +99 -0
- package/dist/channels/telegram/__tests__/inline-keyboards.test.js.map +1 -0
- package/dist/channels/telegram/client.d.ts +48 -0
- package/dist/channels/telegram/client.js +177 -0
- package/dist/channels/telegram/client.js.map +1 -0
- package/dist/channels/telegram/command-handler.d.ts +28 -0
- package/dist/channels/telegram/command-handler.js +209 -0
- package/dist/channels/telegram/command-handler.js.map +1 -0
- package/dist/channels/telegram/index.d.ts +8 -0
- package/dist/channels/telegram/index.js +9 -0
- package/dist/channels/telegram/index.js.map +1 -0
- package/dist/channels/telegram/inline-keyboards.d.ts +20 -0
- package/dist/channels/telegram/inline-keyboards.js +38 -0
- package/dist/channels/telegram/inline-keyboards.js.map +1 -0
- package/dist/channels/telegram/plugin.d.ts +33 -0
- package/dist/channels/telegram/plugin.js +640 -0
- package/dist/channels/telegram/plugin.js.map +1 -0
- package/dist/channels/telegram/webhook.d.ts +31 -0
- package/dist/channels/telegram/webhook.js +129 -0
- package/dist/channels/telegram/webhook.js.map +1 -0
- package/dist/channels/types.d.ts +186 -0
- package/dist/channels/types.js +7 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/channels/typing-controller.d.ts +47 -0
- package/dist/channels/typing-controller.js +117 -0
- package/dist/channels/typing-controller.js.map +1 -0
- package/dist/channels/update-offset-store.d.ts +37 -0
- package/dist/channels/update-offset-store.js +165 -0
- package/dist/channels/update-offset-store.js.map +1 -0
- package/dist/channels/whatsapp/index.d.ts +4 -0
- package/dist/channels/whatsapp/index.js +5 -0
- package/dist/channels/whatsapp/index.js.map +1 -0
- package/dist/channels/whatsapp/plugin.d.ts +27 -0
- package/dist/channels/whatsapp/plugin.js +66 -0
- package/dist/channels/whatsapp/plugin.js.map +1 -0
- package/dist/cli/__tests__/registry.test.d.ts +1 -0
- package/dist/cli/__tests__/registry.test.js +366 -0
- package/dist/cli/__tests__/registry.test.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +1 -0
- package/dist/cli/commands/agent.js +216 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +6 -0
- package/dist/cli/commands/auth.js +440 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/config.d.ts +1 -0
- package/dist/cli/commands/config.js +135 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/configure.d.ts +1 -0
- package/dist/cli/commands/configure.js +173 -0
- package/dist/cli/commands/configure.js.map +1 -0
- package/dist/cli/commands/cron.d.ts +1 -0
- package/dist/cli/commands/cron.js +81 -0
- package/dist/cli/commands/cron.js.map +1 -0
- package/dist/cli/commands/gateway.d.ts +1 -0
- package/dist/cli/commands/gateway.js +91 -0
- package/dist/cli/commands/gateway.js.map +1 -0
- package/dist/cli/commands/index.d.ts +0 -0
- package/dist/cli/commands/index.js +2 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/models.d.ts +1 -0
- package/dist/cli/commands/models.js +79 -0
- package/dist/cli/commands/models.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +1 -0
- package/dist/cli/commands/onboard.js +621 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/plugin.d.ts +1 -0
- package/dist/cli/commands/plugin.js +341 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/cli/commands/session.d.ts +1 -0
- package/dist/cli/commands/session.js +450 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/skills-test.d.ts +9 -0
- package/dist/cli/commands/skills-test.js +195 -0
- package/dist/cli/commands/skills-test.js.map +1 -0
- package/dist/cli/commands/skills.d.ts +9 -0
- package/dist/cli/commands/skills.js +385 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/index.d.ts +19 -0
- package/dist/cli/index.js +40 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/registry.d.ts +43 -0
- package/dist/cli/registry.js +82 -0
- package/dist/cli/registry.js.map +1 -0
- package/dist/cli/templates.d.ts +19 -0
- package/dist/cli/templates.js +191 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/cli/utils/colors.d.ts +13 -0
- package/dist/cli/utils/colors.js +16 -0
- package/dist/cli/utils/colors.js.map +1 -0
- package/dist/config/__tests__/diff.test.d.ts +1 -0
- package/dist/config/__tests__/diff.test.js +192 -0
- package/dist/config/__tests__/diff.test.js.map +1 -0
- package/dist/config/__tests__/loader.test.d.ts +1 -0
- package/dist/config/__tests__/loader.test.js +356 -0
- package/dist/config/__tests__/loader.test.js.map +1 -0
- package/dist/config/__tests__/paths.test.d.ts +1 -0
- package/dist/config/__tests__/paths.test.js +192 -0
- package/dist/config/__tests__/paths.test.js.map +1 -0
- package/dist/config/__tests__/reload.test.d.ts +1 -0
- package/dist/config/__tests__/reload.test.js +374 -0
- package/dist/config/__tests__/reload.test.js.map +1 -0
- package/dist/config/__tests__/rules.test.d.ts +1 -0
- package/dist/config/__tests__/rules.test.js +204 -0
- package/dist/config/__tests__/rules.test.js.map +1 -0
- package/dist/config/__tests__/schema.test.d.ts +1 -0
- package/dist/config/__tests__/schema.test.js +672 -0
- package/dist/config/__tests__/schema.test.js.map +1 -0
- package/dist/config/diff.d.ts +7 -0
- package/dist/config/diff.js +46 -0
- package/dist/config/diff.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.js +7 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +5 -0
- package/dist/config/loader.js +81 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/paths.d.ts +35 -0
- package/dist/config/paths.js +79 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/reload.d.ts +78 -0
- package/dist/config/reload.js +190 -0
- package/dist/config/reload.js.map +1 -0
- package/dist/config/rules.d.ts +42 -0
- package/dist/config/rules.js +114 -0
- package/dist/config/rules.js.map +1 -0
- package/dist/config/schema.d.ts +1340 -0
- package/dist/config/schema.js +611 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/cron/executor.d.ts +54 -0
- package/dist/cron/executor.js +364 -0
- package/dist/cron/executor.js.map +1 -0
- package/dist/cron/index.d.ts +5 -0
- package/dist/cron/index.js +6 -0
- package/dist/cron/index.js.map +1 -0
- package/dist/cron/persistence.d.ts +61 -0
- package/dist/cron/persistence.js +188 -0
- package/dist/cron/persistence.js.map +1 -0
- package/dist/cron/service.d.ts +94 -0
- package/dist/cron/service.js +382 -0
- package/dist/cron/service.js.map +1 -0
- package/dist/cron/types.d.ts +119 -0
- package/dist/cron/types.js +3 -0
- package/dist/cron/types.js.map +1 -0
- package/dist/cron/validation.d.ts +144 -0
- package/dist/cron/validation.js +113 -0
- package/dist/cron/validation.js.map +1 -0
- package/dist/errors/__tests__/index.test.d.ts +1 -0
- package/dist/errors/__tests__/index.test.js +301 -0
- package/dist/errors/__tests__/index.test.js.map +1 -0
- package/dist/errors/index.d.ts +114 -0
- package/dist/errors/index.js +278 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/gateway/hono/app.d.ts +7 -0
- package/dist/gateway/hono/app.js +668 -0
- package/dist/gateway/hono/app.js.map +1 -0
- package/dist/gateway/hono/index.d.ts +2 -0
- package/dist/gateway/hono/index.js +3 -0
- package/dist/gateway/hono/index.js.map +1 -0
- package/dist/gateway/hono/middleware/auth.d.ts +18 -0
- package/dist/gateway/hono/middleware/auth.js +79 -0
- package/dist/gateway/hono/middleware/auth.js.map +1 -0
- package/dist/gateway/hono/middleware/logger.d.ts +1 -0
- package/dist/gateway/hono/middleware/logger.js +17 -0
- package/dist/gateway/hono/middleware/logger.js.map +1 -0
- package/dist/gateway/hono/sse.d.ts +55 -0
- package/dist/gateway/hono/sse.js +224 -0
- package/dist/gateway/hono/sse.js.map +1 -0
- package/dist/gateway/index.d.ts +4 -0
- package/dist/gateway/index.js +5 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/gateway/protocol.d.ts +28 -0
- package/dist/gateway/protocol.js +14 -0
- package/dist/gateway/protocol.js.map +1 -0
- package/dist/gateway/server.d.ts +19 -0
- package/dist/gateway/server.js +64 -0
- package/dist/gateway/server.js.map +1 -0
- package/dist/gateway/service.d.ts +265 -0
- package/dist/gateway/service.js +621 -0
- package/dist/gateway/service.js.map +1 -0
- package/dist/gateway/static/root/assets/main-CfIxL-cL.js +2105 -0
- package/dist/gateway/static/root/assets/main-CfIxL-cL.js.map +1 -0
- package/dist/gateway/static/root/assets/main-DndcTCgX.css +1 -0
- package/dist/gateway/static/root/index.html +116 -0
- package/dist/heartbeat/index.d.ts +1 -0
- package/dist/heartbeat/index.js +2 -0
- package/dist/heartbeat/index.js.map +1 -0
- package/dist/heartbeat/service.d.ts +19 -0
- package/dist/heartbeat/service.js +61 -0
- package/dist/heartbeat/service.js.map +1 -0
- package/dist/plugin-sdk/index.d.ts +21 -0
- package/dist/plugin-sdk/index.js +12 -0
- package/dist/plugin-sdk/index.js.map +1 -0
- package/dist/plugins/__tests__/api.test.d.ts +1 -0
- package/dist/plugins/__tests__/api.test.js +164 -0
- package/dist/plugins/__tests__/api.test.js.map +1 -0
- package/dist/plugins/__tests__/hooks.test.d.ts +1 -0
- package/dist/plugins/__tests__/hooks.test.js +159 -0
- package/dist/plugins/__tests__/hooks.test.js.map +1 -0
- package/dist/plugins/__tests__/loader.test.d.ts +1 -0
- package/dist/plugins/__tests__/loader.test.js +120 -0
- package/dist/plugins/__tests__/loader.test.js.map +1 -0
- package/dist/plugins/api.d.ts +41 -0
- package/dist/plugins/api.js +131 -0
- package/dist/plugins/api.js.map +1 -0
- package/dist/plugins/hooks.d.ts +153 -0
- package/dist/plugins/hooks.js +172 -0
- package/dist/plugins/hooks.js.map +1 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.js +16 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/install.d.ts +59 -0
- package/dist/plugins/install.js +324 -0
- package/dist/plugins/install.js.map +1 -0
- package/dist/plugins/loader.d.ts +84 -0
- package/dist/plugins/loader.js +545 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/types.d.ts +190 -0
- package/dist/plugins/types.js +7 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/providers/__tests__/registry.test.d.ts +1 -0
- package/dist/providers/__tests__/registry.test.js +110 -0
- package/dist/providers/__tests__/registry.test.js.map +1 -0
- package/dist/providers/api-strategies.d.ts +15 -0
- package/dist/providers/api-strategies.js +96 -0
- package/dist/providers/api-strategies.js.map +1 -0
- package/dist/providers/auto-discovery.d.ts +84 -0
- package/dist/providers/auto-discovery.js +236 -0
- package/dist/providers/auto-discovery.js.map +1 -0
- package/dist/providers/config.d.ts +25 -0
- package/dist/providers/config.js +42 -0
- package/dist/providers/config.js.map +1 -0
- package/dist/providers/index.d.ts +25 -0
- package/dist/providers/index.js +55 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/model-catalog.d.ts +205 -0
- package/dist/providers/model-catalog.js +1071 -0
- package/dist/providers/model-catalog.js.map +1 -0
- package/dist/providers/models-dev-data.d.ts +11 -0
- package/dist/providers/models-dev-data.js +1035 -0
- package/dist/providers/models-dev-data.js.map +1 -0
- package/dist/providers/models-dev.d.ts +30 -0
- package/dist/providers/models-dev.js +42 -0
- package/dist/providers/models-dev.js.map +1 -0
- package/dist/providers/pi-ai.d.ts +62 -0
- package/dist/providers/pi-ai.js +221 -0
- package/dist/providers/pi-ai.js.map +1 -0
- package/dist/providers/provider-catalog.d.ts +173 -0
- package/dist/providers/provider-catalog.js +834 -0
- package/dist/providers/provider-catalog.js.map +1 -0
- package/dist/providers/registry.d.ts +155 -0
- package/dist/providers/registry.js +524 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/types.d.ts +95 -0
- package/dist/providers/types.js +7 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/session/chat-manager.d.ts +49 -0
- package/dist/session/chat-manager.js +167 -0
- package/dist/session/chat-manager.js.map +1 -0
- package/dist/session/chat-types.d.ts +53 -0
- package/dist/session/chat-types.js +63 -0
- package/dist/session/chat-types.js.map +1 -0
- package/dist/session/index.d.ts +5 -0
- package/dist/session/index.js +5 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/manager.d.ts +103 -0
- package/dist/session/manager.js +200 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/store.d.ts +114 -0
- package/dist/session/store.js +687 -0
- package/dist/session/store.js.map +1 -0
- package/dist/session/types.d.ts +88 -0
- package/dist/session/types.js +10 -0
- package/dist/session/types.js.map +1 -0
- package/dist/types/index.d.ts +177 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/providers.d.ts +67 -0
- package/dist/types/providers.js +7 -0
- package/dist/types/providers.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +17 -0
- package/dist/utils/frontmatter.js +104 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/helpers.d.ts +5 -0
- package/dist/utils/helpers.js +36 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/log-store.d.ts +78 -0
- package/dist/utils/log-store.js +432 -0
- package/dist/utils/log-store.js.map +1 -0
- package/dist/utils/logger.d.ts +127 -0
- package/dist/utils/logger.js +481 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/logger.types.d.ts +152 -0
- package/dist/utils/logger.types.js +30 -0
- package/dist/utils/logger.types.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,2105 @@
|
|
|
1
|
+
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))i(n);new MutationObserver(n=>{for(const r of n)if(r.type==="childList")for(const l of r.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&i(l)}).observe(document,{childList:!0,subtree:!0});function s(n){const r={};return n.integrity&&(r.integrity=n.integrity),n.referrerPolicy&&(r.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?r.credentials="include":n.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(n){if(n.ep)return;n.ep=!0;const r=s(n);fetch(n.href,r)}})();const ye=globalThis,De=ye.ShadowRoot&&(ye.ShadyCSS===void 0||ye.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,it=Symbol(),He=new WeakMap;let mt=class{constructor(t,s,i){if(this._$cssResult$=!0,i!==it)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=s}get styleSheet(){let t=this.o;const s=this.t;if(De&&t===void 0){const i=s!==void 0&&s.length===1;i&&(t=He.get(s)),t===void 0&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),i&&He.set(s,t))}return t}toString(){return this.cssText}};const _t=e=>new mt(typeof e=="string"?e:e+"",void 0,it),vt=(e,t)=>{if(De)e.adoptedStyleSheets=t.map(s=>s instanceof CSSStyleSheet?s:s.styleSheet);else for(const s of t){const i=document.createElement("style"),n=ye.litNonce;n!==void 0&&i.setAttribute("nonce",n),i.textContent=s.cssText,e.appendChild(i)}},Ne=De?e=>e:e=>e instanceof CSSStyleSheet?(t=>{let s="";for(const i of t.cssRules)s+=i.cssText;return _t(s)})(e):e;const{is:ft,defineProperty:yt,getOwnPropertyDescriptor:wt,getOwnPropertyNames:bt,getOwnPropertySymbols:$t,getPrototypeOf:xt}=Object,ke=globalThis,ze=ke.trustedTypes,St=ze?ze.emptyScript:"",kt=ke.reactiveElementPolyfillSupport,he=(e,t)=>e,we={toAttribute(e,t){switch(t){case Boolean:e=e?St:null;break;case Object:case Array:e=e==null?e:JSON.stringify(e)}return e},fromAttribute(e,t){let s=e;switch(t){case Boolean:s=e!==null;break;case Number:s=e===null?null:Number(e);break;case Object:case Array:try{s=JSON.parse(e)}catch{s=null}}return s}},Oe=(e,t)=>!ft(e,t),qe={attribute:!0,type:String,converter:we,reflect:!1,useDefault:!1,hasChanged:Oe};Symbol.metadata??=Symbol("metadata"),ke.litPropertyMetadata??=new WeakMap;let ee=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=qe){if(s.state&&(s.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((s=Object.create(s)).wrapped=!0),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(t,i,s);n!==void 0&&yt(this.prototype,t,n)}}static getPropertyDescriptor(t,s,i){const{get:n,set:r}=wt(this.prototype,t)??{get(){return this[s]},set(l){this[s]=l}};return{get:n,set(l){const h=n?.call(this);r?.call(this,l),this.requestUpdate(t,h,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??qe}static _$Ei(){if(this.hasOwnProperty(he("elementProperties")))return;const t=xt(this);t.finalize(),t.l!==void 0&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(he("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(he("properties"))){const s=this.properties,i=[...bt(s),...$t(s)];for(const n of i)this.createProperty(n,s[n])}const t=this[Symbol.metadata];if(t!==null){const s=litPropertyMetadata.get(t);if(s!==void 0)for(const[i,n]of s)this.elementProperties.set(i,n)}this._$Eh=new Map;for(const[s,i]of this.elementProperties){const n=this._$Eu(s,i);n!==void 0&&this._$Eh.set(n,s)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const s=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const n of i)s.unshift(Ne(n))}else t!==void 0&&s.push(Ne(t));return s}static _$Eu(t,s){const i=s.attribute;return i===!1?void 0:typeof i=="string"?i:typeof t=="string"?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),this.renderRoot!==void 0&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return vt(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,s,i){this._$AK(t,i)}_$ET(t,s){const i=this.constructor.elementProperties.get(t),n=this.constructor._$Eu(t,i);if(n!==void 0&&i.reflect===!0){const r=(i.converter?.toAttribute!==void 0?i.converter:we).toAttribute(s,i.type);this._$Em=t,r==null?this.removeAttribute(n):this.setAttribute(n,r),this._$Em=null}}_$AK(t,s){const i=this.constructor,n=i._$Eh.get(t);if(n!==void 0&&this._$Em!==n){const r=i.getPropertyOptions(n),l=typeof r.converter=="function"?{fromAttribute:r.converter}:r.converter?.fromAttribute!==void 0?r.converter:we;this._$Em=n;const h=l.fromAttribute(s,r.type);this[n]=h??this._$Ej?.get(n)??h,this._$Em=null}}requestUpdate(t,s,i,n=!1,r){if(t!==void 0){const l=this.constructor;if(n===!1&&(r=this[t]),i??=l.getPropertyOptions(t),!((i.hasChanged??Oe)(r,s)||i.useDefault&&i.reflect&&r===this._$Ej?.get(t)&&!this.hasAttribute(l._$Eu(t,i))))return;this.C(t,s,i)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(t,s,{useDefault:i,reflect:n,wrapped:r},l){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,l??s??this[t]),r!==!0||l!==void 0)||(this._$AL.has(t)||(this.hasUpdated||i||(s=void 0),this._$AL.set(t,s)),n===!0&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(s){Promise.reject(s)}const t=this.scheduleUpdate();return t!=null&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[n,r]of this._$Ep)this[n]=r;this._$Ep=void 0}const i=this.constructor.elementProperties;if(i.size>0)for(const[n,r]of i){const{wrapped:l}=r,h=this[n];l!==!0||this._$AL.has(n)||h===void 0||this.C(n,void 0,r,h)}}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach(i=>i.hostUpdate?.()),this.update(s)):this._$EM()}catch(i){throw t=!1,this._$EM(),i}t&&this._$AE(s)}willUpdate(t){}_$AE(t){this._$EO?.forEach(s=>s.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(s=>this._$ET(s,this[s])),this._$EM()}updated(t){}firstUpdated(t){}};ee.elementStyles=[],ee.shadowRootOptions={mode:"open"},ee[he("elementProperties")]=new Map,ee[he("finalized")]=new Map,kt?.({ReactiveElement:ee}),(ke.reactiveElementVersions??=[]).push("2.1.2");const Re=globalThis,Je=e=>e,be=Re.trustedTypes,Ge=be?be.createPolicy("lit-html",{createHTML:e=>e}):void 0,nt="$lit$",B=`lit$${Math.random().toFixed(9).slice(2)}$`,ot="?"+B,At=`<${ot}>`,J=document,pe=()=>J.createComment(""),ue=e=>e===null||typeof e!="object"&&typeof e!="function",Be=Array.isArray,Ct=e=>Be(e)||typeof e?.[Symbol.iterator]=="function",Te=`[
|
|
2
|
+
\f\r]`,re=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,We=/-->/g,Ve=/>/g,N=RegExp(`>|${Te}(?:([^\\s"'>=/]+)(${Te}*=${Te}*(?:[^
|
|
3
|
+
\f\r"'\`<>=]|("|')|))|$)`,"g"),Qe=/'/g,Xe=/"/g,rt=/^(?:script|style|textarea|title)$/i,Mt=e=>(t,...s)=>({_$litType$:e,strings:t,values:s}),o=Mt(1),G=Symbol.for("lit-noChange"),m=Symbol.for("lit-nothing"),Ze=new WeakMap,z=J.createTreeWalker(J,129);function at(e,t){if(!Be(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return Ge!==void 0?Ge.createHTML(t):t}const Tt=(e,t)=>{const s=e.length-1,i=[];let n,r=t===2?"<svg>":t===3?"<math>":"",l=re;for(let h=0;h<s;h++){const d=e[h];let g,S,f=-1,E=0;for(;E<d.length&&(l.lastIndex=E,S=l.exec(d),S!==null);)E=l.lastIndex,l===re?S[1]==="!--"?l=We:S[1]!==void 0?l=Ve:S[2]!==void 0?(rt.test(S[2])&&(n=RegExp("</"+S[2],"g")),l=N):S[3]!==void 0&&(l=N):l===N?S[0]===">"?(l=n??re,f=-1):S[1]===void 0?f=-2:(f=l.lastIndex-S[2].length,g=S[1],l=S[3]===void 0?N:S[3]==='"'?Xe:Qe):l===Xe||l===Qe?l=N:l===We||l===Ve?l=re:(l=N,n=void 0);const L=l===N&&e[h+1].startsWith("/>")?" ":"";r+=l===re?d+At:f>=0?(i.push(g),d.slice(0,f)+nt+d.slice(f)+B+L):d+B+(f===-2?h:L)}return[at(e,r+(e[s]||"<?>")+(t===2?"</svg>":t===3?"</math>":"")),i]};class ge{constructor({strings:t,_$litType$:s},i){let n;this.parts=[];let r=0,l=0;const h=t.length-1,d=this.parts,[g,S]=Tt(t,s);if(this.el=ge.createElement(g,i),z.currentNode=this.el.content,s===2||s===3){const f=this.el.content.firstChild;f.replaceWith(...f.childNodes)}for(;(n=z.nextNode())!==null&&d.length<h;){if(n.nodeType===1){if(n.hasAttributes())for(const f of n.getAttributeNames())if(f.endsWith(nt)){const E=S[l++],L=n.getAttribute(f).split(B),ve=/([.?@])?(.*)/.exec(E);d.push({type:1,index:r,name:ve[2],strings:L,ctor:ve[1]==="."?Pt:ve[1]==="?"?Ft:ve[1]==="@"?Lt:Ae}),n.removeAttribute(f)}else f.startsWith(B)&&(d.push({type:6,index:r}),n.removeAttribute(f));if(rt.test(n.tagName)){const f=n.textContent.split(B),E=f.length-1;if(E>0){n.textContent=be?be.emptyScript:"";for(let L=0;L<E;L++)n.append(f[L],pe()),z.nextNode(),d.push({type:2,index:++r});n.append(f[E],pe())}}}else if(n.nodeType===8)if(n.data===ot)d.push({type:2,index:r});else{let f=-1;for(;(f=n.data.indexOf(B,f+1))!==-1;)d.push({type:7,index:r}),f+=B.length-1}r++}}static createElement(t,s){const i=J.createElement("template");return i.innerHTML=t,i}}function se(e,t,s=e,i){if(t===G)return t;let n=i!==void 0?s._$Co?.[i]:s._$Cl;const r=ue(t)?void 0:t._$litDirective$;return n?.constructor!==r&&(n?._$AO?.(!1),r===void 0?n=void 0:(n=new r(e),n._$AT(e,s,i)),i!==void 0?(s._$Co??=[])[i]=n:s._$Cl=n),n!==void 0&&(t=se(e,n._$AS(e,t.values),n,i)),t}class Et{constructor(t,s){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=s}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){const{el:{content:s},parts:i}=this._$AD,n=(t?.creationScope??J).importNode(s,!0);z.currentNode=n;let r=z.nextNode(),l=0,h=0,d=i[0];for(;d!==void 0;){if(l===d.index){let g;d.type===2?g=new _e(r,r.nextSibling,this,t):d.type===1?g=new d.ctor(r,d.name,d.strings,this,t):d.type===6&&(g=new It(r,this,t)),this._$AV.push(g),d=i[++h]}l!==d?.index&&(r=z.nextNode(),l++)}return z.currentNode=J,n}p(t){let s=0;for(const i of this._$AV)i!==void 0&&(i.strings!==void 0?(i._$AI(t,i,s),s+=i.strings.length-2):i._$AI(t[s])),s++}}class _e{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,s,i,n){this.type=2,this._$AH=m,this._$AN=void 0,this._$AA=t,this._$AB=s,this._$AM=i,this.options=n,this._$Cv=n?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode;const s=this._$AM;return s!==void 0&&t?.nodeType===11&&(t=s.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,s=this){t=se(this,t,s),ue(t)?t===m||t==null||t===""?(this._$AH!==m&&this._$AR(),this._$AH=m):t!==this._$AH&&t!==G&&this._(t):t._$litType$!==void 0?this.$(t):t.nodeType!==void 0?this.T(t):Ct(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==m&&ue(this._$AH)?this._$AA.nextSibling.data=t:this.T(J.createTextNode(t)),this._$AH=t}$(t){const{values:s,_$litType$:i}=t,n=typeof i=="number"?this._$AC(t):(i.el===void 0&&(i.el=ge.createElement(at(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(s);else{const r=new Et(n,this),l=r.u(this.options);r.p(s),this.T(l),this._$AH=r}}_$AC(t){let s=Ze.get(t.strings);return s===void 0&&Ze.set(t.strings,s=new ge(t)),s}k(t){Be(this._$AH)||(this._$AH=[],this._$AR());const s=this._$AH;let i,n=0;for(const r of t)n===s.length?s.push(i=new _e(this.O(pe()),this.O(pe()),this,this.options)):i=s[n],i._$AI(r),n++;n<s.length&&(this._$AR(i&&i._$AB.nextSibling,n),s.length=n)}_$AR(t=this._$AA.nextSibling,s){for(this._$AP?.(!1,!0,s);t!==this._$AB;){const i=Je(t).nextSibling;Je(t).remove(),t=i}}setConnected(t){this._$AM===void 0&&(this._$Cv=t,this._$AP?.(t))}}class Ae{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,s,i,n,r){this.type=1,this._$AH=m,this._$AN=void 0,this.element=t,this.name=s,this._$AM=n,this.options=r,i.length>2||i[0]!==""||i[1]!==""?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=m}_$AI(t,s=this,i,n){const r=this.strings;let l=!1;if(r===void 0)t=se(this,t,s,0),l=!ue(t)||t!==this._$AH&&t!==G,l&&(this._$AH=t);else{const h=t;let d,g;for(t=r[0],d=0;d<r.length-1;d++)g=se(this,h[i+d],s,d),g===G&&(g=this._$AH[d]),l||=!ue(g)||g!==this._$AH[d],g===m?t=m:t!==m&&(t+=(g??"")+r[d+1]),this._$AH[d]=g}l&&!n&&this.j(t)}j(t){t===m?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}}class Pt extends Ae{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===m?void 0:t}}class Ft extends Ae{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==m)}}class Lt extends Ae{constructor(t,s,i,n,r){super(t,s,i,n,r),this.type=5}_$AI(t,s=this){if((t=se(this,t,s,0)??m)===G)return;const i=this._$AH,n=t===m&&i!==m||t.capture!==i.capture||t.once!==i.once||t.passive!==i.passive,r=t!==m&&(i===m||n);n&&this.element.removeEventListener(this.name,this,i),r&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}}class It{constructor(t,s,i){this.element=t,this.type=6,this._$AN=void 0,this._$AM=s,this.options=i}get _$AU(){return this._$AM._$AU}_$AI(t){se(this,t)}}const Dt=Re.litHtmlPolyfillSupport;Dt?.(ge,_e),(Re.litHtmlVersions??=[]).push("3.3.2");const Ot=(e,t,s)=>{const i=s?.renderBefore??t;let n=i._$litPart$;if(n===void 0){const r=s?.renderBefore??null;i._$litPart$=n=new _e(t.insertBefore(pe(),r),r,void 0,s??{})}return n._$AI(e),n};const Ke=globalThis;let y=class extends ee{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const s=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=Ot(s,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return G}};y._$litElement$=!0,y.finalized=!0,Ke.litElementHydrateSupport?.({LitElement:y});const Rt=Ke.litElementPolyfillSupport;Rt?.({LitElement:y});(Ke.litElementVersions??=[]).push("4.2.2");const k=e=>(t,s)=>{s!==void 0?s.addInitializer(()=>{customElements.define(e,t)}):customElements.define(e,t)};const Bt={attribute:!0,type:String,converter:we,reflect:!1,hasChanged:Oe},Kt=(e=Bt,t,s)=>{const{kind:i,metadata:n}=s;let r=globalThis.litPropertyMetadata.get(n);if(r===void 0&&globalThis.litPropertyMetadata.set(n,r=new Map),i==="setter"&&((e=Object.create(e)).wrapped=!0),r.set(s.name,e),i==="accessor"){const{name:l}=s;return{set(h){const d=t.get.call(this);t.set.call(this,h),this.requestUpdate(l,d,e,!0,h)},init(h){return h!==void 0&&this.C(l,void 0,e,h),h}}}if(i==="setter"){const{name:l}=s;return function(h){const d=this[l];t.call(this,h),this.requestUpdate(l,d,e,!0,h)}}throw Error("Unsupported decorator location: "+i)};function u(e){return(t,s)=>typeof s=="object"?Kt(e,t,s):((i,n,r)=>{const l=n.hasOwnProperty(r);return n.constructor.createProperty(r,i),l?Object.getOwnPropertyDescriptor(n,r):void 0})(e,t,s)}function c(e){return u({...e,state:!0,attribute:!1})}const jt=(e,t,s)=>(s.configurable=!0,s.enumerable=!0,Reflect.decorate&&typeof t!="object"&&Object.defineProperty(e,t,s),s);function ie(e,t){return(s,i,n)=>{const r=l=>l.renderRoot?.querySelector(e)??null;return jt(s,i,{get(){return r(this)}})}}const Ut=e=>e.strings===void 0;const lt={CHILD:2},ct=e=>(...t)=>({_$litDirective$:e,values:t});class ht{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,s,i){this._$Ct=t,this._$AM=s,this._$Ci=i}_$AS(t,s){return this.update(t,s)}update(t,s){return this.render(...s)}}const de=(e,t)=>{const s=e._$AN;if(s===void 0)return!1;for(const i of s)i._$AO?.(t,!1),de(i,t);return!0},$e=e=>{let t,s;do{if((t=e._$AM)===void 0)break;s=t._$AN,s.delete(e),e=t}while(s?.size===0)},dt=e=>{for(let t;t=e._$AM;e=t){let s=t._$AN;if(s===void 0)t._$AN=s=new Set;else if(s.has(e))break;s.add(e),zt(t)}};function Ht(e){this._$AN!==void 0?($e(this),this._$AM=e,dt(this)):this._$AM=e}function Nt(e,t=!1,s=0){const i=this._$AH,n=this._$AN;if(n!==void 0&&n.size!==0)if(t)if(Array.isArray(i))for(let r=s;r<i.length;r++)de(i[r],!1),$e(i[r]);else i!=null&&(de(i,!1),$e(i));else de(this,e)}const zt=e=>{e.type==lt.CHILD&&(e._$AP??=Nt,e._$AQ??=Ht)};class qt extends ht{constructor(){super(...arguments),this._$AN=void 0}_$AT(t,s,i){super._$AT(t,s,i),dt(this),this.isConnected=t._$AU}_$AO(t,s=!0){t!==this.isConnected&&(this.isConnected=t,t?this.reconnected?.():this.disconnected?.()),s&&(de(this,t),$e(this))}setValue(t){if(Ut(this._$Ct))this._$Ct._$AI(t,this);else{const s=[...this._$Ct._$AH];s[this._$Ci]=t,this._$Ct._$AI(s,this,0)}}disconnected(){}reconnected(){}}const Ye=()=>new Jt;class Jt{}const Ee=new WeakMap,et=ct(class extends qt{render(e){return m}update(e,[t]){const s=t!==this.G;return s&&this.G!==void 0&&this.rt(void 0),(s||this.lt!==this.ct)&&(this.G=t,this.ht=e.options?.host,this.rt(this.ct=e.element)),m}rt(e){if(this.isConnected||(e=void 0),typeof this.G=="function"){const t=this.ht??globalThis;let s=Ee.get(t);s===void 0&&(s=new WeakMap,Ee.set(t,s)),s.get(this.G)!==void 0&&this.G.call(this.ht,void 0),s.set(this.G,e),e!==void 0&&this.G.call(this.ht,e)}else this.G.value=e}get lt(){return typeof this.G=="function"?Ee.get(this.ht??globalThis)?.get(this.G):this.G?.value}disconnected(){this.lt===this.ct&&this.rt(void 0)}reconnected(){this.rt(this.ct)}});class Pe extends ht{constructor(t){if(super(t),this.it=m,t.type!==lt.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(t){if(t===m||t==null)return this._t=void 0,this.it=t;if(t===G)return t;if(typeof t!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(t===this.it)return this._t;this.it=t;const s=[t];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}Pe.directiveName="unsafeHTML",Pe.resultType=1;const ae=ct(Pe);const Ce={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};const Gt=["svg",Ce,[["path",{d:"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48"}]]];const Wt=["svg",Ce,[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"}],["path",{d:"m21.854 2.147-10.94 10.939"}]]];const Vt=["svg",Ce,[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2"}]]];const Qt=["svg",Ce,[["path",{d:"M18 6 6 18"}],["path",{d:"m6 6 12 12"}]]],Xt={title:"XOPCBOT Gateway",brand:"XOPCBOT"},Zt={chat:"Chat",sessions:"Sessions",cron:"Cron Jobs",logs:"Logs",settings:"Settings",management:"Management"},Yt={title:"XopcBot",newSession:"New Chat",welcomeTitle:"Welcome to xopcbot",welcomeDescription:"Send a message to get started",emptyState:"No messages yet",emptyStateDescription:"Start a conversation by typing a message below",you:"You",assistant:"Assistant",tool:"Tool",thinking:"thinking...",typeMessage:"Type a message...",attachFile:"Attach file",sendMessage:"Send message",abort:"Abort",retry:"Retry",reasoning:"Reasoning",thinkingLevelNone:"None",thinkingLevel1:"Level 1",thinkingLevel2:"Level 2",thinkingLevel3:"Level 3",thinkingLevel4:"Level 4",connecting:"Connecting...",disconnected:"Disconnected",connectionError:"Connection error",reconnecting:"Reconnecting...",online:"Online",offline:"Offline"},es={title:"Settings",save:"Save",cancel:"Cancel",close:"Close",loading:"Loading settings...",unsaved:"{{count}} unsaved",saveChanges:"Save Changes",saving:"Saving...",noSection:"No section selected",enableFeature:"Enable this feature",required:"{{field}} is required",invalidFormat:"Invalid format",unsavedChanges:"Unsaved changes",sections:{agent:"Agent",providers:"Providers",channels:"Channels",gateway:"Gateway"},descriptions:{agent:"Configure your agent settings",providers:"Configure your provider API keys",channels:"Configure messaging channels",gateway:"Configure gateway settings"},fields:{model:"Model",workspace:"Workspace",maxTokens:"Max Tokens",temperature:"Temperature",maxToolIterations:"Max Tool Iterations",openaiApiKey:"OpenAI API Key",anthropicApiKey:"Anthropic API Key",googleApiKey:"Google API Key",qwenApiKey:"Qwen API Key",kimiApiKey:"Kimi API Key",minimaxApiKey:"MiniMax API Key",deepseekApiKey:"DeepSeek API Key",grokApiKey:"Grok API Key",openrouterApiKey:"OpenRouter API Key",telegramEnabled:"Telegram",telegramToken:"Telegram Token",telegramApiRoot:"API Root (Optional)",telegramAllowFrom:"Allow From (Optional)",telegramDebug:"Debug Mode",whatsappEnabled:"WhatsApp",whatsappBridgeUrl:"Bridge URL",whatsappAllowFrom:"Allow From (Optional)",heartbeatEnabled:"Heartbeat",heartbeatIntervalMs:"Heartbeat Interval (ms)"},descriptionsFields:{model:"Default AI model to use",workspace:"Working directory for agent files",maxTokens:"Maximum tokens in response",temperature:"Randomness in responses (0-2)",maxToolIterations:"Maximum tool calls per message",openaiApiKey:"API key for OpenAI models",anthropicApiKey:"API key for Claude models",googleApiKey:"API key for Gemini models",qwenApiKey:"API key for Qwen models",kimiApiKey:"API key for Kimi models",minimaxApiKey:"API key for MiniMax models",deepseekApiKey:"API key for DeepSeek models",grokApiKey:"API key for Grok models",openrouterApiKey:"API key for OpenRouter models",telegramEnabled:"Enable Telegram bot",telegramToken:"Bot API token from @BotFather",telegramApiRoot:"Custom Telegram API root URL",telegramAllowFrom:"Allowed user IDs, comma separated",telegramDebug:"Enable debug logging for Telegram",whatsappEnabled:"Enable WhatsApp bridge",whatsappBridgeUrl:"WhatsApp bridge WebSocket URL",whatsappAllowFrom:"Allowed phone numbers, comma separated",heartbeatEnabled:"Enable heartbeat monitoring",heartbeatIntervalMs:"Heartbeat check interval in milliseconds"},placeholders:{workspace:"~/.xopcbot/workspace",openaiApiKey:"sk-...",anthropicApiKey:"sk-ant-...",googleApiKey:"AIzaSy...",qwenApiKey:"sk-...",kimiApiKey:"sk-kimi-...",minimaxApiKey:"sk-cp-...",deepseekApiKey:"sk-...",openrouterApiKey:"sk-or-...",telegramToken:"1234567890:ABCdefGHIjklMNOpqrsTUVwxyz",telegramApiRoot:"https://api.telegram.org",telegramAllowFrom:"123456789, 987654321",whatsappBridgeUrl:"ws://localhost:3001",whatsappAllowFrom:"+1234567890, +0987654321"},connection:{title:"Connection",gatewayUrl:"Gateway URL",gatewayUrlDesc:"WebSocket URL for the gateway server",authToken:"Auth Token",authTokenDesc:"Optional authentication token"},appearance:{title:"Appearance",theme:"Theme",themeDesc:"Choose your preferred color scheme",themeSystem:"System",themeLight:"Light",themeDark:"Dark"},chat:{title:"Chat",enableAttachments:"Enable Attachments",enableAttachmentsDesc:"Allow file attachments in chat",showModelSelector:"Show Model Selector",showModelSelectorDesc:"Display model selection dropdown",showThinkingSelector:"Show Thinking Selector",showThinkingSelectorDesc:"Display thinking level selection"}},ts={noSession:"No session available",noAgent:"No agent set",noModel:"No model set",requestTimeout:"Request timeout",sendFailed:"Failed to send message",invalidFileType:"Invalid file type",fileTooLarge:"File too large (max {{size}})",readFileFailed:"Failed to read file"},ss={dropHere:"Drop files here",dragDrop:"Drag and drop files here",image:"Image",document:"Document",pdf:"PDF",word:"Word",excel:"Excel",powerpoint:"PowerPoint",text:"Text",code:"Code",archive:"Archive",unknown:"Unknown"},is={settings:"Open settings"},ns={title:"Configuration",save:"Save Configuration",noResult:"No result",artifacts:"Artifacts",showArtifacts:"Show artifacts"},os={title:"Logs",refresh:"Refresh",clear:"Clear",totalLogs:"Total Logs",pause:"Pause",autoRefresh:"Auto Refresh",level:"Level",search:"Search",searchPlaceholder:"Search logs...",time:"Time",message:"Message",module:"Module",noLogs:"No logs found",noLogsDescription:"Try adjusting your filters or check back later.",details:"Log Details"},rs={title:"Sessions",newSession:"New Session",searchPlaceholder:"Search sessions...",totalSessions:"Total Sessions",activeSessions:"Active Sessions",pinnedSessions:"Pinned Sessions",archivedSessions:"Archived Sessions",noSessions:"No sessions",delete:"Delete",archive:"Archive",pin:"Pin",unpin:"Unpin",confirmDelete:"Are you sure you want to delete this session?"},as={title:"Cron Jobs",addJob:"Add Cron Job",editJob:"Edit Job",name:"Name (optional)",namePlaceholder:"My scheduled task",schedule:"Schedule (cron expression) *",scheduleHint:"e.g., */5 * * * * (every 5 minutes), 0 9 * * * (daily at 9am)",message:"Message *",messagePlaceholder:"What should the assistant do?",create:"Create Job",runNow:"Run Now",delete:"Delete",edit:"Edit",enable:"Enable",disable:"Disable",enabled:"Enabled",disabled:"Disabled",running:"Running",lastRun:"Last Run",nextRun:"Next Run",status:"Status",history:"History",actions:"Actions",noJobs:"No cron jobs",confirmDelete:"Are you sure you want to delete this cron job?",confirmRun:"Run this cron job now?",success:"Success",failed:"Failed",scheduleLabel:"Schedule",messageLabel:"Message",confirm:"Confirm",cancel:"Cancel",total:"Total",schedulePresets:{custom:"-- Custom (enter below) --",everyMinute:"Every minute",every5Minutes:"Every 5 minutes (default)",every10Minutes:"Every 10 minutes",every15Minutes:"Every 15 minutes",every30Minutes:"Every 30 minutes",everyHour:"Every hour",every2Hours:"Every 2 hours",every4Hours:"Every 4 hours",every6Hours:"Every 6 hours",every12Hours:"Every 12 hours",everyDayMidnight:"Every day at midnight",everyDay9AM:"Every day at 9:00 AM",everyDay9PM:"Every day at 9:00 PM"},scheduleHintPreset:"Select a preset or enter custom cron expression",mode:"Mode",modeDirect:"Send message directly to the channel without AI processing",modeAgent:"Use AI agent to process the message, then send the response",modeDirectOption:"Direct (send message directly)",modeAgentOption:"AI Agent (process with AI then send)",model:"Model",noConfiguredModels:"No configured models",save:"Save",failedToLoadJobs:"Failed to load jobs",scheduleRequired:"Schedule and message are required",chatIdRequired:"Chat ID is required",failedToJob:"Failed to {{mode}} job",failedToToggleJob:"Failed to toggle job",actionFailed:"Action failed",enterManuallyOrSelect:"Enter manually or select from recent chats",noRecentChats:"No recent chats found. Enter chat ID manually (e.g., 123456789 for Telegram)",timeLabels:{lessThanMinute:"Less than a minute",minutes:"{{count}} min",hours:"{{count}} hours",overdue:"Overdue"},lastActiveLabels:{justNow:"just now",minutesAgo:"{{count}}m ago",hoursAgo:"{{count}}h ago",daysAgo:"{{count}}d ago"}},ls={save:"Save",cancel:"Cancel",confirm:"Confirm",close:"Close",loading:"Loading...",error:"Error",success:"Success",noData:"No data"},cs={app:Xt,nav:Zt,chat:Yt,settings:es,errors:ts,fileUpload:ss,shortcuts:is,config:ns,logs:os,sessions:rs,cron:as,common:ls},hs={title:"XOPCBOT 网关",brand:"XOPCBOT"},ds={chat:"对话",sessions:"会话",cron:"定时任务",logs:"日志",settings:"设置",management:"管理"},ps={title:"XopcBot",newSession:"新建对话",welcomeTitle:"欢迎使用 xopcbot",welcomeDescription:"发送消息开始对话",emptyState:"暂无消息",emptyStateDescription:"在下方输入消息开始对话",you:"你",assistant:"助手",tool:"工具",thinking:"思考中...",typeMessage:"输入消息...",attachFile:"附加文件",sendMessage:"发送消息",abort:"中止",retry:"重试",reasoning:"推理",thinkingLevelNone:"无",thinkingLevel1:"级别 1",thinkingLevel2:"级别 2",thinkingLevel3:"级别 3",thinkingLevel4:"级别 4",connecting:"连接中...",disconnected:"已断开",connectionError:"连接错误",reconnecting:"重新连接中...",online:"在线",offline:"离线"},us={title:"设置",save:"保存",cancel:"取消",close:"关闭",loading:"加载设置中...",unsaved:"{{count}} 个未保存",saveChanges:"保存更改",saving:"保存中...",noSection:"未选择部分",enableFeature:"启用此功能",required:"{{field}} 为必填项",invalidFormat:"格式无效",unsavedChanges:"未保存的更改",sections:{agent:"代理",providers:"提供商",channels:"渠道",gateway:"网关"},descriptions:{agent:"配置代理设置",providers:"配置提供商 API 密钥",channels:"配置消息渠道",gateway:"配置网关设置"},fields:{model:"模型",workspace:"工作区",maxTokens:"最大 Token 数",temperature:"温度",maxToolIterations:"最大工具调用次数",openaiApiKey:"OpenAI API 密钥",anthropicApiKey:"Anthropic API 密钥",googleApiKey:"Google API 密钥",qwenApiKey:"Qwen API 密钥",kimiApiKey:"Kimi API 密钥",minimaxApiKey:"MiniMax API 密钥",deepseekApiKey:"DeepSeek API 密钥",grokApiKey:"Grok API 密钥",openrouterApiKey:"OpenRouter API 密钥",telegramEnabled:"Telegram",telegramToken:"Telegram 令牌",telegramApiRoot:"API 根地址(可选)",telegramAllowFrom:"允许来源(可选)",telegramDebug:"调试模式",whatsappEnabled:"WhatsApp",whatsappBridgeUrl:"桥接地址",whatsappAllowFrom:"允许来源(可选)",heartbeatEnabled:"心跳",heartbeatIntervalMs:"心跳间隔(毫秒)"},descriptionsFields:{model:"默认使用的 AI 模型",workspace:"代理文件的工作目录",maxTokens:"响应中的最大 token 数",temperature:"响应随机性(0-2)",maxToolIterations:"每条消息的最大工具调用次数",openaiApiKey:"OpenAI 模型的 API 密钥",anthropicApiKey:"Claude 模型的 API 密钥",googleApiKey:"Gemini 模型的 API 密钥",qwenApiKey:"Qwen 模型的 API 密钥",kimiApiKey:"Kimi 模型的 API 密钥",minimaxApiKey:"MiniMax 模型的 API 密钥",deepseekApiKey:"DeepSeek 模型的 API 密钥",grokApiKey:"Grok 模型的 API 密钥",openrouterApiKey:"OpenRouter 模型的 API 密钥",telegramEnabled:"启用 Telegram 机器人",telegramToken:"@BotFather 获取的机器人 API 令牌",telegramApiRoot:"自定义 Telegram API 根地址",telegramAllowFrom:"允许的用户 ID,逗号分隔",telegramDebug:"启用 Telegram 调试日志",whatsappEnabled:"启用 WhatsApp 桥接",whatsappBridgeUrl:"WhatsApp 桥接 WebSocket 地址",whatsappAllowFrom:"允许的电话号码,逗号分隔",heartbeatEnabled:"启用心跳监控",heartbeatIntervalMs:"心跳检查间隔(毫秒)"},placeholders:{workspace:"~/.xopcbot/workspace",openaiApiKey:"sk-...",anthropicApiKey:"sk-ant-...",googleApiKey:"AIzaSy...",qwenApiKey:"sk-...",kimiApiKey:"sk-kimi-...",minimaxApiKey:"sk-cp-...",deepseekApiKey:"sk-...",openrouterApiKey:"sk-or-...",telegramToken:"1234567890:ABCdefGHIjklMNOpqrsTUVwxyz",telegramApiRoot:"https://api.telegram.org",telegramAllowFrom:"123456789, 987654321",whatsappBridgeUrl:"ws://localhost:3001",whatsappAllowFrom:"+1234567890, +0987654321"},connection:{title:"连接",gatewayUrl:"网关地址",gatewayUrlDesc:"网关服务器的 WebSocket 地址",authToken:"认证令牌",authTokenDesc:"可选的认证令牌"},appearance:{title:"外观",theme:"主题",themeDesc:"选择你喜欢的配色方案",themeSystem:"跟随系统",themeLight:"浅色",themeDark:"深色"},chat:{title:"对话",enableAttachments:"启用附件",enableAttachmentsDesc:"允许在对话中附加文件",showModelSelector:"显示模型选择器",showModelSelectorDesc:"显示模型选择下拉框",showThinkingSelector:"显示思考选择器",showThinkingSelectorDesc:"显示思考级别选择"}},gs={noSession:"无可用会话",noAgent:"未设置代理",noModel:"未设置模型",requestTimeout:"请求超时",sendFailed:"发送消息失败",invalidFileType:"无效的文件类型",fileTooLarge:"文件过大(最大 {{size}})",readFileFailed:"读取文件失败"},ms={dropHere:"拖放文件到此处",dragDrop:"拖放文件到此处",image:"图片",document:"文档",pdf:"PDF",word:"Word",excel:"Excel",powerpoint:"PowerPoint",text:"文本",code:"代码",archive:"压缩包",unknown:"未知"},_s={settings:"打开设置"},vs={title:"配置",save:"保存配置",noResult:"无结果",artifacts:"产物",showArtifacts:"显示产物"},fs={title:"日志",refresh:"刷新",clear:"清空",totalLogs:"总日志数",pause:"暂停",autoRefresh:"自动刷新",level:"级别",search:"搜索",searchPlaceholder:"搜索日志...",time:"时间",message:"消息",module:"模块",noLogs:"暂无日志",noLogsDescription:"尝试调整筛选条件或稍后再查看。",details:"日志详情"},ys={title:"会话",newSession:"新建会话",searchPlaceholder:"搜索会话...",totalSessions:"总会话数",activeSessions:"活跃会话",pinnedSessions:"固定会话",archivedSessions:"归档会话",noSessions:"暂无会话",delete:"删除",archive:"归档",pin:"固定",unpin:"取消固定",confirmDelete:"确定要删除此会话吗?"},ws={title:"定时任务",addJob:"添加定时任务",editJob:"编辑任务",name:"名称(可选)",namePlaceholder:"我的定时任务",schedule:"计划表达式 *",scheduleHint:"例如:*/5 * * * *(每5分钟),0 9 * * *(每天9点)",message:"消息 *",messagePlaceholder:"助手应该做什么?",create:"创建任务",runNow:"立即执行",delete:"删除",edit:"编辑",enable:"启用",disable:"禁用",enabled:"已启用",disabled:"已禁用",running:"运行中",lastRun:"上次执行",nextRun:"下次执行",status:"状态",history:"历史记录",actions:"操作",noJobs:"暂无定时任务",confirmDelete:"确定要删除此定时任务吗?",confirmRun:"立即执行此定时任务?",success:"成功",failed:"失败",scheduleLabel:"计划",messageLabel:"消息",confirm:"确认",cancel:"取消",total:"总计",schedulePresets:{custom:"-- 自定义(在下方输入) --",everyMinute:"每分钟",every5Minutes:"每 5 分钟(默认)",every10Minutes:"每 10 分钟",every15Minutes:"每 15 分钟",every30Minutes:"每 30 分钟",everyHour:"每小时",every2Hours:"每 2 小时",every4Hours:"每 4 小时",every6Hours:"每 6 小时",every12Hours:"每 12 小时",everyDayMidnight:"每天午夜",everyDay9AM:"每天早上 9 点",everyDay9PM:"每天晚上 9 点"},scheduleHintPreset:"选择预设或输入自定义 cron 表达式",mode:"模式",modeDirect:"直接发送消息到渠道,不经过 AI 处理",modeAgent:"使用 AI 代理处理消息,然后发送回复",modeDirectOption:"直接发送(直接发送到渠道)",modeAgentOption:"AI 代理(经过 AI 处理后发送)",model:"模型",noConfiguredModels:"未配置模型",save:"保存",failedToLoadJobs:"加载任务失败",scheduleRequired:"计划表达式和消息为必填项",chatIdRequired:"Chat ID 为必填项",failedToJob:"{{mode}} 任务失败",failedToToggleJob:"切换任务状态失败",actionFailed:"操作失败",enterManuallyOrSelect:"手动输入或从最近聊天中选择",noRecentChats:"未找到最近聊天。请手动输入 chat ID(例如:Telegram 为 123456789)",timeLabels:{lessThanMinute:"不到 1 分钟",minutes:"{{count}} 分钟",hours:"{{count}} 小时",overdue:"已过期"},lastActiveLabels:{justNow:"刚刚",minutesAgo:"{{count}} 分钟前",hoursAgo:"{{count}} 小时前",daysAgo:"{{count}} 天前"}},bs={save:"保存",cancel:"取消",confirm:"确认",close:"关闭",loading:"加载中...",error:"错误",success:"成功",noData:"暂无数据"},$s={app:hs,nav:ds,chat:ps,settings:us,errors:gs,fileUpload:ms,shortcuts:_s,config:vs,logs:fs,sessions:ys,cron:ws,common:bs},pt={en:cs,zh:$s},K=new Map;K.set("en",pt.en);K.set("zh",pt.zh);let q="en";function a(e,t){const s=K.get(q);if(!s)return e;const i=e.split(".");let n=s;for(const r of i)if(n&&typeof n=="object"&&r in n)n=n[r];else{const l=K.get("en");if(l&&q!=="en"){let h=l;for(const d of i)if(h&&typeof h=="object"&&d in h)h=h[d];else return e;n=h}else return e}return typeof n!="string"?e:t?n.replace(/\{\{(\w+)\}\}/g,(r,l)=>{const h=t[l];return h!==void 0?String(h):`{{${l}}}`}):n}async function xs(e){if(K.has(e)){q=e;return}try{const t=await fetch(`/src/i18n/${e}.json`);if(!t.ok)throw new Error(`Failed to load ${e} translations`);const s=await t.json();K.set(e,s),q=e,window.dispatchEvent(new CustomEvent("languagechange",{detail:{language:e}}))}catch(t){console.error(`Failed to load ${e} translations:`,t),e!=="en"&&K.has("en")&&(q="en")}}function tt(e){K.has(e)?(q=e,window.dispatchEvent(new CustomEvent("languagechange",{detail:{language:e}}))):xs(e)}function Ss(e="en"){q=e}const ks={"Type a message...":"chat.typeMessage","Attach file":"chat.attachFile","Send message":"chat.sendMessage",Abort:"chat.abort","No session available":"errors.noSession","No agent set":"errors.noAgent",Configuration:"config.title",Cancel:"settings.cancel",Save:"settings.save","No result":"config.noResult",Artifacts:"config.artifacts","Show artifacts":"config.showArtifacts"};function te(e){const t=ks[e];return a(t||e)}var As=Object.defineProperty,Cs=Object.getOwnPropertyDescriptor,T=(e,t,s,i)=>{for(var n=i>1?void 0:i?Cs(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&As(t,s,n),n};function le(e,t=""){if(!e||!Array.isArray(e))return"";const[s,i,n]=e,r=Object.entries(i||{}).map(([d,g])=>`${d}="${g}"`).join(" "),l=Array.isArray(n)?n.map(d=>{if(Array.isArray(d)){const[g,S]=d,f=Object.entries(S||{}).map(([E,L])=>`${E}="${L}"`).join(" ");return`<${g} ${f} />`}return""}).join(""):"";return`<svg ${t?`${r} class="${t}"`:r}>${l}</svg>`}let M=class extends y{constructor(){super(...arguments),this.value="",this.attachments=[],this.isStreaming=!1,this.showAttachmentButton=!0,this.showModelSelector=!0,this._isComposing=!1,this._isDragging=!1,this._processingFiles=!1,this._isSending=!1,this.textareaRef=Ye(),this.fileInputRef=Ye(),this.maxFileSize=20*1024*1024,this.acceptedTypes="image/*,application/pdf,.docx,.pptx,.xlsx,.xls,.txt,.md,.json,.xml,.html,.css,.js,.ts,.jsx,.tsx,.yml,.yaml,.zip",this._handleDocumentDragOver=e=>{e.dataTransfer?.types.includes("Files")&&(e.preventDefault(),this._isDragging=!0)},this._handleDocumentDragLeave=e=>{e.relatedTarget===null&&(this._isDragging=!1)},this._handleDocumentDrop=async e=>{e.preventDefault(),this._isDragging=!1;const t=e.dataTransfer?.files;t&&t.length>0&&await this._processFiles(Array.from(t))},this._handleInput=e=>{const t=e.target;this.value=t.value,this._adjustTextareaHeight()},this._handleKeydown=e=>{e.key==="Enter"&&!e.shiftKey&&!this._isComposing&&(e.preventDefault(),this._send())},this._handlePaste=async e=>{const t=e.clipboardData?.items;if(!t)return;const s=[];for(const i of Array.from(t))if(i.type.startsWith("image/")){const n=i.getAsFile();n&&s.push(n)}s.length>0&&(e.preventDefault(),await this._processFiles(s))},this._handleFileInputChange=async e=>{const t=e.target,s=t.files;s&&(await this._processFiles(Array.from(s)),t.value="")}}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),document.addEventListener("dragover",this._handleDocumentDragOver),document.addEventListener("drop",this._handleDocumentDrop),document.addEventListener("dragleave",this._handleDocumentDragLeave),document.addEventListener("click",this._handleOutsideClick)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("dragover",this._handleDocumentDragOver),document.removeEventListener("drop",this._handleDocumentDrop),document.removeEventListener("dragleave",this._handleDocumentDragLeave),document.removeEventListener("click",this._handleOutsideClick)}render(){return o`
|
|
4
|
+
<div class="editor-container">
|
|
5
|
+
${this.attachments.length>0?this._renderAttachments():""}
|
|
6
|
+
|
|
7
|
+
<div class="input-row ${this._isDragging?"dragging":""}">
|
|
8
|
+
${this.showAttachmentButton?this._renderAttachmentButton():""}
|
|
9
|
+
|
|
10
|
+
<textarea
|
|
11
|
+
${et(this.textareaRef)}
|
|
12
|
+
class="text-input"
|
|
13
|
+
placeholder=${te("Type a message...")}
|
|
14
|
+
.value=${this.value}
|
|
15
|
+
@input=${this._handleInput}
|
|
16
|
+
@keydown=${this._handleKeydown}
|
|
17
|
+
@compositionstart=${()=>this._isComposing=!0}
|
|
18
|
+
@compositionend=${()=>this._isComposing=!1}
|
|
19
|
+
@paste=${this._handlePaste}
|
|
20
|
+
rows="1"
|
|
21
|
+
></textarea>
|
|
22
|
+
|
|
23
|
+
<div class="input-actions">
|
|
24
|
+
${this._renderSendButton()}
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
${this._isDragging?this._renderDropOverlay():""}
|
|
29
|
+
</div>
|
|
30
|
+
`}_renderAttachments(){return o`
|
|
31
|
+
<div class="attachments-row">
|
|
32
|
+
${this.attachments.map((e,t)=>o`
|
|
33
|
+
<div class="attachment-chip">
|
|
34
|
+
<div class="attachment-preview">
|
|
35
|
+
${e.mimeType.startsWith("image/")?o`
|
|
36
|
+
<img src="${e.content}" alt="${e.name}" />
|
|
37
|
+
`:o`
|
|
38
|
+
${ae(le(FileText,"w-4 h-4"))}
|
|
39
|
+
`}
|
|
40
|
+
</div>
|
|
41
|
+
<span class="attachment-name">${e.name}</span>
|
|
42
|
+
<button type="button" class="attachment-remove" @click=${()=>this._removeAttachment(t)}>
|
|
43
|
+
${ae(le(Qt,"w-3 h-3"))}
|
|
44
|
+
</button>
|
|
45
|
+
</div>
|
|
46
|
+
`)}
|
|
47
|
+
</div>
|
|
48
|
+
`}_renderAttachmentButton(){return o`
|
|
49
|
+
<button type="button" class="attach-btn" @click=${()=>this._triggerFileSelect("all")} title=${te("Attach file")}>
|
|
50
|
+
${ae(le(Gt,"w-4 h-4"))}
|
|
51
|
+
</button>
|
|
52
|
+
|
|
53
|
+
<input
|
|
54
|
+
${et(this.fileInputRef)}
|
|
55
|
+
type="file"
|
|
56
|
+
multiple
|
|
57
|
+
accept=${this.acceptedTypes}
|
|
58
|
+
class="hidden"
|
|
59
|
+
@change=${this._handleFileInputChange}
|
|
60
|
+
/>
|
|
61
|
+
`}_renderSendButton(){const e=this.value.trim()||this.attachments.length>0;return this.isStreaming?o`
|
|
62
|
+
<button type="button" class="stop-btn" @click=${()=>this.onAbort?.()} title=${te("Abort")}>
|
|
63
|
+
${ae(le(Vt,"w-4 h-4"))}
|
|
64
|
+
</button>
|
|
65
|
+
`:o`
|
|
66
|
+
<button
|
|
67
|
+
type="button"
|
|
68
|
+
class="send-btn ${e?"active":""}"
|
|
69
|
+
?disabled=${!e}
|
|
70
|
+
@click=${this._send}
|
|
71
|
+
title=${te("Send message")}
|
|
72
|
+
>
|
|
73
|
+
${ae(le(Wt,"w-4 h-4"))}
|
|
74
|
+
</button>
|
|
75
|
+
`}_renderDropOverlay(){return o`
|
|
76
|
+
<div class="drop-overlay">
|
|
77
|
+
<span>Drop files here to attach</span>
|
|
78
|
+
</div>
|
|
79
|
+
`}_triggerFileSelect(e){let t=this.fileInputRef.value;if(t||(t=this.querySelector('input[type="file"]')),!t){console.warn("File input not found");return}e==="image"?t.accept="image/*":e==="document"?t.accept=".pdf,.docx,.pptx,.xlsx,.xls,.txt,.md,.json,.xml,.html,.css,.js,.ts,.jsx,.tsx,.yml,.yaml,.zip":t.accept=this.acceptedTypes,t.click()}_adjustTextareaHeight(){const e=this.textareaRef.value;e&&(e.style.height="auto",e.style.height=Math.min(e.scrollHeight,200)+"px")}_send(){if(this._isSending||this.isStreaming||!this.value.trim()&&this.attachments.length===0)return;this._isSending=!0;const e=[...this.attachments];this.onSend?.(this.value,e),this.value="",this.attachments=[],requestAnimationFrame(()=>{this._adjustTextareaHeight(),setTimeout(()=>{this._isSending=!1},500)})}async _processFiles(e){this._processingFiles=!0;try{for(const t of e){if(t.size>this.maxFileSize){console.warn(`File ${t.name} exceeds max size of ${this.maxFileSize} bytes`);continue}const s=await this._loadAttachment(t);this.attachments=[...this.attachments,s]}}finally{this._processingFiles=!1}}async _loadAttachment(e){const t=await this._readFileAsBase64(e),s=e.type.startsWith("image/");return{id:crypto.randomUUID(),name:e.name,type:s?"image":"document",mimeType:e.type,size:e.size,content:t}}_readFileAsBase64(e){return new Promise((t,s)=>{const i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>s(i.error),i.readAsDataURL(e)})}_removeAttachment(e){this.attachments=this.attachments.filter((t,s)=>s!==e)}_formatFileSize(e){const t=["B","KB","MB","GB"];let s=0,i=e;for(;i>=1024&&s<t.length-1;)i/=1024,s++;return`${i.toFixed(1)} ${t[s]}`}};T([ie("textarea")],M.prototype,"textarea",2);T([u({type:String})],M.prototype,"value",2);T([u({type:Array})],M.prototype,"attachments",2);T([u({type:Boolean})],M.prototype,"isStreaming",2);T([u({type:Boolean})],M.prototype,"showAttachmentButton",2);T([u({type:Boolean})],M.prototype,"showModelSelector",2);T([u({attribute:!1})],M.prototype,"currentModel",2);T([u({attribute:!1})],M.prototype,"onSend",2);T([u({attribute:!1})],M.prototype,"onAbort",2);T([u({attribute:!1})],M.prototype,"onModelSelect",2);T([c()],M.prototype,"_isComposing",2);T([c()],M.prototype,"_isDragging",2);T([c()],M.prototype,"_processingFiles",2);T([c()],M.prototype,"_isSending",2);M=T([k("message-editor")],M);function p(e){return Fe[e]||Fe.helpCircle}const Fe={messageSquare:o`
|
|
80
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
81
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
|
82
|
+
</svg>
|
|
83
|
+
`,settings:o`
|
|
84
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
85
|
+
<circle cx="12" cy="12" r="3"></circle>
|
|
86
|
+
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
|
|
87
|
+
</svg>
|
|
88
|
+
`,menu:o`
|
|
89
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
90
|
+
<line x1="3" y1="12" x2="21" y2="12"></line>
|
|
91
|
+
<line x1="3" y1="6" x2="21" y2="6"></line>
|
|
92
|
+
<line x1="3" y1="18" x2="21" y2="18"></line>
|
|
93
|
+
</svg>
|
|
94
|
+
`,chevronDown:o`
|
|
95
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
96
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
97
|
+
</svg>
|
|
98
|
+
`,sun:o`
|
|
99
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
100
|
+
<circle cx="12" cy="12" r="5"></circle>
|
|
101
|
+
<line x1="12" y1="1" x2="12" y2="3"></line>
|
|
102
|
+
<line x1="12" y1="21" x2="12" y2="23"></line>
|
|
103
|
+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
|
104
|
+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
|
105
|
+
<line x1="1" y1="12" x2="3" y2="12"></line>
|
|
106
|
+
<line x1="21" y1="12" x2="23" y2="12"></line>
|
|
107
|
+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
|
108
|
+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
|
109
|
+
</svg>
|
|
110
|
+
`,moon:o`
|
|
111
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
112
|
+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
|
113
|
+
</svg>
|
|
114
|
+
`,monitor:o`
|
|
115
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
116
|
+
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
|
|
117
|
+
<line x1="8" y1="21" x2="16" y2="21"></line>
|
|
118
|
+
<line x1="12" y1="17" x2="12" y2="21"></line>
|
|
119
|
+
</svg>
|
|
120
|
+
`,send:o`
|
|
121
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
122
|
+
<line x1="22" y1="2" x2="11" y2="13"></line>
|
|
123
|
+
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
|
|
124
|
+
</svg>
|
|
125
|
+
`,paperclip:o`
|
|
126
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
127
|
+
<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"></path>
|
|
128
|
+
</svg>
|
|
129
|
+
`,x:o`
|
|
130
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
131
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
132
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
133
|
+
</svg>
|
|
134
|
+
`,fileText:o`
|
|
135
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
136
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
|
|
137
|
+
<polyline points="14 2 14 8 20 8"></polyline>
|
|
138
|
+
<line x1="16" y1="13" x2="8" y2="13"></line>
|
|
139
|
+
<line x1="16" y1="17" x2="8" y2="17"></line>
|
|
140
|
+
<polyline points="10 9 9 9 8 9"></polyline>
|
|
141
|
+
</svg>
|
|
142
|
+
`,image:o`
|
|
143
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
144
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
145
|
+
<circle cx="8.5" cy="8.5" r="1.5"></circle>
|
|
146
|
+
<polyline points="21 15 16 10 5 21"></polyline>
|
|
147
|
+
</svg>
|
|
148
|
+
`,file:o`
|
|
149
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
150
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
|
|
151
|
+
<polyline points="14 2 14 8 20 8"></polyline>
|
|
152
|
+
</svg>
|
|
153
|
+
`,plug:o`
|
|
154
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
155
|
+
<path d="M12 22v-5"></path>
|
|
156
|
+
<path d="M15 8V2"></path>
|
|
157
|
+
<path d="M9 8V2"></path>
|
|
158
|
+
<path d="M15 8a3 3 0 0 1 3 3v5a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3v-5a3 3 0 0 1 3-3h6z"></path>
|
|
159
|
+
</svg>
|
|
160
|
+
`,palette:o`
|
|
161
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
162
|
+
<circle cx="13.5" cy="6.5" r=".5"></circle>
|
|
163
|
+
<circle cx="17.5" cy="10.5" r=".5"></circle>
|
|
164
|
+
<circle cx="8.5" cy="7.5" r=".5"></circle>
|
|
165
|
+
<circle cx="6.5" cy="12.5" r=".5"></circle>
|
|
166
|
+
<path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.01 17.461 2 12 2z"></path>
|
|
167
|
+
</svg>
|
|
168
|
+
`,alertCircle:o`
|
|
169
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
170
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
171
|
+
<line x1="12" y1="8" x2="12" y2="12"></line>
|
|
172
|
+
<line x1="12" y1="16" x2="12.01" y2="16"></line>
|
|
173
|
+
</svg>
|
|
174
|
+
`,check:o`
|
|
175
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
176
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
177
|
+
</svg>
|
|
178
|
+
`,chevronRight:o`
|
|
179
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
180
|
+
<polyline points="9 18 15 12 9 6"></polyline>
|
|
181
|
+
</svg>
|
|
182
|
+
`,arrowLeft:o`
|
|
183
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
184
|
+
<line x1="19" y1="12" x2="5" y2="12"></line>
|
|
185
|
+
<polyline points="12 19 5 12 12 5"></polyline>
|
|
186
|
+
</svg>
|
|
187
|
+
`,bot:o`
|
|
188
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
189
|
+
<rect x="3" y="11" width="18" height="10" rx="2"></rect>
|
|
190
|
+
<circle cx="12" cy="5" r="2"></circle>
|
|
191
|
+
<path d="M12 7v4"></path>
|
|
192
|
+
<line x1="8" y1="16" x2="8" y2="16.01"></line>
|
|
193
|
+
<line x1="16" y1="16" x2="16" y2="16.01"></line>
|
|
194
|
+
</svg>
|
|
195
|
+
`,helpCircle:o`
|
|
196
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
197
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
198
|
+
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
|
|
199
|
+
<line x1="12" y1="17" x2="12.01" y2="17"></line>
|
|
200
|
+
</svg>
|
|
201
|
+
`,rotateCcw:o`
|
|
202
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
203
|
+
<polyline points="1 4 1 10 7 10"></polyline>
|
|
204
|
+
<path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path>
|
|
205
|
+
</svg>
|
|
206
|
+
`,square:o`
|
|
207
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
208
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
209
|
+
</svg>
|
|
210
|
+
`,moreHorizontal:o`
|
|
211
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
212
|
+
<circle cx="12" cy="12" r="1"></circle>
|
|
213
|
+
<circle cx="19" cy="12" r="1"></circle>
|
|
214
|
+
<circle cx="5" cy="12" r="1"></circle>
|
|
215
|
+
</svg>
|
|
216
|
+
`,copy:o`
|
|
217
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
218
|
+
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
|
219
|
+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
|
|
220
|
+
</svg>
|
|
221
|
+
`,download:o`
|
|
222
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
223
|
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
|
224
|
+
<polyline points="7 10 12 15 17 10"></polyline>
|
|
225
|
+
<line x1="12" y1="15" x2="12" y2="3"></line>
|
|
226
|
+
</svg>
|
|
227
|
+
`,folderOpen:o`
|
|
228
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
229
|
+
<path d="M6 17h12a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3.5"></path>
|
|
230
|
+
<path d="M2 17V5a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v1"></path>
|
|
231
|
+
</svg>
|
|
232
|
+
`,phone:o`
|
|
233
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
234
|
+
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
|
|
235
|
+
</svg>
|
|
236
|
+
`,globe:o`
|
|
237
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
238
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
239
|
+
<line x1="2" y1="12" x2="22" y2="12"></line>
|
|
240
|
+
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
|
|
241
|
+
</svg>
|
|
242
|
+
`,terminal:o`
|
|
243
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
244
|
+
<polyline points="4 17 10 11 4 5"></polyline>
|
|
245
|
+
<line x1="12" y1="19" x2="20" y2="19"></line>
|
|
246
|
+
</svg>
|
|
247
|
+
`,zap:o`
|
|
248
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
249
|
+
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon>
|
|
250
|
+
</svg>
|
|
251
|
+
`,pin:o`
|
|
252
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
253
|
+
<line x1="12" y1="17" x2="12" y2="22"></line>
|
|
254
|
+
<path d="M5 17h14v-3a2 2 0 0 0-2-2h-3.5"></path>
|
|
255
|
+
<path d="M5 12V7a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v5"></path>
|
|
256
|
+
<circle cx="12" cy="7" r="1"></circle>
|
|
257
|
+
</svg>
|
|
258
|
+
`,pinOff:o`
|
|
259
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
260
|
+
<line x1="2" y1="2" x2="22" y2="22"></line>
|
|
261
|
+
<line x1="12" y1="17" x2="12" y2="22"></line>
|
|
262
|
+
<path d="M5 17h14v-3a2 2 0 0 0-2-2h-3.5"></path>
|
|
263
|
+
<path d="M5 12V7a2 2 0 0 1 2-2h1"></path>
|
|
264
|
+
</svg>
|
|
265
|
+
`,archive:o`
|
|
266
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
267
|
+
<polyline points="21 8 21 21 3 21 3 8"></polyline>
|
|
268
|
+
<rect x="1" y="3" width="22" height="5"></rect>
|
|
269
|
+
<line x1="10" y1="12" x2="14" y2="12"></line>
|
|
270
|
+
</svg>
|
|
271
|
+
`,archiveRestore:o`
|
|
272
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
273
|
+
<polyline points="21 8 21 21 3 21 3 8"></polyline>
|
|
274
|
+
<rect x="1" y="3" width="22" height="5"></rect>
|
|
275
|
+
<polyline points="10 12 14 12 14 8"></polyline>
|
|
276
|
+
</svg>
|
|
277
|
+
`,trash:o`
|
|
278
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
279
|
+
<polyline points="3 6 5 6 21 6"></polyline>
|
|
280
|
+
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
|
|
281
|
+
</svg>
|
|
282
|
+
`,grid:o`
|
|
283
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
284
|
+
<rect x="3" y="3" width="7" height="7"></rect>
|
|
285
|
+
<rect x="14" y="3" width="7" height="7"></rect>
|
|
286
|
+
<rect x="14" y="14" width="7" height="7"></rect>
|
|
287
|
+
<rect x="3" y="14" width="7" height="7"></rect>
|
|
288
|
+
</svg>
|
|
289
|
+
`,list:o`
|
|
290
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
291
|
+
<line x1="8" y1="6" x2="21" y2="6"></line>
|
|
292
|
+
<line x1="8" y1="12" x2="21" y2="12"></line>
|
|
293
|
+
<line x1="8" y1="18" x2="21" y2="18"></line>
|
|
294
|
+
<line x1="3" y1="6" x2="3.01" y2="6"></line>
|
|
295
|
+
<line x1="3" y1="12" x2="3.01" y2="12"></line>
|
|
296
|
+
<line x1="3" y1="18" x2="3.01" y2="18"></line>
|
|
297
|
+
</svg>
|
|
298
|
+
`,layers:o`
|
|
299
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
300
|
+
<polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
|
|
301
|
+
<polyline points="2 17 12 22 22 17"></polyline>
|
|
302
|
+
<polyline points="2 12 12 17 22 12"></polyline>
|
|
303
|
+
</svg>
|
|
304
|
+
`,circle:o`
|
|
305
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
306
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
307
|
+
</svg>
|
|
308
|
+
`,search:o`
|
|
309
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
310
|
+
<circle cx="11" cy="11" r="8"></circle>
|
|
311
|
+
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
312
|
+
</svg>
|
|
313
|
+
`,chevronUp:o`
|
|
314
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
315
|
+
<polyline points="18 15 12 9 6 15"></polyline>
|
|
316
|
+
</svg>
|
|
317
|
+
`,alertTriangle:o`
|
|
318
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
319
|
+
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>
|
|
320
|
+
<line x1="12" y1="9" x2="12" y2="13"></line>
|
|
321
|
+
<line x1="12" y1="17" x2="12.01" y2="17"></line>
|
|
322
|
+
</svg>
|
|
323
|
+
`,info:o`
|
|
324
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
325
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
326
|
+
<line x1="12" y1="16" x2="12" y2="12"></line>
|
|
327
|
+
<line x1="12" y1="8" x2="12.01" y2="8"></line>
|
|
328
|
+
</svg>
|
|
329
|
+
`,folder:o`
|
|
330
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
331
|
+
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
|
|
332
|
+
</svg>
|
|
333
|
+
`,clock:o`
|
|
334
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
335
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
336
|
+
<polyline points="12 6 12 12 16 14"></polyline>
|
|
337
|
+
</svg>
|
|
338
|
+
`,plus:o`
|
|
339
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
340
|
+
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
341
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
342
|
+
</svg>
|
|
343
|
+
`,refresh:o`
|
|
344
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
345
|
+
<polyline points="23 4 23 10 17 10"></polyline>
|
|
346
|
+
<polyline points="1 20 1 14 7 14"></polyline>
|
|
347
|
+
<path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>
|
|
348
|
+
</svg>
|
|
349
|
+
`,play:o`
|
|
350
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
351
|
+
<polygon points="5 3 19 12 5 21 5 3"></polygon>
|
|
352
|
+
</svg>
|
|
353
|
+
`,edit:o`
|
|
354
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
355
|
+
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
|
|
356
|
+
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
|
|
357
|
+
</svg>
|
|
358
|
+
`,pause:o`
|
|
359
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
360
|
+
<rect x="6" y="4" width="4" height="16"></rect>
|
|
361
|
+
<rect x="14" y="4" width="4" height="16"></rect>
|
|
362
|
+
</svg>
|
|
363
|
+
`,refreshCw:o`
|
|
364
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
365
|
+
<polyline points="23 4 23 10 17 10"></polyline>
|
|
366
|
+
<polyline points="1 20 1 14 7 14"></polyline>
|
|
367
|
+
<path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>
|
|
368
|
+
</svg>
|
|
369
|
+
`,checkCircle:o`
|
|
370
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
371
|
+
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
|
|
372
|
+
<polyline points="22 4 12 14.01 9 11.01"></polyline>
|
|
373
|
+
</svg>
|
|
374
|
+
`,xCircle:o`
|
|
375
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
376
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
377
|
+
<line x1="15" y1="9" x2="9" y2="15"></line>
|
|
378
|
+
<line x1="9" y1="9" x2="15" y2="15"></line>
|
|
379
|
+
</svg>
|
|
380
|
+
`,loader:o`
|
|
381
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
382
|
+
<line x1="12" y1="2" x2="12" y2="6"></line>
|
|
383
|
+
<line x1="12" y1="18" x2="12" y2="22"></line>
|
|
384
|
+
<line x1="4.93" y1="4.93" x2="7.76" y2="7.76"></line>
|
|
385
|
+
<line x1="16.24" y1="16.24" x2="19.07" y2="19.07"></line>
|
|
386
|
+
<line x1="2" y1="12" x2="6" y2="12"></line>
|
|
387
|
+
<line x1="18" y1="12" x2="22" y2="12"></line>
|
|
388
|
+
<line x1="4.93" y1="19.07" x2="7.76" y2="16.24"></line>
|
|
389
|
+
<line x1="16.24" y1="7.76" x2="19.07" y2="4.93"></line>
|
|
390
|
+
</svg>
|
|
391
|
+
`,slash:o`
|
|
392
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
393
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
394
|
+
<line x1="4.93" y1="4.93" x2="19.07" y2="19.07"></line>
|
|
395
|
+
</svg>
|
|
396
|
+
`};function Ms(e){return e.includes("pdf")?o`
|
|
397
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2">
|
|
398
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
399
|
+
<polyline points="14,2 14,8 20,8"/>
|
|
400
|
+
</svg>
|
|
401
|
+
`:e.includes("word")||e.includes("document")?o`
|
|
402
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2">
|
|
403
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
404
|
+
<polyline points="14,2 14,8 20,8"/>
|
|
405
|
+
</svg>
|
|
406
|
+
`:e.includes("sheet")||e.includes("excel")?o`
|
|
407
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#16a34a" stroke-width="2">
|
|
408
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
409
|
+
<polyline points="14,2 14,8 20,8"/>
|
|
410
|
+
</svg>
|
|
411
|
+
`:e.includes("presentation")||e.includes("powerpoint")?o`
|
|
412
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2">
|
|
413
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
414
|
+
<polyline points="14,2 14,8 20,8"/>
|
|
415
|
+
</svg>
|
|
416
|
+
`:Fe.file}var Ts=Object.defineProperty,Es=Object.getOwnPropertyDescriptor,ut=(e,t,s,i)=>{for(var n=i>1?void 0:i?Es(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Ts(t,s,n),n};let Le=class extends y{constructor(){super(...arguments),this.attachments=[]}createRenderRoot(){return this}render(){if(!this.attachments?.length)return null;const e=this.attachments.filter(s=>s.type==="image"||s.mimeType?.startsWith("image/")),t=this.attachments.filter(s=>s.type!=="image"&&!s.mimeType?.startsWith("image/"));return o`
|
|
417
|
+
<div class="flex flex-col gap-2 mt-2">
|
|
418
|
+
${e.length>0?this._renderImageGallery(e):""}
|
|
419
|
+
${t.length>0?this._renderDocumentList(t):""}
|
|
420
|
+
</div>
|
|
421
|
+
`}_renderImageGallery(e){const t=e.length;let s="single";return t===2?s="double":t===3?s="triple":t>=4&&(s="quad"),o`
|
|
422
|
+
<div class="image-gallery ${s}">
|
|
423
|
+
${e.map(i=>o`
|
|
424
|
+
<img
|
|
425
|
+
src="${i.data||i.content}"
|
|
426
|
+
alt="${i.name||a("fileUpload.image")}"
|
|
427
|
+
@click=${()=>this._handleImageClick(i)}
|
|
428
|
+
/>
|
|
429
|
+
`)}
|
|
430
|
+
</div>
|
|
431
|
+
`}_renderDocumentList(e){return o`
|
|
432
|
+
<div class="flex flex-col gap-2">
|
|
433
|
+
${e.map(t=>this._renderDocumentPreview(t))}
|
|
434
|
+
</div>
|
|
435
|
+
`}_renderDocumentPreview(e){const t=e.name||a("fileUpload.document"),s=e.size?this._formatFileSize(e.size):"";return o`
|
|
436
|
+
<div class="document-preview" @click=${()=>this._handleDocumentClick(e)}>
|
|
437
|
+
<div class="icon">${Ms(e.mimeType||"")}</div>
|
|
438
|
+
<div class="info">
|
|
439
|
+
<div class="name">${t}</div>
|
|
440
|
+
<div class="meta">${s||e.mimeType||a("fileUpload.unknown")}</div>
|
|
441
|
+
</div>
|
|
442
|
+
</div>
|
|
443
|
+
`}_formatFileSize(e){const t=["B","KB","MB","GB"];let s=0,i=e;for(;i>=1024&&s<t.length-1;)i/=1024,s++;return`${i.toFixed(1)} ${t[s]}`}_handleImageClick(e){this.dispatchEvent(new CustomEvent("image-click",{detail:e,bubbles:!0,composed:!0}))}_handleDocumentClick(e){this.dispatchEvent(new CustomEvent("document-click",{detail:e,bubbles:!0,composed:!0}))}};ut([u({attribute:!1})],Le.prototype,"attachments",2);Le=ut([k("attachment-renderer")],Le);var Ps=Object.defineProperty,Fs=Object.getOwnPropertyDescriptor,gt=(e,t,s,i)=>{for(var n=i>1?void 0:i?Fs(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Ps(t,s,n),n};let Ie=class extends y{createRenderRoot(){return this}render(){if(!this.usage)return null;const e=[];return this.usage.totalTokens!==void 0?e.push(`${this.usage.totalTokens} tokens`):this.usage.inputTokens!==void 0&&this.usage.outputTokens!==void 0&&e.push(`${this.usage.inputTokens+this.usage.outputTokens} tokens`),this.usage.cost!==void 0&&this.usage.cost>0&&e.push(`$${this.usage.cost.toFixed(4)}`),e.length===0?null:o`
|
|
444
|
+
<span class="usage-badge">
|
|
445
|
+
${e.join(" · ")}
|
|
446
|
+
</span>
|
|
447
|
+
`}};gt([u({attribute:!1})],Ie.prototype,"usage",2);Ie=gt([k("usage-badge")],Ie);var Ls=Object.defineProperty,Is=Object.getOwnPropertyDescriptor,je=(e,t,s,i)=>{for(var n=i>1?void 0:i?Is(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Ls(t,s,n),n};let xe=class extends y{constructor(){super(...arguments),this.isStreaming=!1}createRenderRoot(){return this}render(){const e=this.message.role==="user"||this.message.role==="user-with-attachments",t=this.message.role==="assistant";this.message.role==="tool"||this.message.role;const s=a(e?"chat.you":t?"chat.assistant":"chat.tool"),i=s.charAt(0);return o`
|
|
448
|
+
<div class="message-item ${e?"flex-row-reverse":""}">
|
|
449
|
+
<div class="avatar ${e?"user":t?"assistant":"tool"}">
|
|
450
|
+
${i}
|
|
451
|
+
</div>
|
|
452
|
+
|
|
453
|
+
<div class="flex flex-col gap-1 max-w-[85%]">
|
|
454
|
+
<div class="flex items-center gap-2 text-xs text-muted">
|
|
455
|
+
<span class="font-medium">${s}</span>
|
|
456
|
+
<span>·</span>
|
|
457
|
+
<span>${this._formatTime(this.message.timestamp)}</span>
|
|
458
|
+
${this.isStreaming?o`<span class="text-primary animate-pulse">${a("chat.thinking")}</span>`:""}
|
|
459
|
+
</div>
|
|
460
|
+
|
|
461
|
+
<div class="message-bubble ${e?"bg-primary-light":"bg-secondary"}">
|
|
462
|
+
${this._renderContent(this.message.content)}
|
|
463
|
+
${this.message.attachments?.length?o`
|
|
464
|
+
<attachment-renderer .attachments=${this.message.attachments}></attachment-renderer>
|
|
465
|
+
`:""}
|
|
466
|
+
</div>
|
|
467
|
+
|
|
468
|
+
${t&&this.message.usage?o`
|
|
469
|
+
<usage-badge .usage=${this.message.usage}></usage-badge>
|
|
470
|
+
`:""}
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
`}_renderContent(e){return!e||e.length===0?this.isStreaming?o`<span class="streaming-cursor"></span>`:null:o`
|
|
474
|
+
<div class="markdown-content">
|
|
475
|
+
${e.map(t=>this._renderContentBlock(t))}
|
|
476
|
+
${this.isStreaming?o`<span class="streaming-cursor"></span>`:""}
|
|
477
|
+
</div>
|
|
478
|
+
`}_renderContentBlock(e){switch(e.type){case"text":if(e.text)return o`<p class="whitespace-pre-wrap">${e.text}</p>`;break;case"image":if(e.source?.data)return o`<img src="${e.source.data}" class="rounded-lg max-w-full" />`;break;case"tool_use":case"tool_result":return this._renderToolCall(e);default:if(e.text)return o`<p class="whitespace-pre-wrap">${e.text}</p>`}return null}_renderToolCall(e){const t=e.is_error||e.error,s=e.name||e.function?.name||"Tool",i=e.input||e.function?.arguments;return o`
|
|
479
|
+
<div class="tool-call ${t?"tool-call--error":""}">
|
|
480
|
+
<div class="tool-call-header">
|
|
481
|
+
<span>🔧 ${s}</span>
|
|
482
|
+
${t?o`<span class="text-red-500 text-xs">Error</span>`:""}
|
|
483
|
+
</div>
|
|
484
|
+
${i?o`
|
|
485
|
+
<pre class="tool-call-content">${JSON.stringify(i,null,2)}</pre>
|
|
486
|
+
`:""}
|
|
487
|
+
${e.content?o`
|
|
488
|
+
<div class="tool-call-result">${JSON.stringify(e.content)}</div>
|
|
489
|
+
`:""}
|
|
490
|
+
</div>
|
|
491
|
+
`}_formatTime(e){return e?new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):""}};je([u({attribute:!1})],xe.prototype,"message",2);je([u({type:Boolean})],xe.prototype,"isStreaming",2);xe=je([k("message-bubble")],xe);var Ds=Object.defineProperty,Os=Object.getOwnPropertyDescriptor,Me=(e,t,s,i)=>{for(var n=i>1?void 0:i?Os(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Ds(t,s,n),n};let me=class extends y{constructor(){super(...arguments),this.messages=[],this.isStreaming=!1,this.useVirtualScroll=!1}createRenderRoot(){return this}render(){return!this.messages||this.messages.length===0?this._renderEmptyState():o`
|
|
492
|
+
<div class="flex flex-col gap-4 pb-4">
|
|
493
|
+
${this.messages.map((e,t)=>o`
|
|
494
|
+
<message-bubble
|
|
495
|
+
.message=${e}
|
|
496
|
+
.isStreaming=${this.isStreaming&&t===this.messages.length-1}
|
|
497
|
+
></message-bubble>
|
|
498
|
+
`)}
|
|
499
|
+
</div>
|
|
500
|
+
`}_renderEmptyState(){return o`
|
|
501
|
+
<div class="empty-state">
|
|
502
|
+
<div class="icon">💬</div>
|
|
503
|
+
<div class="title">${a("chat.emptyState")}</div>
|
|
504
|
+
<div class="description">${a("chat.emptyStateDescription")}</div>
|
|
505
|
+
</div>
|
|
506
|
+
`}scrollToBottom(){const e=this.closest(".overflow-y-auto");e&&(e.scrollTop=e.scrollHeight)}isNearBottom(e=100){const t=this.closest(".overflow-y-auto");if(!t)return!0;const{scrollTop:s,scrollHeight:i,clientHeight:n}=t;return i-s-n<e}};Me([u({attribute:!1})],me.prototype,"messages",2);Me([u({type:Boolean})],me.prototype,"isStreaming",2);Me([u({type:Boolean})],me.prototype,"useVirtualScroll",2);me=Me([k("message-list")],me);var Rs=Object.defineProperty,Bs=Object.getOwnPropertyDescriptor,ne=(e,t,s,i)=>{for(var n=i>1?void 0:i?Bs(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Rs(t,s,n),n};let W=class extends y{constructor(){super(...arguments),this.tools=new Map,this.pendingToolCalls=new Set,this.isStreaming=!1,this._currentMessage=null,this._isComplete=!1}createRenderRoot(){return this}setMessage(e,t){this._currentMessage=e,this._isComplete=t}render(){return this._currentMessage?o`
|
|
507
|
+
<div class="flex gap-3 message-item">
|
|
508
|
+
<div class="avatar assistant">
|
|
509
|
+
AI
|
|
510
|
+
</div>
|
|
511
|
+
|
|
512
|
+
<div class="flex flex-col gap-1 max-w-[85%]">
|
|
513
|
+
<div class="flex items-center gap-2 text-xs text-muted">
|
|
514
|
+
<span class="font-medium">Assistant</span>
|
|
515
|
+
<span>·</span>
|
|
516
|
+
<span class="text-accent animate-pulse">thinking...</span>
|
|
517
|
+
</div>
|
|
518
|
+
|
|
519
|
+
<div class="rounded-xl p-3 bg-secondary">
|
|
520
|
+
${this.renderStreamingContent()}
|
|
521
|
+
</div>
|
|
522
|
+
</div>
|
|
523
|
+
</div>
|
|
524
|
+
`:null}renderStreamingContent(){const e=this._currentMessage?.content||[];return o`
|
|
525
|
+
<div class="markdown-content">
|
|
526
|
+
${e.map(t=>t.type==="text"?o`<p class="whitespace-pre-wrap">${this._escapeHtml(t.text||"")}<span class="streaming-cursor"></span></p>`:t.type==="tool_use"?this.renderToolUse(t):"")}
|
|
527
|
+
${this.isStreaming&&(!e.length||e[e.length-1]?.type!=="text")?o`<span class="streaming-cursor"></span>`:""}
|
|
528
|
+
</div>
|
|
529
|
+
`}renderToolUse(e){const t=e.name||e.function?.name,s=e.input||e.function?.arguments||{},i=typeof s=="string"?s:JSON.stringify(s,null,2);return o`
|
|
530
|
+
<div class="tool-call">
|
|
531
|
+
<div class="name">
|
|
532
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
533
|
+
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
|
534
|
+
</svg>
|
|
535
|
+
<span>${t}</span>
|
|
536
|
+
</div>
|
|
537
|
+
<pre class="input">${i}</pre>
|
|
538
|
+
</div>
|
|
539
|
+
`}_escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}};ne([u({attribute:!1})],W.prototype,"tools",2);ne([u({attribute:!1})],W.prototype,"pendingToolCalls",2);ne([u({type:Boolean})],W.prototype,"isStreaming",2);ne([c()],W.prototype,"_currentMessage",2);ne([c()],W.prototype,"_isComplete",2);W=ne([k("streaming-message-container")],W);var Ks=Object.defineProperty,js=Object.getOwnPropertyDescriptor,x=(e,t,s,i)=>{for(var n=i>1?void 0:i?js(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Ks(t,s,n),n};function Y(e,t){return`${e.replace(/\/+$/,"")}${t}`}function ce(e){const t={"Content-Type":"application/json"};return e&&(t.Authorization=`Bearer ${e}`),t}let w=class extends y{constructor(){super(...arguments),this.enableAttachments=!0,this.enableModelSelector=!0,this._connectionState="disconnected",this._error=null,this._messages=[],this._isStreaming=!1,this._streamingContent="",this._streamingMessage=null,this._reconnectCount=0,this._isAtBottom=!0,this._currentSessionKey=null,this._sessions=[],this._hasMoreMessages=!0,this._isLoadingMore=!1,this._shouldReconnect=!0,this._isSending=!1,this._lastLoadedSessionKey=null,this._handleScroll=()=>{if(!this._chatMessages)return;const{scrollTop:e,scrollHeight:t,clientHeight:s}=this._chatMessages,i=t-e-s<50;i!==this._isAtBottom&&(this._isAtBottom=i),e<100&&!this._isAtBottom&&this._hasMoreMessages&&!this._isLoadingMore&&this._loadMoreMessages()},this._handleSend=(e,t)=>{const s=t?.map(i=>({type:i.type||"file",mimeType:i.mimeType,data:i.content,name:i.name,size:i.size}));this.sendMessage(e,s)}}get _maxReconnectAttempts(){return this.config?.maxReconnectAttempts??10}get _autoReconnect(){return this.config?.autoReconnect??!0}createRenderRoot(){return this}async connectedCallback(){super.connectedCallback(),this.classList.add("chat-container"),await Ss("en")}firstUpdated(){this._chatMessages&&this._chatMessages.addEventListener("scroll",this._handleScroll),this._handleRouteChange()}updated(e){super.updated(e),e.has("config")&&this.config&&this._connectionState==="disconnected"&&this.connect(),e.has("route")&&this.route&&this._handleRouteChange()}async _handleRouteChange(){const e=this.route;if(!e)return;let t=null;switch(e.type){case"recent":this._lastLoadedSessionKey=null,await this._loadSessions();return;case"session":t=e.sessionKey;break;case"new":await this._createNewSession();return}t&&t!==this._lastLoadedSessionKey&&(await this._loadSession(t,0),this._lastLoadedSessionKey=t)}async _loadSession(e,t=0){if(this.config)try{const s=Y(this.config.url,`/api/sessions/${encodeURIComponent(e)}?offset=${t}&limit=50`),i=ce(this.config.token),n=await fetch(s,{headers:i});if(!n.ok)throw new Error(`HTTP ${n.status}`);const l=(await n.json()).session;this._currentSessionKey=e;const h=l.messages||[],d=h.filter(g=>g.role==="user"||g.role==="assistant").map(g=>({role:g.role,content:typeof g.content=="string"?[{type:"text",text:g.content}]:g.content||[],attachments:g.attachments,timestamp:g.timestamp?new Date(g.timestamp).getTime():Date.now()}));t>0?this._messages=[...d,...this._messages]:this._messages=d,this._hasMoreMessages=h.length>=50,t===0&&this._scrollToBottom(!1),this.requestUpdate()}catch(s){console.error("[GatewayChat] Failed to load session:",s)}}async _loadMoreMessages(){if(!this._currentSessionKey||this._isLoadingMore||!this._hasMoreMessages)return;this._isLoadingMore=!0;const e=this._messages.length;try{await this._loadSession(this._currentSessionKey,e)}finally{this._isLoadingMore=!1}}disconnectedCallback(){super.disconnectedCallback(),this._shouldReconnect=!1,this.disconnect(),this._chatMessages&&this._chatMessages.removeEventListener("scroll",this._handleScroll)}_scrollToBottom(e=!0){this.updateComplete.then(()=>{this._chatMessages&&this._chatMessages.scrollTo({top:this._chatMessages.scrollHeight,behavior:e?"smooth":"auto"})})}connect(){if(!(!this.config||this._connectionState==="connecting")){this._connectionState="connecting",this._error=null,this.requestUpdate();try{const e=Y(this.config.url,"/api/events"),t=new URL(e);this.config.token&&t.searchParams.set("token",this.config.token),this._eventSource=new EventSource(t.toString()),this._eventSource.onopen=()=>{this._connectionState="connected",this._error=null,this._reconnectCount=0,this.requestUpdate(),this._lastLoadedSessionKey||this._loadSessions()},this._eventSource.addEventListener("connected",()=>{this._connectionState="connected",this._error=null,this.requestUpdate()}),this._eventSource.addEventListener("config.reload",s=>{try{const i=JSON.parse(s.data);this.dispatchEvent(new CustomEvent("config-reload",{detail:i}))}catch{}}),this._eventSource.addEventListener("channels.status",s=>{try{const i=JSON.parse(s.data);this.dispatchEvent(new CustomEvent("channels-status",{detail:i}))}catch{}}),this._eventSource.addEventListener("message.sent",s=>{try{const i=JSON.parse(s.data);this.dispatchEvent(new CustomEvent("message-sent",{detail:i}))}catch{}}),this._eventSource.onerror=()=>{this._eventSource?.readyState===EventSource.CLOSED?(this._connectionState="disconnected",this._handlePermanentDisconnect()):this._connectionState="reconnecting",this.requestUpdate()}}catch(e){console.error("[GatewayChat] Failed to create EventSource:",e),this._connectionState="error",this._error=a("errors.connectionError"),this.requestUpdate()}}}_handlePermanentDisconnect(){this._isStreaming&&(this._isStreaming=!1,this._isSending=!1,this._streamingContent="",this._streamingMessage=null),this._shouldReconnect&&this._autoReconnect&&(this._reconnectCount++,this._reconnectCount>this._maxReconnectAttempts&&(this._error=a("errors.connectionError"),this._connectionState="error"))}disconnect(){this._shouldReconnect=!1,this._eventSource?.close(),this._eventSource=void 0,this._agentAbort?.abort(),this._agentAbort=void 0,this._connectionState="disconnected"}reconnect(){this._shouldReconnect=!0,this._reconnectCount=0,this.disconnect(),setTimeout(()=>this.connect(),100)}async _loadSessions(){if(this.config)try{const e=Y(this.config.url,"/api/sessions?limit=20"),t=ce(this.config.token),s=await fetch(e,{headers:t});if(!s.ok)throw new Error(`HTTP ${s.status}`);const r=((await s.json()).items||[]).filter(h=>h.key.startsWith("gateway:")).sort((h,d)=>new Date(d.updatedAt).getTime()-new Date(h.updatedAt).getTime());this._sessions=r;const l=r.filter(h=>h.messageCount>0);if(l.length>0){const h=l[0].key;await this._loadSession(h,0),this._lastLoadedSessionKey=h,this._updateUrlWithSession(h)}else if(r.length>0){const h=r[0];this._currentSessionKey=h.key,this._messages=[],this._lastLoadedSessionKey=h.key,this._updateUrlWithSession(h.key)}else await this._createNewSession()}catch(e){console.error("[GatewayChat] Failed to load sessions:",e)}}_updateUrlWithSession(e){const t=`#/chat/${encodeURIComponent(e)}`;location.hash!==t&&history.replaceState(null,"",t)}async _createNewSession(){if(!this.config)return;const e=this._sessions.find(t=>t.messageCount===0);if(e){this._currentSessionKey=e.key,this._messages=[],this._lastLoadedSessionKey=e.key,this._updateUrlWithSession(e.key);return}try{const t=Y(this.config.url,"/api/sessions"),s={...ce(this.config.token),"Content-Type":"application/json"},i=await fetch(t,{method:"POST",headers:s,body:JSON.stringify({channel:"gateway"})});if(!i.ok)throw new Error(`HTTP ${i.status}`);const r=(await i.json()).session;this._currentSessionKey=r.key,this._messages=[],this._sessions=[{key:r.key,name:r.name,updatedAt:r.updatedAt},...this._sessions],this._currentSessionKey=r.key,this._lastLoadedSessionKey=r.key,this._updateUrlWithSession(r.key),this._scrollToBottom(),this.requestUpdate()}catch(t){console.error("[GatewayChat] Failed to create new session:",t)}}async sendMessage(e,t){if(!(this._isSending||this._isStreaming)&&!(!e.trim()&&!t?.length)&&this.config){this._isSending=!0,this._messages=[...this._messages,{role:"user",content:e?[{type:"text",text:e}]:[],attachments:t,timestamp:Date.now()}],this._scrollToBottom(),this.requestUpdate();try{this._agentAbort=new AbortController;const s=Y(this.config.url,"/api/agent"),i={...ce(this.config.token),Accept:"text/event-stream"},n=this._currentSessionKey?this._currentSessionKey.replace("gateway:",""):"default",r=await fetch(s,{method:"POST",headers:i,body:JSON.stringify({message:e,channel:"gateway",chatId:n,attachments:t}),signal:this._agentAbort.signal});if(!r.ok){const h=await r.json().catch(()=>({}));throw new Error(h.error?.message||`HTTP ${r.status}`)}if((r.headers.get("Content-Type")||"").includes("text/event-stream")&&r.body)await this._consumeSSEStream(r.body);else{const h=await r.json();h.ok&&h.payload?.content&&(this._updateStreamingMessage(h.payload.content),this._finalizeMessage())}}catch(s){if(s.name==="AbortError")return;this._error=s instanceof Error?s.message:a("errors.sendFailed"),this._isStreaming=!1,this._isSending=!1,this._streamingMessage=null,this.requestUpdate()}finally{this._agentAbort=void 0,this._isSending=!1}}}async _consumeSSEStream(e){const t=e.pipeThrough(new TextDecoderStream).getReader();let s="",i="",n="";try{for(;;){const{done:r,value:l}=await t.read();if(r)break;for(s+=l;s.includes(`
|
|
540
|
+
`);){const h=s.indexOf(`
|
|
541
|
+
`),d=s.slice(0,h);s=s.slice(h+1),d.startsWith("event:")?i=d.slice(6).trim():d.startsWith("data:")?n+=(n?`
|
|
542
|
+
`:"")+d.slice(5).trim():d===""&&n&&(this._handleSSEEvent(i||"message",n),i="",n="")}}if(s.trim()||n){if(s.trim()){const r=s.split(`
|
|
543
|
+
`);for(const l of r)l.startsWith("event:")?i=l.slice(6).trim():l.startsWith("data:")?n+=(n?`
|
|
544
|
+
`:"")+l.slice(5).trim():l===""&&n&&(this._handleSSEEvent(i||"message",n),i="",n="")}n&&this._handleSSEEvent(i||"message",n)}}finally{t.releaseLock()}}_handleSSEEvent(e,t){try{const s=JSON.parse(t);switch(e){case"status":this._isStreaming=!0,this.requestUpdate();break;case"token":s.content&&this._updateStreamingMessage(s.content);break;case"error":this._error=s.content||s.error?.message||a("errors.sendFailed"),this._isStreaming=!1,this._isSending=!1,this._streamingMessage=null,this.requestUpdate();break;case"result":this._finalizeMessage();break;default:s.content&&this._updateStreamingMessage(s.content);break}}catch{}}_updateStreamingMessage(e){if(this._streamingMessage){const t=this._streamingMessage.content.find(s=>s.type==="text");t?t.text=(t.text||"")+e:this._streamingMessage.content.push({type:"text",text:e})}else this._streamingMessage={role:"assistant",content:[{type:"text",text:e}],timestamp:Date.now()};this._isStreaming=!0,this._streamingContent=e,this.requestUpdate(),this._isAtBottom&&this._scrollToBottom()}_finalizeMessage(){this._streamingMessage&&(this._messages=[...this._messages,this._streamingMessage],this._streamingMessage=null),this._isStreaming=!1,this._streamingContent="",this._isSending=!1,this._isAtBottom&&this._scrollToBottom(),this.requestUpdate()}async request(e,t,s){if(!this.config)throw new Error("Not configured");const i=Y(this.config.url,t),n=await fetch(i,{method:e,headers:ce(this.config.token),body:s?JSON.stringify(s):void 0});if(!n.ok){const r=await n.json().catch(()=>({error:{message:`HTTP ${n.status}`}}));throw new Error(r.error?.message||`HTTP ${n.status}`)}return n.json()}abort(){this._agentAbort?.abort(),this._agentAbort=void 0,this._isStreaming=!1,this._isSending=!1,this._streamingContent="",this._streamingMessage=null,this.requestUpdate()}get connectionState(){return this._connectionState}get messages(){return this._messages}clearMessages(){this._messages=[],this.requestUpdate()}render(){return o`
|
|
545
|
+
${this._renderStatus()}
|
|
546
|
+
${this._renderHeader()}
|
|
547
|
+
|
|
548
|
+
<div class="chat-messages">
|
|
549
|
+
<div class="chat-messages-inner">
|
|
550
|
+
${this._renderMessages()}
|
|
551
|
+
</div>
|
|
552
|
+
</div>
|
|
553
|
+
|
|
554
|
+
<!-- Scroll to bottom button - placed outside overflow container -->
|
|
555
|
+
${this._isAtBottom?"":o`
|
|
556
|
+
<button
|
|
557
|
+
class="scroll-to-bottom-btn"
|
|
558
|
+
style="position: fixed; bottom: 100px; right: 24px; width: 48px; height: 48px; border-radius: 50%; background: #3b82f6; color: white; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 100;"
|
|
559
|
+
@click=${this._scrollToBottom}
|
|
560
|
+
title="Scroll to bottom"
|
|
561
|
+
>
|
|
562
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
|
|
563
|
+
</button>
|
|
564
|
+
`}
|
|
565
|
+
|
|
566
|
+
<div class="chat-input-container">
|
|
567
|
+
<div class="chat-input-inner">
|
|
568
|
+
${this._renderInput()}
|
|
569
|
+
</div>
|
|
570
|
+
</div>
|
|
571
|
+
`}_renderHeader(){return o`
|
|
572
|
+
<div class="chat-header">
|
|
573
|
+
<div class="chat-header-title">
|
|
574
|
+
<span class="font-semibold">${a("chat.title")||"XopcBot"}</span>
|
|
575
|
+
${this._currentSessionKey?o`
|
|
576
|
+
<span class="text-xs text-muted ml-2">${this._sessions.find(e=>e.key===this._currentSessionKey)?.name||this._currentSessionKey}</span>
|
|
577
|
+
`:""}
|
|
578
|
+
</div>
|
|
579
|
+
<button class="new-session-btn" @click=${()=>this._createNewSession()}>
|
|
580
|
+
${this._renderIcon("plus")}
|
|
581
|
+
<span>${a("chat.newSession")||"New Chat"}</span>
|
|
582
|
+
</button>
|
|
583
|
+
</div>
|
|
584
|
+
`}_renderStatus(){return this._connectionState==="error"&&this._error?o`
|
|
585
|
+
<div class="status-bar error">
|
|
586
|
+
${this._renderIcon("alertCircle")}
|
|
587
|
+
<span>${this._error}</span>
|
|
588
|
+
<button class="underline ml-auto" @click=${()=>this.reconnect()}>${a("chat.retry")}</button>
|
|
589
|
+
</div>
|
|
590
|
+
`:this._connectionState==="reconnecting"?o`
|
|
591
|
+
<div class="status-bar warning">
|
|
592
|
+
<div class="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
|
|
593
|
+
<span>${a("chat.reconnecting")}</span>
|
|
594
|
+
</div>
|
|
595
|
+
`:this._connectionState==="connecting"?o`
|
|
596
|
+
<div class="status-bar warning">
|
|
597
|
+
<div class="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
|
|
598
|
+
<span>${a("chat.connecting")}</span>
|
|
599
|
+
</div>
|
|
600
|
+
`:null}_renderIcon(e){return{alertCircle:o`
|
|
601
|
+
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
602
|
+
<circle cx="12" cy="12" r="10"/>
|
|
603
|
+
<line x1="12" y1="8" x2="12" y2="12"/>
|
|
604
|
+
<line x1="12" y1="16" x2="12.01" y2="16"/>
|
|
605
|
+
</svg>
|
|
606
|
+
`,chevronDown:o`
|
|
607
|
+
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
608
|
+
<polyline points="6 9 12 15 18 9"/>
|
|
609
|
+
</svg>
|
|
610
|
+
`,plus:o`
|
|
611
|
+
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
612
|
+
<line x1="12" y1="5" x2="12" y2="19"/>
|
|
613
|
+
<line x1="5" y1="12" x2="19" y2="12"/>
|
|
614
|
+
</svg>
|
|
615
|
+
`}[e]||""}_renderScrollToBottomButton(){return o`
|
|
616
|
+
<button
|
|
617
|
+
class="scroll-to-bottom-btn"
|
|
618
|
+
style="background: red !important; width: 60px; height: 60px; font-size: 24px;"
|
|
619
|
+
@click=${this._scrollToBottom}
|
|
620
|
+
title="Scroll to bottom"
|
|
621
|
+
>
|
|
622
|
+
👇
|
|
623
|
+
</button>
|
|
624
|
+
`}_renderMessages(){return!this._messages.length&&!this._isStreaming?o`
|
|
625
|
+
<div class="empty-state" style="padding-top: 30vh;">
|
|
626
|
+
<div class="icon">🤖</div>
|
|
627
|
+
<div class="title">${a("chat.welcomeTitle")}</div>
|
|
628
|
+
<div class="description">${a("chat.welcomeDescription")}</div>
|
|
629
|
+
</div>
|
|
630
|
+
`:o`
|
|
631
|
+
<div class="flex flex-col gap-4">
|
|
632
|
+
${this._messages.map(e=>this._renderMessage(e))}
|
|
633
|
+
${this._isStreaming&&this._streamingMessage?this._renderStreamingMessage():""}
|
|
634
|
+
</div>
|
|
635
|
+
`}_renderMessage(e){const t=e.role==="user";return!e.content?.some(i=>i.text)&&!e.attachments?.length?null:o`
|
|
636
|
+
<div class="message-item ${t?"flex-row-reverse":""}">
|
|
637
|
+
<div class="avatar ${t?"user":"assistant"}">
|
|
638
|
+
${t?a("chat.you").charAt(0):"X"}
|
|
639
|
+
</div>
|
|
640
|
+
|
|
641
|
+
<div class="flex flex-col gap-1 max-w-[calc(100%-3rem)]">
|
|
642
|
+
<div class="flex items-center gap-2 text-xs text-muted ${t?"flex-row-reverse":""}">
|
|
643
|
+
<span class="font-medium">${a(t?"chat.you":"chat.assistant")}</span>
|
|
644
|
+
<span>·</span>
|
|
645
|
+
<span>${this._formatTime(e.timestamp)}</span>
|
|
646
|
+
</div>
|
|
647
|
+
|
|
648
|
+
<div class="message-bubble ${t?"user":"assistant"}">
|
|
649
|
+
${this._renderMessageContent(e.content)}
|
|
650
|
+
${e.attachments?.length?this._renderAttachments(e.attachments):""}
|
|
651
|
+
</div>
|
|
652
|
+
</div>
|
|
653
|
+
</div>
|
|
654
|
+
`}_renderStreamingMessage(){const e=this._streamingMessage?.content||[];return o`
|
|
655
|
+
<div class="message-item">
|
|
656
|
+
<div class="avatar assistant">X</div>
|
|
657
|
+
<div class="flex flex-col gap-1 max-w-[calc(100%-3rem)]">
|
|
658
|
+
<div class="flex items-center gap-2 text-xs text-muted">
|
|
659
|
+
<span class="font-medium">${a("chat.assistant")}</span>
|
|
660
|
+
<span>·</span>
|
|
661
|
+
<span class="text-primary animate-pulse">${a("chat.thinking")}</span>
|
|
662
|
+
</div>
|
|
663
|
+
<div class="message-bubble assistant">
|
|
664
|
+
<div class="markdown-content">
|
|
665
|
+
${e.map(t=>t.type==="text"&&t.text?o`<p class="whitespace-pre-wrap">${t.text}<span class="streaming-cursor"></span></p>`:"")}
|
|
666
|
+
${e.length?"":o`<span class="streaming-cursor"></span>`}
|
|
667
|
+
</div>
|
|
668
|
+
</div>
|
|
669
|
+
</div>
|
|
670
|
+
</div>
|
|
671
|
+
`}_renderMessageContent(e){return!e||e.length===0?null:o`
|
|
672
|
+
<div class="markdown-content">
|
|
673
|
+
${e.map(t=>t.type==="text"&&t.text?o`<p class="whitespace-pre-wrap">${t.text}</p>`:"")}
|
|
674
|
+
</div>
|
|
675
|
+
`}_renderAttachments(e){const t=e.filter(i=>i.type==="image"||i.mimeType?.startsWith("image/")),s=e.filter(i=>i.type!=="image"&&!i.mimeType?.startsWith("image/"));return o`
|
|
676
|
+
<div class="flex flex-col gap-2 mt-2">
|
|
677
|
+
${t.length>0?this._renderImageGallery(t):""}
|
|
678
|
+
${s.length>0?this._renderDocumentList(s):""}
|
|
679
|
+
</div>
|
|
680
|
+
`}_renderImageGallery(e){const t=e.length;let s="single";return t===2?s="double":t===3?s="triple":t>=4&&(s="quad"),o`
|
|
681
|
+
<div class="image-gallery ${s}">
|
|
682
|
+
${e.map(i=>o`<img src="${i.data}" alt="${i.name||"Image"}" />`)}
|
|
683
|
+
</div>
|
|
684
|
+
`}_renderDocumentList(e){return o`
|
|
685
|
+
<div class="flex flex-col gap-2">
|
|
686
|
+
${e.map(t=>this._renderDocumentPreview(t))}
|
|
687
|
+
</div>
|
|
688
|
+
`}_renderDocumentPreview(e){const t=e.name||"Document",s=e.size?this._formatFileSize(e.size):"";return o`
|
|
689
|
+
<div class="document-preview">
|
|
690
|
+
<div class="icon">${this._getDocumentIcon(e.mimeType||"")}</div>
|
|
691
|
+
<div class="info">
|
|
692
|
+
<div class="name">${t}</div>
|
|
693
|
+
<div class="meta">${s||e.mimeType||"File"}</div>
|
|
694
|
+
</div>
|
|
695
|
+
</div>
|
|
696
|
+
`}_getDocumentIcon(e){const t=e.includes("pdf")?"#ef4444":e.includes("word")||e.includes("document")?"#2563eb":e.includes("sheet")||e.includes("excel")?"#16a34a":"currentColor";return o`
|
|
697
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="${t}" stroke-width="2">
|
|
698
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
699
|
+
<polyline points="14,2 14,8 20,8"/>
|
|
700
|
+
</svg>
|
|
701
|
+
`}_renderInput(){return o`
|
|
702
|
+
<message-editor
|
|
703
|
+
.isStreaming=${this._isStreaming}
|
|
704
|
+
.showAttachmentButton=${this.enableAttachments}
|
|
705
|
+
.showModelSelector=${this.enableModelSelector}
|
|
706
|
+
.onSend=${(e,t)=>this._handleSend(e,t)}
|
|
707
|
+
.onAbort=${()=>this.abort()}
|
|
708
|
+
></message-editor>
|
|
709
|
+
`}_formatTime(e){return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}_formatFileSize(e){const t=["B","KB","MB","GB"];let s=0,i=e;for(;i>=1024&&s<t.length-1;)i/=1024,s++;return`${i.toFixed(1)} ${t[s]}`}};x([u({attribute:!1})],w.prototype,"config",2);x([u({attribute:!1})],w.prototype,"route",2);x([u({type:Boolean})],w.prototype,"enableAttachments",2);x([u({type:Boolean})],w.prototype,"enableModelSelector",2);x([ie("message-editor")],w.prototype,"_messageEditor",2);x([ie(".chat-messages")],w.prototype,"_chatMessages",2);x([c()],w.prototype,"_connectionState",2);x([c()],w.prototype,"_error",2);x([c()],w.prototype,"_messages",2);x([c()],w.prototype,"_isStreaming",2);x([c()],w.prototype,"_streamingContent",2);x([c()],w.prototype,"_streamingMessage",2);x([c()],w.prototype,"_reconnectCount",2);x([c()],w.prototype,"_isAtBottom",2);x([c()],w.prototype,"_currentSessionKey",2);x([c()],w.prototype,"_sessions",2);x([c()],w.prototype,"_hasMoreMessages",2);x([c()],w.prototype,"_isLoadingMore",2);w=x([k("xopcbot-gateway-chat")],w);var Us=Object.defineProperty,Hs=Object.getOwnPropertyDescriptor,Ue=(e,t,s,i)=>{for(var n=i>1?void 0:i?Hs(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Us(t,s,n),n};let Se=class extends y{constructor(){super(...arguments),this.selected=!1}createRenderRoot(){return this}_emit(e){this.dispatchEvent(new CustomEvent("session-action",{detail:{action:e,key:this.session.key},bubbles:!0,composed:!0}))}_formatDate(e){const t=new Date(e),i=Math.floor((new Date().getTime()-t.getTime())/(1e3*60*60*24));return i===0?t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):i===1?"Yesterday":i<7?t.toLocaleDateString([],{weekday:"short"}):t.toLocaleDateString([],{month:"short",day:"numeric"})}_getChannelIcon(e){return{telegram:"send",whatsapp:"phone",gateway:"globe",cli:"terminal"}[e]||"messageSquare"}_getStatusBadge(){switch(this.session.status){case"archived":return"bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400";case"pinned":return"bg-blue-100 text-blue-600 dark:bg-blue-900/30 dark:text-blue-400";default:return"bg-green-100 text-green-600 dark:bg-green-900/30 dark:text-green-400"}}render(){const e=this.session.name||this.session.key,t=this.session.status==="archived",s=this.session.status==="pinned";return o`
|
|
710
|
+
<div
|
|
711
|
+
class="session-card ${this.selected?"session-card--selected":""} ${t?"session-card--archived":""}"
|
|
712
|
+
@click=${()=>this._emit("click")}
|
|
713
|
+
>
|
|
714
|
+
<div class="session-card__header">
|
|
715
|
+
<div class="session-card__channel">
|
|
716
|
+
<span class="channel-icon">${p(this._getChannelIcon(this.session.sourceChannel))}</span>
|
|
717
|
+
<span class="channel-name">${this.session.sourceChannel}</span>
|
|
718
|
+
</div>
|
|
719
|
+
<div class="session-card__meta">
|
|
720
|
+
${s?o`<span class="pin-badge" title="Pinned">${p("pin")}</span>`:""}
|
|
721
|
+
<span class="date">${this._formatDate(this.session.updatedAt)}</span>
|
|
722
|
+
</div>
|
|
723
|
+
</div>
|
|
724
|
+
|
|
725
|
+
<div class="session-card__title">
|
|
726
|
+
${e}
|
|
727
|
+
</div>
|
|
728
|
+
|
|
729
|
+
<div class="session-card__stats">
|
|
730
|
+
<span class="stat">
|
|
731
|
+
${p("messageSquare")}
|
|
732
|
+
${this.session.messageCount}
|
|
733
|
+
</span>
|
|
734
|
+
<span class="stat">
|
|
735
|
+
${p("zap")}
|
|
736
|
+
${this._formatTokens(this.session.estimatedTokens)}
|
|
737
|
+
</span>
|
|
738
|
+
</div>
|
|
739
|
+
|
|
740
|
+
${this.session.tags.length>0?o`
|
|
741
|
+
<div class="session-card__tags">
|
|
742
|
+
${this.session.tags.slice(0,3).map(i=>o`
|
|
743
|
+
<span class="tag">${i}</span>
|
|
744
|
+
`)}
|
|
745
|
+
${this.session.tags.length>3?o`
|
|
746
|
+
<span class="tag tag--more">+${this.session.tags.length-3}</span>
|
|
747
|
+
`:""}
|
|
748
|
+
</div>
|
|
749
|
+
`:""}
|
|
750
|
+
|
|
751
|
+
<div class="session-card__actions" @click=${i=>i.stopPropagation()}>
|
|
752
|
+
${t?o`
|
|
753
|
+
<button
|
|
754
|
+
class="btn-icon btn-icon--success"
|
|
755
|
+
title="Unarchive"
|
|
756
|
+
@click=${()=>this._emit("unarchive")}
|
|
757
|
+
>${p("archiveRestore")}</button>
|
|
758
|
+
`:o`
|
|
759
|
+
<button
|
|
760
|
+
class="btn-icon"
|
|
761
|
+
title="Archive"
|
|
762
|
+
@click=${()=>this._emit("archive")}
|
|
763
|
+
>${p("archive")}</button>
|
|
764
|
+
`}
|
|
765
|
+
|
|
766
|
+
${s?o`
|
|
767
|
+
<button
|
|
768
|
+
class="btn-icon btn-icon--primary"
|
|
769
|
+
title="Unpin"
|
|
770
|
+
@click=${()=>this._emit("unpin")}
|
|
771
|
+
>${p("pinOff")}</button>
|
|
772
|
+
`:o`
|
|
773
|
+
<button
|
|
774
|
+
class="btn-icon"
|
|
775
|
+
title="Pin"
|
|
776
|
+
@click=${()=>this._emit("pin")}
|
|
777
|
+
>${p("pin")}</button>
|
|
778
|
+
`}
|
|
779
|
+
|
|
780
|
+
<button
|
|
781
|
+
class="btn-icon"
|
|
782
|
+
title="Export"
|
|
783
|
+
@click=${()=>this._emit("export")}
|
|
784
|
+
>${p("download")}</button>
|
|
785
|
+
|
|
786
|
+
<button
|
|
787
|
+
class="btn-icon btn-icon--danger"
|
|
788
|
+
title="Delete"
|
|
789
|
+
@click=${()=>this._emit("delete")}
|
|
790
|
+
>${p("trash")}</button>
|
|
791
|
+
</div>
|
|
792
|
+
</div>
|
|
793
|
+
`}_formatTokens(e){return e>=1e3?(e/1e3).toFixed(1)+"k":e.toString()}};Ue([u({attribute:!1})],Se.prototype,"session",2);Ue([u({type:Boolean})],Se.prototype,"selected",2);Se=Ue([k("session-card")],Se);var Ns=Object.defineProperty,zs=Object.getOwnPropertyDescriptor,oe=(e,t,s,i)=>{for(var n=i>1?void 0:i?zs(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Ns(t,s,n),n};let V=class extends y{constructor(){super(...arguments),this.sessions=[],this.loading=!1,this.hasMore=!1,this.selectedKey=null,this._viewMode="grid"}createRenderRoot(){return this}_emit(e,t){this.dispatchEvent(new CustomEvent("list-action",{detail:{action:e,key:t},bubbles:!0,composed:!0}))}_handleCardAction(e){const{action:t,key:s}=e.detail;t==="click"?this._emit("select",s):this._emit(t,s)}_loadMore(){this.dispatchEvent(new CustomEvent("load-more",{bubbles:!0,composed:!0}))}render(){return this.loading&&this.sessions.length===0?this._renderLoading():this.sessions.length===0?this._renderEmpty():o`
|
|
794
|
+
<div class="session-list">
|
|
795
|
+
${this._renderToolbar()}
|
|
796
|
+
|
|
797
|
+
<div class="session-list__content session-list__content--${this._viewMode}">
|
|
798
|
+
${this.sessions.map(e=>o`
|
|
799
|
+
<session-card
|
|
800
|
+
.session=${e}
|
|
801
|
+
.selected=${e.key===this.selectedKey}
|
|
802
|
+
@session-action=${this._handleCardAction}
|
|
803
|
+
></session-card>
|
|
804
|
+
`)}
|
|
805
|
+
</div>
|
|
806
|
+
|
|
807
|
+
${this.hasMore?o`
|
|
808
|
+
<div class="session-list__load-more">
|
|
809
|
+
<button class="btn btn--secondary" @click=${this._loadMore}>
|
|
810
|
+
${p("chevronDown")}
|
|
811
|
+
Load More
|
|
812
|
+
</button>
|
|
813
|
+
</div>
|
|
814
|
+
`:""}
|
|
815
|
+
|
|
816
|
+
${this.loading?o`
|
|
817
|
+
<div class="session-list__loading-overlay">
|
|
818
|
+
<div class="spinner"></div>
|
|
819
|
+
</div>
|
|
820
|
+
`:""}
|
|
821
|
+
</div>
|
|
822
|
+
`}_renderToolbar(){return o`
|
|
823
|
+
<div class="session-list__toolbar">
|
|
824
|
+
<div class="session-list__count">
|
|
825
|
+
${this.sessions.length} sessions
|
|
826
|
+
</div>
|
|
827
|
+
|
|
828
|
+
<div class="session-list__view-toggle">
|
|
829
|
+
<button
|
|
830
|
+
class="btn-icon ${this._viewMode==="grid"?"btn-icon--active":""}"
|
|
831
|
+
title="Grid view"
|
|
832
|
+
@click=${()=>this._viewMode="grid"}
|
|
833
|
+
>${p("grid")}</button>
|
|
834
|
+
<button
|
|
835
|
+
class="btn-icon ${this._viewMode==="list"?"btn-icon--active":""}"
|
|
836
|
+
title="List view"
|
|
837
|
+
@click=${()=>this._viewMode="list"}
|
|
838
|
+
>${p("list")}</button>
|
|
839
|
+
</div>
|
|
840
|
+
</div>
|
|
841
|
+
`}_renderLoading(){return o`
|
|
842
|
+
<div class="session-list session-list--loading">
|
|
843
|
+
<div class="session-list__skeleton">
|
|
844
|
+
${Array.from({length:6}).map(()=>o`
|
|
845
|
+
<div class="skeleton-card">
|
|
846
|
+
<div class="skeleton skeleton--header"></div>
|
|
847
|
+
<div class="skeleton skeleton--title"></div>
|
|
848
|
+
<div class="skeleton skeleton--stats"></div>
|
|
849
|
+
</div>
|
|
850
|
+
`)}
|
|
851
|
+
</div>
|
|
852
|
+
</div>
|
|
853
|
+
`}_renderEmpty(){return o`
|
|
854
|
+
<div class="session-list session-list--empty">
|
|
855
|
+
<div class="empty-state">
|
|
856
|
+
<div class="empty-state__icon">${p("folderOpen")}</div>
|
|
857
|
+
<div class="empty-state__title">No sessions found</div>
|
|
858
|
+
<div class="empty-state__description">
|
|
859
|
+
Start a conversation to create your first session.
|
|
860
|
+
</div>
|
|
861
|
+
</div>
|
|
862
|
+
</div>
|
|
863
|
+
`}};oe([u({attribute:!1})],V.prototype,"sessions",2);oe([u({type:Boolean})],V.prototype,"loading",2);oe([u({type:Boolean})],V.prototype,"hasMore",2);oe([u({type:String})],V.prototype,"selectedKey",2);oe([c()],V.prototype,"_viewMode",2);V=oe([k("session-list")],V);var qs=Object.defineProperty,Js=Object.getOwnPropertyDescriptor,Q=(e,t,s,i)=>{for(var n=i>1?void 0:i?Js(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&qs(t,s,n),n};let j=class extends y{constructor(){super(...arguments),this.session=null,this.open=!1,this.loading=!1,this._searchQuery="",this._searchResults=[],this._currentResultIndex=-1}createRenderRoot(){return this}_emit(e){this.dispatchEvent(new CustomEvent("detail-action",{detail:{action:e},bubbles:!0,composed:!0}))}_handleClose(){this._emit("close")}_handleBackdropClick(e){e.target===e.currentTarget&&this._handleClose()}_handleSearch(e){const t=e.target;this._searchQuery=t.value,this._performSearch()}_performSearch(){if(!this.session||!this._searchQuery.trim()){this._searchResults=[],this._currentResultIndex=-1;return}const e=this._searchQuery.toLowerCase(),t=[];this.session.messages.forEach((s,i)=>{s.content.toLowerCase().includes(e)&&t.push(i)}),this._searchResults=t,this._currentResultIndex=t.length>0?0:-1}_navigateSearch(e){if(this._searchResults.length===0)return;e==="next"?this._currentResultIndex=(this._currentResultIndex+1)%this._searchResults.length:this._currentResultIndex=(this._currentResultIndex-1+this._searchResults.length)%this._searchResults.length;const t=this._searchResults[this._currentResultIndex],s=this.querySelector(`[data-message-index="${t}"]`);s&&s.scrollIntoView({behavior:"smooth",block:"center"})}_highlightText(e){if(!this._searchQuery.trim())return e;const t=this._searchQuery;return e.split(new RegExp(`(${t})`,"gi")).map((i,n)=>i.toLowerCase()===t.toLowerCase()?o`<mark class="search-highlight">${i}</mark>`:i)}_formatDate(e){return new Date(e).toLocaleString()}render(){return this.open?o`
|
|
864
|
+
<div class="drawer-backdrop" @click=${this._handleBackdropClick}>
|
|
865
|
+
<div class="drawer drawer--${this.open?"open":"closed"}">
|
|
866
|
+
${this._renderHeader()}
|
|
867
|
+
${this._renderSearch()}
|
|
868
|
+
${this._renderContent()}
|
|
869
|
+
${this._renderActions()}
|
|
870
|
+
</div>
|
|
871
|
+
</div>
|
|
872
|
+
`:""}_renderHeader(){if(!this.session)return"";const e=this.session.status==="archived",t=this.session.status==="pinned";return o`
|
|
873
|
+
<div class="drawer-header">
|
|
874
|
+
<div class="drawer-header__info">
|
|
875
|
+
<div class="drawer-header__title">
|
|
876
|
+
${this.session.name||this.session.key}
|
|
877
|
+
${t?o`<span class="pin-badge">${p("pin")}</span>`:""}
|
|
878
|
+
${e?o`<span class="archive-badge">Archived</span>`:""}
|
|
879
|
+
</div>
|
|
880
|
+
<div class="drawer-header__meta">
|
|
881
|
+
<span>${this.session.sourceChannel}</span>
|
|
882
|
+
<span>•</span>
|
|
883
|
+
<span>${this.session.messageCount} messages</span>
|
|
884
|
+
<span>•</span>
|
|
885
|
+
<span>${this._formatDate(this.session.updatedAt)}</span>
|
|
886
|
+
</div>
|
|
887
|
+
</div>
|
|
888
|
+
<button class="btn-icon" @click=${this._handleClose} title="Close">
|
|
889
|
+
${p("x")}
|
|
890
|
+
</button>
|
|
891
|
+
</div>
|
|
892
|
+
`}_renderSearch(){return this.session?o`
|
|
893
|
+
<div class="drawer-search">
|
|
894
|
+
<div class="search-input-wrapper">
|
|
895
|
+
${p("search")}
|
|
896
|
+
<input
|
|
897
|
+
type="text"
|
|
898
|
+
placeholder="Search in session..."
|
|
899
|
+
.value=${this._searchQuery}
|
|
900
|
+
@input=${this._handleSearch}
|
|
901
|
+
/>
|
|
902
|
+
${this._searchQuery?o`
|
|
903
|
+
<button class="btn-icon btn-icon--sm" @click=${()=>{this._searchQuery="",this._performSearch()}}>
|
|
904
|
+
${p("x")}
|
|
905
|
+
</button>
|
|
906
|
+
`:""}
|
|
907
|
+
</div>
|
|
908
|
+
|
|
909
|
+
${this._searchResults.length>0?o`
|
|
910
|
+
<div class="search-nav">
|
|
911
|
+
<span class="search-count">${this._currentResultIndex+1} / ${this._searchResults.length}</span>
|
|
912
|
+
<button class="btn-icon btn-icon--sm" @click=${()=>this._navigateSearch("prev")} title="Previous">
|
|
913
|
+
${p("chevronUp")}
|
|
914
|
+
</button>
|
|
915
|
+
<button class="btn-icon btn-icon--sm" @click=${()=>this._navigateSearch("next")} title="Next">
|
|
916
|
+
${p("chevronDown")}
|
|
917
|
+
</button>
|
|
918
|
+
</div>
|
|
919
|
+
`:""}
|
|
920
|
+
</div>
|
|
921
|
+
`:""}_renderContent(){return this.loading?o`
|
|
922
|
+
<div class="drawer-content drawer-content--loading">
|
|
923
|
+
<div class="spinner"></div>
|
|
924
|
+
<span>Loading...</span>
|
|
925
|
+
</div>
|
|
926
|
+
`:this.session?o`
|
|
927
|
+
<div class="drawer-content">
|
|
928
|
+
${this.session.messages.map((e,t)=>{const s=this._searchResults.includes(t),i=this._searchResults[this._currentResultIndex]===t;return o`
|
|
929
|
+
<div
|
|
930
|
+
class="message ${e.role} ${s?"message--highlight":""} ${i?"message--current":""}"
|
|
931
|
+
data-message-index="${t}"
|
|
932
|
+
>
|
|
933
|
+
<div class="message__header">
|
|
934
|
+
<span class="message__role">${e.role}</span>
|
|
935
|
+
${e.timestamp?o`<span class="message__time">${this._formatDate(e.timestamp)}</span>`:""}
|
|
936
|
+
</div>
|
|
937
|
+
<div class="message__content">${this._highlightText(e.content)}</div>
|
|
938
|
+
</div>
|
|
939
|
+
`})}
|
|
940
|
+
</div>
|
|
941
|
+
`:o`
|
|
942
|
+
<div class="drawer-content drawer-content--empty">
|
|
943
|
+
<span>No session selected</span>
|
|
944
|
+
</div>
|
|
945
|
+
`}_renderActions(){if(!this.session)return"";const e=this.session.status==="archived",t=this.session.status==="pinned";return o`
|
|
946
|
+
<div class="drawer-actions">
|
|
947
|
+
${e?o`
|
|
948
|
+
<button class="btn btn--secondary" @click=${()=>this._emit("unarchive")}>
|
|
949
|
+
${p("archiveRestore")} Unarchive
|
|
950
|
+
</button>
|
|
951
|
+
`:o`
|
|
952
|
+
<button class="btn btn--secondary" @click=${()=>this._emit("archive")}>
|
|
953
|
+
${p("archive")} Archive
|
|
954
|
+
</button>
|
|
955
|
+
`}
|
|
956
|
+
|
|
957
|
+
${t?o`
|
|
958
|
+
<button class="btn btn--secondary" @click=${()=>this._emit("unpin")}>
|
|
959
|
+
${p("pinOff")} Unpin
|
|
960
|
+
</button>
|
|
961
|
+
`:o`
|
|
962
|
+
<button class="btn btn--secondary" @click=${()=>this._emit("pin")}>
|
|
963
|
+
${p("pin")} Pin
|
|
964
|
+
</button>
|
|
965
|
+
`}
|
|
966
|
+
|
|
967
|
+
<button class="btn btn--secondary" @click=${()=>this._emit("export")}>
|
|
968
|
+
${p("download")} Export
|
|
969
|
+
</button>
|
|
970
|
+
|
|
971
|
+
<button class="btn btn--danger" @click=${()=>this._emit("delete")}>
|
|
972
|
+
${p("trash")} Delete
|
|
973
|
+
</button>
|
|
974
|
+
</div>
|
|
975
|
+
`}};Q([u({attribute:!1})],j.prototype,"session",2);Q([u({type:Boolean})],j.prototype,"open",2);Q([u({type:Boolean})],j.prototype,"loading",2);Q([c()],j.prototype,"_searchQuery",2);Q([c()],j.prototype,"_searchResults",2);Q([c()],j.prototype,"_currentResultIndex",2);j=Q([k("session-detail-drawer")],j);var Gs=Object.defineProperty,Ws=Object.getOwnPropertyDescriptor,X=(e,t,s,i)=>{for(var n=i>1?void 0:i?Ws(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Gs(t,s,n),n};let U=class extends y{constructor(){super(...arguments),this.open=!1,this.title="Confirm",this.message="Are you sure?",this.confirmText="Confirm",this.cancelText="Cancel",this.type="warning"}createRenderRoot(){return this}_emit(e){this.dispatchEvent(new CustomEvent("confirm",{detail:{confirmed:e},bubbles:!0,composed:!0})),this.open=!1}_handleBackdropClick(e){e.target===e.currentTarget&&this._emit(!1)}_getIcon(){switch(this.type){case"danger":return"trash";case"warning":return"alertTriangle";case"info":return"info";default:return"helpCircle"}}_getIconColor(){switch(this.type){case"danger":return"text-red-500";case"warning":return"text-amber-500";case"info":return"text-blue-500";default:return"text-gray-500"}}render(){return this.open?o`
|
|
976
|
+
<div class="modal-backdrop" @click=${this._handleBackdropClick}>
|
|
977
|
+
<div class="modal modal--${this.type}">
|
|
978
|
+
<div class="modal__icon ${this._getIconColor()}">
|
|
979
|
+
${p(this._getIcon())}
|
|
980
|
+
</div>
|
|
981
|
+
|
|
982
|
+
<div class="modal__content">
|
|
983
|
+
<h3 class="modal__title">${this.title}</h3>
|
|
984
|
+
<p class="modal__message">${this.message}</p>
|
|
985
|
+
</div>
|
|
986
|
+
|
|
987
|
+
<div class="modal__actions">
|
|
988
|
+
<button class="btn btn--secondary" @click=${()=>this._emit(!1)}>
|
|
989
|
+
${this.cancelText}
|
|
990
|
+
</button>
|
|
991
|
+
<button class="btn btn--${this.type==="danger"?"danger":"primary"}" @click=${()=>this._emit(!0)}>
|
|
992
|
+
${this.confirmText}
|
|
993
|
+
</button>
|
|
994
|
+
</div>
|
|
995
|
+
</div>
|
|
996
|
+
</div>
|
|
997
|
+
`:""}};X([u({type:Boolean})],U.prototype,"open",2);X([u({type:String})],U.prototype,"title",2);X([u({type:String})],U.prototype,"message",2);X([u({type:String})],U.prototype,"confirmText",2);X([u({type:String})],U.prototype,"cancelText",2);X([u({type:String})],U.prototype,"type",2);U=X([k("confirm-dialog")],U);class Vs{constructor(t,s){this.baseUrl=t.replace(/\/$/,""),this.token=s}async request(t,s,i){const n={"Content-Type":"application/json"};this.token&&(n.Authorization=`Bearer ${this.token}`);const r=await fetch(`${this.baseUrl}${s}`,{method:t,headers:n,body:i?JSON.stringify(i):void 0});if(!r.ok){const l=await r.json().catch(()=>({error:"Request failed"}));throw new Error(l.error||`HTTP ${r.status}`)}return r.json()}async listSessions(t){const s=new URLSearchParams;t?.status&&s.set("status",t.status),t?.search&&s.set("search",t.search),t?.limit&&s.set("limit",String(t.limit)),t?.offset&&s.set("offset",String(t.offset));const i=s.toString(),n=`/api/sessions${i?`?${i}`:""}`;return await this.request("GET",n)}async getSession(t){try{return(await this.request("GET",`/api/sessions/${t}`)).session||null}catch(s){if(s instanceof Error&&s.message.includes("404"))return null;throw s}}async deleteSession(t){return await this.request("DELETE",`/api/sessions/${t}`)}async archiveSession(t){return await this.request("POST",`/api/sessions/${t}/archive`)}async unarchiveSession(t){return await this.request("POST",`/api/sessions/${t}/unarchive`)}async pinSession(t){return await this.request("POST",`/api/sessions/${t}/pin`)}async unpinSession(t){return await this.request("POST",`/api/sessions/${t}/unpin`)}async renameSession(t,s){return await this.request("POST",`/api/sessions/${t}/rename`,{name:s})}async exportSession(t,s="json"){return(await this.request("GET",`/api/sessions/${t}/export?format=${s}`)).content}async getStats(){return await this.request("GET","/api/sessions/stats")}}var Qs=Object.defineProperty,Xs=Object.getOwnPropertyDescriptor,A=(e,t,s,i)=>{for(var n=i>1?void 0:i?Xs(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Qs(t,s,n),n};let b=class extends y{constructor(){super(...arguments),this._sessions=[],this._loading=!1,this._hasMore=!1,this._stats=null,this._searchQuery="",this._statusFilter="all",this._offset=0,this._error=null,this._detailOpen=!1,this._detailSession=null,this._detailLoading=!1,this._confirmOpen=!1,this._confirmTitle="",this._confirmMessage="",this._confirmKey=null,this._confirmAction=null,this._limit=20,this._initialized=!1,this._debouncedSearch=this._debounce(()=>{this._loadSessions(!0)},300)}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this._tryInitialize()}willUpdate(e){super.willUpdate(e),e.has("config")&&this._tryInitialize()}_tryInitialize(){if(this._initialized||!this.config?.url)return;const e=this.config.url.replace(/\/+$/,"");this._api=new Vs(e,this.config.token),this._initialized=!0,this._loadSessions(),this._loadStats()}disconnectedCallback(){super.disconnectedCallback()}async _loadSessions(e=!1){if(!this._loading){this._loading=!0,this._error=null,e&&(this._offset=0,this._sessions=[]);try{const t={limit:this._limit,offset:this._offset,sortBy:"updatedAt",sortOrder:"desc",...this._statusFilter!=="all"&&{status:this._statusFilter},...this._searchQuery&&{search:this._searchQuery}},s=await this._api.listSessions(t);e?this._sessions=s.items:this._sessions=[...this._sessions,...s.items],this._hasMore=s.hasMore,this._offset=s.offset+s.items.length}catch(t){this._error=t instanceof Error?t.message:"Failed to load sessions",console.error("[SessionManager] Load error:",t)}finally{this._loading=!1}}}async _loadStats(){try{this._stats=await this._api.getStats()}catch(e){console.error("[SessionManager] Stats error:",e)}}async _openDetail(e){this._detailOpen=!0,this._detailLoading=!0;try{const t=await this._api.getSession(e);this._detailSession=t}catch(t){console.error("[SessionManager] Load detail error:",t),this._detailOpen=!1}finally{this._detailLoading=!1}}_closeDetail(){this._detailOpen=!1,this._detailSession=null}_handleDetailAction(e){const{action:t}=e.detail,s=this._detailSession?.key;if(s)switch(t){case"close":this._closeDetail();break;case"delete":this._showConfirm(s);break;case"archive":this._archiveSession(s);break;case"unarchive":this._unarchiveSession(s);break;case"pin":this._pinSession(s);break;case"unpin":this._unpinSession(s);break;case"export":this._exportSession(s);break}}_showConfirm(e){this._confirmKey=e,this._confirmAction="delete",this._confirmTitle="Delete Session",this._confirmMessage=`Are you sure you want to delete session "${e}"?
|
|
998
|
+
|
|
999
|
+
This action cannot be undone.`,this._confirmOpen=!0}_handleConfirm(e){if(!e.detail.confirmed||!this._confirmKey){this._confirmOpen=!1,this._confirmKey=null;return}this._deleteSession(this._confirmKey),this._confirmOpen=!1,this._confirmKey=null}async _deleteSession(e){try{await this._api.deleteSession(e),this._sessions=this._sessions.filter(t=>t.key!==e),this._detailSession?.key===e&&this._closeDetail(),await this._loadStats()}catch(t){alert("Failed to delete session: "+(t instanceof Error?t.message:String(t)))}}async _archiveSession(e){try{await this._api.archiveSession(e),this._updateSessionStatus(e,"archived"),this._detailSession?.key===e&&(this._detailSession={...this._detailSession,status:"archived"}),await this._loadStats()}catch(t){console.error("[SessionManager] Archive error:",t)}}async _unarchiveSession(e){try{await this._api.unarchiveSession(e),this._updateSessionStatus(e,"active"),this._detailSession?.key===e&&(this._detailSession={...this._detailSession,status:"active"}),await this._loadStats()}catch(t){console.error("[SessionManager] Unarchive error:",t)}}async _pinSession(e){try{await this._api.pinSession(e),this._updateSessionStatus(e,"pinned"),this._detailSession?.key===e&&(this._detailSession={...this._detailSession,status:"pinned"}),await this._loadStats()}catch(t){console.error("[SessionManager] Pin error:",t)}}async _unpinSession(e){try{await this._api.unpinSession(e),this._updateSessionStatus(e,"active"),this._detailSession?.key===e&&(this._detailSession={...this._detailSession,status:"active"}),await this._loadStats()}catch(t){console.error("[SessionManager] Unpin error:",t)}}async _exportSession(e){try{const t=await this._api.exportSession(e,"json"),s=new Blob([t],{type:"application/json"}),i=URL.createObjectURL(s),n=document.createElement("a");n.href=i,n.download=`session-${e.replace(/[^a-z0-9]/gi,"_")}.json`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(i)}catch(t){alert("Failed to export session: "+(t instanceof Error?t.message:String(t)))}}_updateSessionStatus(e,t){this._sessions=this._sessions.map(s=>s.key===e?{...s,status:t}:s)}_handleListAction(e){const{action:t,key:s}=e.detail;switch(t){case"select":this._openDetail(s);break;case"delete":this._showConfirm(s);break;case"archive":this._archiveSession(s);break;case"unarchive":this._unarchiveSession(s);break;case"pin":this._pinSession(s);break;case"unpin":this._unpinSession(s);break;case"export":this._exportSession(s);break}}_handleSearch(e){const t=e.target;this._searchQuery=t.value,this._debouncedSearch()}_debounce(e,t){let s;return()=>{clearTimeout(s),s=setTimeout(e,t)}}_handleStatusFilter(e){this._statusFilter=e,this._loadSessions(!0)}_handleLoadMore(){this._loadSessions()}render(){return o`
|
|
1000
|
+
<div class="session-manager">
|
|
1001
|
+
${this._renderHeader()}
|
|
1002
|
+
${this._renderFilters()}
|
|
1003
|
+
${this._renderStats()}
|
|
1004
|
+
${this._error?o`<div class="error-banner">${this._error}</div>`:""}
|
|
1005
|
+
|
|
1006
|
+
<session-list
|
|
1007
|
+
.sessions=${this._sessions}
|
|
1008
|
+
.loading=${this._loading}
|
|
1009
|
+
.hasMore=${this._hasMore}
|
|
1010
|
+
@list-action=${this._handleListAction}
|
|
1011
|
+
@load-more=${this._handleLoadMore}
|
|
1012
|
+
></session-list>
|
|
1013
|
+
</div>
|
|
1014
|
+
|
|
1015
|
+
<session-detail-drawer
|
|
1016
|
+
.session=${this._detailSession}
|
|
1017
|
+
.open=${this._detailOpen}
|
|
1018
|
+
.loading=${this._detailLoading}
|
|
1019
|
+
@detail-action=${this._handleDetailAction}
|
|
1020
|
+
></session-detail-drawer>
|
|
1021
|
+
|
|
1022
|
+
<confirm-dialog
|
|
1023
|
+
.open=${this._confirmOpen}
|
|
1024
|
+
.title=${this._confirmTitle}
|
|
1025
|
+
.message=${this._confirmMessage}
|
|
1026
|
+
.confirmText="Delete"
|
|
1027
|
+
.cancelText="Cancel"
|
|
1028
|
+
.type="danger"
|
|
1029
|
+
@confirm=${this._handleConfirm}
|
|
1030
|
+
></confirm-dialog>
|
|
1031
|
+
`}_renderHeader(){return o`
|
|
1032
|
+
<div class="session-manager__header">
|
|
1033
|
+
<h1 class="page-title">${p("folderOpen")} ${a("sessions.title")}</h1>
|
|
1034
|
+
<div class="search-box">
|
|
1035
|
+
${p("search")}
|
|
1036
|
+
<input
|
|
1037
|
+
type="text"
|
|
1038
|
+
placeholder="${a("sessions.searchPlaceholder")}"
|
|
1039
|
+
.value=${this._searchQuery}
|
|
1040
|
+
@input=${this._handleSearch}
|
|
1041
|
+
/>
|
|
1042
|
+
</div>
|
|
1043
|
+
</div>
|
|
1044
|
+
`}_renderFilters(){return o`
|
|
1045
|
+
<div class="session-manager__filters">
|
|
1046
|
+
${[{key:"all",label:"All",icon:"layers"},{key:"active",label:"Active",icon:"circle"},{key:"pinned",label:"Pinned",icon:"pin"},{key:"archived",label:"Archived",icon:"archive"}].map(t=>o`
|
|
1047
|
+
<button
|
|
1048
|
+
class="filter-btn ${this._statusFilter===t.key?"filter-btn--active":""}"
|
|
1049
|
+
@click=${()=>this._handleStatusFilter(t.key)}
|
|
1050
|
+
>
|
|
1051
|
+
${p(t.icon)}
|
|
1052
|
+
${t.label}
|
|
1053
|
+
</button>
|
|
1054
|
+
`)}
|
|
1055
|
+
</div>
|
|
1056
|
+
`}_renderStats(){return this._stats?o`
|
|
1057
|
+
<div class="session-manager__stats">
|
|
1058
|
+
<div class="stat-card">
|
|
1059
|
+
<div class="stat-value">${this._stats.totalSessions}</div>
|
|
1060
|
+
<div class="stat-label">${a("sessions.totalSessions")}</div>
|
|
1061
|
+
</div>
|
|
1062
|
+
<div class="stat-card">
|
|
1063
|
+
<div class="stat-value">${this._stats.activeSessions}</div>
|
|
1064
|
+
<div class="stat-label">${a("sessions.activeSessions")}</div>
|
|
1065
|
+
</div>
|
|
1066
|
+
<div class="stat-card">
|
|
1067
|
+
<div class="stat-value">${this._stats.pinnedSessions}</div>
|
|
1068
|
+
<div class="stat-label">${a("sessions.pinnedSessions")}</div>
|
|
1069
|
+
</div>
|
|
1070
|
+
<div class="stat-card">
|
|
1071
|
+
<div class="stat-value">${this._stats.archivedSessions}</div>
|
|
1072
|
+
<div class="stat-label">${a("sessions.archivedSessions")}</div>
|
|
1073
|
+
</div>
|
|
1074
|
+
</div>
|
|
1075
|
+
`:""}};A([u({attribute:!1})],b.prototype,"config",2);A([c()],b.prototype,"_sessions",2);A([c()],b.prototype,"_loading",2);A([c()],b.prototype,"_hasMore",2);A([c()],b.prototype,"_stats",2);A([c()],b.prototype,"_searchQuery",2);A([c()],b.prototype,"_statusFilter",2);A([c()],b.prototype,"_offset",2);A([c()],b.prototype,"_error",2);A([c()],b.prototype,"_detailOpen",2);A([c()],b.prototype,"_detailSession",2);A([c()],b.prototype,"_detailLoading",2);A([c()],b.prototype,"_confirmOpen",2);A([c()],b.prototype,"_confirmTitle",2);A([c()],b.prototype,"_confirmMessage",2);A([c()],b.prototype,"_confirmKey",2);A([c()],b.prototype,"_confirmAction",2);b=A([k("session-manager")],b);class Zs{constructor(t,s){this.baseUrl=t.replace(/\/$/,""),this.token=s}async request(t,s,i){const n={"Content-Type":"application/json"};this.token&&(n.Authorization=`Bearer ${this.token}`);const r=await fetch(`${this.baseUrl}${s}`,{method:t,headers:n,body:i?JSON.stringify(i):void 0});if(!r.ok){const l=await r.json().catch(()=>({error:"Request failed"}));throw new Error(l.error||`HTTP ${r.status}`)}return r.json()}async listJobs(){return(await this.request("GET","/api/cron")).jobs||[]}async getJob(t){try{return(await this.request("GET",`/api/cron/${t}`)).job||null}catch(s){if(s instanceof Error&&s.message.includes("404"))return null;throw s}}async addJob(t,s,i){return await this.request("POST","/api/cron",{schedule:t,message:s,...i})}async updateJob(t,s){return(await this.request("PATCH",`/api/cron/${t}`,s)).updated}async removeJob(t){return(await this.request("DELETE",`/api/cron/${t}`)).removed}async toggleJob(t,s){return(await this.request("POST",`/api/cron/${t}/toggle`,{enabled:s})).toggled}async runJob(t){await this.request("POST",`/api/cron/${t}/run`)}async getHistory(t,s=10){return(await this.request("GET",`/api/cron/${t}/history?limit=${s}`)).history||[]}async getMetrics(){return await this.request("GET","/api/cron/metrics")}async getChannels(){return(await this.request("GET","/api/channels/status")).payload?.channels||[]}async getModels(){return(await this.request("GET","/api/models")).payload?.models||[]}async getConfig(){return{model:((await this.request("GET","/api/config")).config||{}).agents?.defaults?.model||""}}async getSessionChatIds(t){const s=t?`?channel=${encodeURIComponent(t)}`:"";return(await this.request("GET",`/api/sessions/chat-ids${s}`)).payload?.chatIds||[]}disconnect(){}}var Ys=Object.defineProperty,ei=Object.getOwnPropertyDescriptor,v=(e,t,s,i)=>{for(var n=i>1?void 0:i?ei(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&Ys(t,s,n),n};let _=class extends y{constructor(){super(...arguments),this._jobs=[],this._metrics=null,this._channels=[],this._availableModels=[],this._defaultModel="",this._sessionChatIds=[],this._loading=!1,this._error=null,this._formOpen=!1,this._formMode="add",this._formJobId=null,this._formName="",this._formSchedule="*/5 * * * *",this._formChannel="telegram",this._formChatId="",this._formMessage="",this._formSessionTarget="main",this._formModel="",this._formSubmitting=!1,this._detailOpen=!1,this._detailJob=null,this._detailHistory=[],this._detailLoading=!1,this._confirmOpen=!1,this._confirmTitle="",this._confirmMessage="",this._confirmJobId=null,this._confirmAction=null,this._initialized=!1}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this._tryInitialize()}willUpdate(e){super.willUpdate(e),e.has("config")&&this._tryInitialize()}_tryInitialize(){if(this._initialized||!this.config?.url)return;const e=this.config.url.replace(/\/+$/,"");this._api=new Zs(e,this.config.token),this._initialized=!0,this._loadJobs(),this._loadMetrics(),this._loadChannels(),this._loadModels(),this._loadSessionChatIds()}disconnectedCallback(){super.disconnectedCallback(),this._api?.disconnect()}async _loadJobs(){if(!this._loading){this._loading=!0,this._error=null;try{this._jobs=await this._api.listJobs()}catch(e){this._error=e instanceof Error&&e.message||a("cron.failedToLoadJobs"),console.error("[CronManager] Load error:",e)}finally{this._loading=!1}}}async _loadMetrics(){try{this._metrics=await this._api.getMetrics()}catch(e){console.error("[CronManager] Metrics error:",e)}}async _loadChannels(){try{this._channels=await this._api.getChannels()}catch(e){console.error("[CronManager] Channels error:",e)}}async _loadModels(){try{this._availableModels=await this._api.getModels();const e=await this._api.getConfig();this._defaultModel=e.model||"",this._formModel=this._defaultModel,console.log("[CronManager] Loaded models:",this._availableModels.length,"default:",this._defaultModel)}catch(e){console.error("[CronManager] Models error:",e)}}async _loadSessionChatIds(){try{const e=await this._api.getSessionChatIds(this._formChannel);this._sessionChatIds=e,console.log("[CronManager] Loaded session chatIds for channel",this._formChannel,":",e.length,e)}catch(e){console.error("[CronManager] Session chatIds error:",e),this._sessionChatIds=[]}}_openForm(e){if(this._formOpen=!0,this._formMode=e?"edit":"add",this._formJobId=e?.id||null,e||this._loadSessionChatIds(),e)if(this._formName=e.name||"",this._formSchedule=e.schedule,this._formMessage=e.message,this._formSessionTarget=e.sessionTarget||"main",this._formModel=e.model||"",e.delivery)this._formChannel=e.delivery.channel||"telegram",this._formChatId=e.delivery.to||"";else{const t=e.message.split(":"),s=["telegram","whatsapp","cli","gateway"];t.length>=3&&s.includes(t[0])?(this._formChannel=t[0],this._formChatId=t[1],this._formMessage=t.slice(2).join(":")):(this._formChannel="telegram",this._formChatId="")}else this._formName="",this._formSchedule="*/5 * * * *",this._formChannel="telegram",this._formChatId="",this._formMessage="",this._formSessionTarget="main",this._formModel=this._defaultModel||(this._availableModels.length>0?this._availableModels[0].id:"")}_closeForm(){this._formOpen=!1,this._formMode="add",this._formJobId=null,this._formName="",this._formSchedule="*/5 * * * *",this._formChannel="telegram",this._formChatId="",this._formMessage="",this._formSessionTarget="main",this._formModel=""}async _submitForm(){if(!this._formSchedule||!this._formMessage){this._error=a("cron.scheduleRequired");return}if(!this._formChatId){this._error=a("cron.chatIdRequired");return}this._formSubmitting=!0,this._error=null;try{const e=this._formMessage,t={mode:"direct",channel:this._formChannel,to:this._formChatId},s=this._formSessionTarget==="isolated"?{kind:"agentTurn",message:e,model:this._formModel}:{kind:"systemEvent",text:e},i={name:this._formName||void 0,schedule:this._formSchedule,message:e,sessionTarget:this._formSessionTarget,model:this._formSessionTarget==="isolated"?this._formModel:void 0,delivery:t};this._formMode==="edit"&&this._formJobId?await this._api.updateJob(this._formJobId,i):await this._api.addJob(this._formSchedule,e,i),this._closeForm(),await this._loadJobs(),await this._loadMetrics()}catch(e){this._error=e instanceof Error?e.message||a("cron.failedToJob",{mode:this._formMode}):a("cron.failedToJob",{mode:this._formMode})}finally{this._formSubmitting=!1}}async _openDetail(e){this._detailOpen=!0,this._detailJob=e,this._detailLoading=!0;try{const t=await this._api.getJob(e.id);t&&(this._detailJob=t,this._detailHistory=await this._api.getHistory(e.id,20))}catch(t){console.error("[CronManager] Load detail error:",t)}finally{this._detailLoading=!1}}_closeDetail(){this._detailOpen=!1,this._detailJob=null,this._detailHistory=[]}async _toggleJob(e,t){try{await this._api.toggleJob(e.id,t),await this._loadJobs(),await this._loadMetrics()}catch(s){this._error=s instanceof Error&&s.message||a("cron.failedToToggleJob")}}_showRunConfirm(e){this._confirmOpen=!0,this._confirmTitle=a("cron.runNow"),this._confirmMessage=a("cron.confirmRun"),this._confirmJobId=e.id,this._confirmAction="run"}_showDeleteConfirm(e){this._confirmOpen=!0,this._confirmTitle=a("cron.delete"),this._confirmMessage=a("cron.confirmDelete"),this._confirmJobId=e.id,this._confirmAction="delete"}_closeConfirm(){this._confirmOpen=!1,this._confirmTitle="",this._confirmMessage="",this._confirmJobId=null,this._confirmAction=null}_handleConfirm(e){e.detail.confirmed?this._executeConfirmAction():this._closeConfirm()}async _executeConfirmAction(){if(!this._confirmJobId||!this._confirmAction)return;const e=this._confirmJobId,t=this._confirmAction;this._closeConfirm();try{t==="run"?(await this._api.runJob(e),await this._loadJobs(),await this._loadMetrics()):t==="delete"&&(await this._api.removeJob(e),await this._loadJobs(),await this._loadMetrics())}catch(s){this._error=s instanceof Error&&s.message||a("cron.actionFailed")}}render(){return o`
|
|
1076
|
+
<div class="cron-manager">
|
|
1077
|
+
${this._error?o`<div class="error-banner">${this._error}</div>`:""}
|
|
1078
|
+
|
|
1079
|
+
<!-- Header -->
|
|
1080
|
+
<div class="cron-manager__header">
|
|
1081
|
+
<h1 class="page-title">${p("clock")} ${a("cron.title")}</h1>
|
|
1082
|
+
<div class="cron-manager__actions">
|
|
1083
|
+
<button class="btn btn-secondary" @click=${this._loadJobs} ?disabled=${this._loading}>
|
|
1084
|
+
${p("refresh")} ${a("logs.refresh")}
|
|
1085
|
+
</button>
|
|
1086
|
+
<button class="btn btn-primary" @click=${()=>this._openForm()}>
|
|
1087
|
+
${p("plus")} ${a("cron.addJob")}
|
|
1088
|
+
</button>
|
|
1089
|
+
</div>
|
|
1090
|
+
</div>
|
|
1091
|
+
|
|
1092
|
+
<!-- Stats -->
|
|
1093
|
+
${this._metrics?o`
|
|
1094
|
+
<div class="cron-manager__stats">
|
|
1095
|
+
<div class="stat-card" style="text-align: center;">
|
|
1096
|
+
<div class="stat-value">${this._metrics.totalJobs}</div>
|
|
1097
|
+
<div class="stat-label">${a("sessions.totalSessions")}</div>
|
|
1098
|
+
</div>
|
|
1099
|
+
<div class="stat-card" style="text-align: center;">
|
|
1100
|
+
<div class="stat-value">${this._metrics.enabledJobs}</div>
|
|
1101
|
+
<div class="stat-label">${a("cron.enabled")}</div>
|
|
1102
|
+
</div>
|
|
1103
|
+
<div class="stat-card" style="text-align: center;">
|
|
1104
|
+
<div class="stat-value">${this._metrics.runningJobs}</div>
|
|
1105
|
+
<div class="stat-label">${a("cron.running")}</div>
|
|
1106
|
+
</div>
|
|
1107
|
+
<div class="stat-card" style="text-align: center;">
|
|
1108
|
+
<div class="stat-value" style="font-size: 0.875rem;">
|
|
1109
|
+
${this._metrics.nextScheduledJob?this._formatNextRun(this._metrics.nextScheduledJob.runAt):"N/A"}
|
|
1110
|
+
</div>
|
|
1111
|
+
<div class="stat-label">${a("cron.nextRun")}</div>
|
|
1112
|
+
</div>
|
|
1113
|
+
</div>
|
|
1114
|
+
`:m}
|
|
1115
|
+
|
|
1116
|
+
<!-- Job List -->
|
|
1117
|
+
<div class="session-list">
|
|
1118
|
+
${this._loading&&this._jobs.length===0?o`
|
|
1119
|
+
<div class="session-list__loading-overlay">
|
|
1120
|
+
<div class="spinner"></div>
|
|
1121
|
+
</div>
|
|
1122
|
+
`:this._jobs.length===0?o`
|
|
1123
|
+
<div class="session-list session-list--empty">
|
|
1124
|
+
<div class="empty-state">
|
|
1125
|
+
<div class="empty-state__icon">${p("clock")}</div>
|
|
1126
|
+
<div class="empty-state__title">No cron jobs yet</div>
|
|
1127
|
+
<button class="btn btn-primary" @click=${this._openForm}>Create your first job</button>
|
|
1128
|
+
</div>
|
|
1129
|
+
</div>
|
|
1130
|
+
`:o`
|
|
1131
|
+
<div class="session-list__toolbar">
|
|
1132
|
+
<div class="session-list__count">${this._jobs.length} job${this._jobs.length!==1?"s":""}</div>
|
|
1133
|
+
</div>
|
|
1134
|
+
<div class="session-list__content">
|
|
1135
|
+
<table class="data-table">
|
|
1136
|
+
<thead>
|
|
1137
|
+
<tr>
|
|
1138
|
+
<th>${a("cron.name")}</th>
|
|
1139
|
+
<th>${a("cron.scheduleLabel")}</th>
|
|
1140
|
+
<th>${a("cron.nextRun")}</th>
|
|
1141
|
+
<th>${a("cron.status")}</th>
|
|
1142
|
+
<th>${a("cron.actions")}</th>
|
|
1143
|
+
</tr>
|
|
1144
|
+
</thead>
|
|
1145
|
+
<tbody>
|
|
1146
|
+
${this._jobs.map(e=>o`
|
|
1147
|
+
<tr>
|
|
1148
|
+
<td style="vertical-align: middle; text-align: center;">
|
|
1149
|
+
<button class="btn btn-link" @click=${()=>this._openDetail(e)}>
|
|
1150
|
+
${e.name||e.id}
|
|
1151
|
+
</button>
|
|
1152
|
+
</td>
|
|
1153
|
+
<td style="vertical-align: middle; text-align: center;"><code>${e.schedule}</code></td>
|
|
1154
|
+
<td style="vertical-align: middle; text-align: center;">${e.next_run?this._formatNextRun(e.next_run):"-"}</td>
|
|
1155
|
+
<td style="vertical-align: middle; text-align: center;">
|
|
1156
|
+
<label class="toggle">
|
|
1157
|
+
<input
|
|
1158
|
+
type="checkbox"
|
|
1159
|
+
?checked=${e.enabled}
|
|
1160
|
+
@change=${t=>this._toggleJob(e,t.target.checked)}
|
|
1161
|
+
/>
|
|
1162
|
+
<span class="toggle__slider"></span>
|
|
1163
|
+
</label>
|
|
1164
|
+
</td>
|
|
1165
|
+
<td style="vertical-align: middle; text-align: center;">
|
|
1166
|
+
<div class="action-buttons">
|
|
1167
|
+
<button class="btn btn-icon btn-secondary" title="Edit" @click=${()=>this._openForm(e)}>
|
|
1168
|
+
${p("edit")}
|
|
1169
|
+
</button>
|
|
1170
|
+
<button class="btn btn-icon btn-secondary" title="${a("cron.runNow")}" @click=${()=>this._showRunConfirm(e)}>
|
|
1171
|
+
${p("play")}
|
|
1172
|
+
</button>
|
|
1173
|
+
<button class="btn btn-icon btn-danger" title="${a("cron.delete")}" @click=${()=>this._showDeleteConfirm(e)}>
|
|
1174
|
+
${p("trash")}
|
|
1175
|
+
</button>
|
|
1176
|
+
</div>
|
|
1177
|
+
</td>
|
|
1178
|
+
</tr>
|
|
1179
|
+
`)}
|
|
1180
|
+
</tbody>
|
|
1181
|
+
</table>
|
|
1182
|
+
</div>
|
|
1183
|
+
`}
|
|
1184
|
+
</div>
|
|
1185
|
+
</div>
|
|
1186
|
+
|
|
1187
|
+
<!-- Add/Edit Job Form Modal -->
|
|
1188
|
+
${this._formOpen?o`
|
|
1189
|
+
<div class="modal-backdrop" @click=${this._closeForm}>
|
|
1190
|
+
<div class="modal modal--form" @click=${e=>e.stopPropagation()}>
|
|
1191
|
+
<div class="modal__header">
|
|
1192
|
+
<h2 class="modal__title">${this._formMode==="edit"?a("cron.editJob"):a("cron.addJob")}</h2>
|
|
1193
|
+
<button class="btn-icon" @click=${this._closeForm}>${p("x")}</button>
|
|
1194
|
+
</div>
|
|
1195
|
+
<div class="modal__content">
|
|
1196
|
+
<div class="form-field">
|
|
1197
|
+
<label class="form-field__label">${a("cron.name")}</label>
|
|
1198
|
+
<input
|
|
1199
|
+
type="text"
|
|
1200
|
+
class="form-field__input"
|
|
1201
|
+
.value=${this._formName??""}
|
|
1202
|
+
@input=${e=>this._formName=e.target.value}
|
|
1203
|
+
placeholder="${a("cron.namePlaceholder")??"My scheduled task"}"
|
|
1204
|
+
/>
|
|
1205
|
+
</div>
|
|
1206
|
+
<div class="form-field">
|
|
1207
|
+
<label class="form-field__label">${a("cron.schedule")}</label>
|
|
1208
|
+
<div style="display: flex; gap: 0.5rem; align-items: center;">
|
|
1209
|
+
<input
|
|
1210
|
+
type="text"
|
|
1211
|
+
class="form-field__input"
|
|
1212
|
+
style="flex: 2; min-width: 0;"
|
|
1213
|
+
.value=${this._formSchedule??"*/5 * * * *"}
|
|
1214
|
+
@input=${e=>this._formSchedule=e.target.value}
|
|
1215
|
+
placeholder="*/5 * * * *"
|
|
1216
|
+
/>
|
|
1217
|
+
<select
|
|
1218
|
+
class="form-field__select"
|
|
1219
|
+
style="flex: 1; min-width: 0;"
|
|
1220
|
+
.value=${this._formSchedule??"*/5 * * * *"}
|
|
1221
|
+
@change=${e=>{const t=e.target.value;t&&(this._formSchedule=t)}}
|
|
1222
|
+
>
|
|
1223
|
+
<option value="">${a("cron.schedulePresets.custom")}</option>
|
|
1224
|
+
<option value="*/1 * * * *">${a("cron.schedulePresets.everyMinute")}</option>
|
|
1225
|
+
<option value="*/5 * * * *">${a("cron.schedulePresets.every5Minutes")}</option>
|
|
1226
|
+
<option value="*/10 * * * *">${a("cron.schedulePresets.every10Minutes")}</option>
|
|
1227
|
+
<option value="*/15 * * * *">${a("cron.schedulePresets.every15Minutes")}</option>
|
|
1228
|
+
<option value="*/30 * * * *">${a("cron.schedulePresets.every30Minutes")}</option>
|
|
1229
|
+
<option value="0 * * * *">${a("cron.schedulePresets.everyHour")}</option>
|
|
1230
|
+
<option value="0 */2 * * *">${a("cron.schedulePresets.every2Hours")}</option>
|
|
1231
|
+
<option value="0 */4 * * *">${a("cron.schedulePresets.every4Hours")}</option>
|
|
1232
|
+
<option value="0 */6 * * *">${a("cron.schedulePresets.every6Hours")}</option>
|
|
1233
|
+
<option value="0 */12 * * *">${a("cron.schedulePresets.every12Hours")}</option>
|
|
1234
|
+
<option value="0 0 * * *">${a("cron.schedulePresets.everyDayMidnight")}</option>
|
|
1235
|
+
<option value="0 9 * * *">${a("cron.schedulePresets.everyDay9AM")}</option>
|
|
1236
|
+
<option value="0 21 * * *">${a("cron.schedulePresets.everyDay9PM")}</option>
|
|
1237
|
+
</select>
|
|
1238
|
+
</div>
|
|
1239
|
+
<p class="form-field__hint">
|
|
1240
|
+
${a("cron.scheduleHintPreset")}
|
|
1241
|
+
</p>
|
|
1242
|
+
</div>
|
|
1243
|
+
<div class="form-field">
|
|
1244
|
+
<label class="form-field__label">${a("cron.mode")}</label>
|
|
1245
|
+
<select
|
|
1246
|
+
class="form-field__select"
|
|
1247
|
+
.value=${this._formSessionTarget??"main"}
|
|
1248
|
+
@change=${e=>this._formSessionTarget=e.target.value}
|
|
1249
|
+
>
|
|
1250
|
+
<option value="main">${a("cron.modeDirectOption")||"Direct (send message directly)"}</option>
|
|
1251
|
+
<option value="isolated">${a("cron.modeAgentOption")||"AI Agent (process with AI then send)"}</option>
|
|
1252
|
+
</select>
|
|
1253
|
+
<p class="form-field__hint">
|
|
1254
|
+
${this._formSessionTarget==="main"?a("cron.modeDirect"):a("cron.modeAgent")}
|
|
1255
|
+
</p>
|
|
1256
|
+
</div>
|
|
1257
|
+
${this._formSessionTarget==="isolated"?o`
|
|
1258
|
+
<div class="form-field">
|
|
1259
|
+
<label class="form-field__label">${a("cron.model")}</label>
|
|
1260
|
+
<select
|
|
1261
|
+
class="form-field__select"
|
|
1262
|
+
.value=${this._formModel??""}
|
|
1263
|
+
@change=${e=>this._formModel=e.target.value}
|
|
1264
|
+
>
|
|
1265
|
+
${this._availableModels.length>0?this._availableModels.map(e=>o`
|
|
1266
|
+
<option value=${e.id}>${e.name} (${e.provider})</option>
|
|
1267
|
+
`):o`
|
|
1268
|
+
<option value="">${a("cron.noConfiguredModels")}</option>
|
|
1269
|
+
`}
|
|
1270
|
+
</select>
|
|
1271
|
+
</div>
|
|
1272
|
+
`:m}
|
|
1273
|
+
<div class="form-field">
|
|
1274
|
+
<label class="form-field__label">Channel</label>
|
|
1275
|
+
<select
|
|
1276
|
+
class="form-field__select"
|
|
1277
|
+
.value=${this._formChannel??"telegram"}
|
|
1278
|
+
@change=${e=>{this._formChannel=e.target.value,this._loadSessionChatIds(),this._formChatId=""}}
|
|
1279
|
+
>
|
|
1280
|
+
${this._channels.map(e=>o`
|
|
1281
|
+
<option value=${e.name} ?disabled=${!e.enabled}>
|
|
1282
|
+
${e.name} ${e.enabled?"":"(disabled)"}
|
|
1283
|
+
</option>
|
|
1284
|
+
`)}
|
|
1285
|
+
</select>
|
|
1286
|
+
</div>
|
|
1287
|
+
<div class="form-field">
|
|
1288
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
|
|
1289
|
+
<label class="form-field__label" style="margin: 0;">Chat ID *</label>
|
|
1290
|
+
<button
|
|
1291
|
+
type="button"
|
|
1292
|
+
class="btn btn-secondary btn-sm"
|
|
1293
|
+
@click=${()=>this._loadSessionChatIds()}
|
|
1294
|
+
title="Refresh chat list"
|
|
1295
|
+
style="padding: 0.25rem 0.5rem; font-size: 0.75rem;"
|
|
1296
|
+
>
|
|
1297
|
+
${p("refresh")} Refresh
|
|
1298
|
+
</button>
|
|
1299
|
+
</div>
|
|
1300
|
+
<div style="display: flex; gap: 0.5rem; align-items: center;">
|
|
1301
|
+
<input
|
|
1302
|
+
type="text"
|
|
1303
|
+
class="form-field__input"
|
|
1304
|
+
style="flex: 2; min-width: 0;"
|
|
1305
|
+
.value=${this._formChatId??""}
|
|
1306
|
+
@input=${e=>this._formChatId=e.target.value}
|
|
1307
|
+
placeholder="e.g., 123456789"
|
|
1308
|
+
/>
|
|
1309
|
+
<select
|
|
1310
|
+
class="form-field__select"
|
|
1311
|
+
style="flex: 1; min-width: 0;"
|
|
1312
|
+
.value=${this._formChatId??""}
|
|
1313
|
+
@change=${e=>{const t=e.target.value;t&&(this._formChatId=t)}}
|
|
1314
|
+
>
|
|
1315
|
+
<option value="">-- Select --</option>
|
|
1316
|
+
${this._sessionChatIds.length>0?this._sessionChatIds.map(e=>o`
|
|
1317
|
+
<option value=${e.chatId}>
|
|
1318
|
+
${e.channel}: ${e.chatId} (${this._formatLastActive(e.lastActive)})
|
|
1319
|
+
</option>
|
|
1320
|
+
`):o`
|
|
1321
|
+
<option value="" disabled>No recent chats</option>
|
|
1322
|
+
`}
|
|
1323
|
+
</select>
|
|
1324
|
+
</div>
|
|
1325
|
+
<p class="form-field__hint">
|
|
1326
|
+
${this._sessionChatIds.length>0?a("cron.enterManuallyOrSelect"):a("cron.noRecentChats")}
|
|
1327
|
+
</p>
|
|
1328
|
+
</div>
|
|
1329
|
+
<div class="form-field">
|
|
1330
|
+
<label class="form-field__label">${a("cron.message")}</label>
|
|
1331
|
+
<textarea
|
|
1332
|
+
class="form-field__textarea"
|
|
1333
|
+
.value=${this._formMessage??""}
|
|
1334
|
+
@input=${e=>this._formMessage=e.target.value}
|
|
1335
|
+
placeholder="${a("cron.messagePlaceholder")??"What should the assistant do?"}"
|
|
1336
|
+
rows="4"
|
|
1337
|
+
></textarea>
|
|
1338
|
+
</div>
|
|
1339
|
+
</div>
|
|
1340
|
+
<div class="modal__actions">
|
|
1341
|
+
<button class="btn btn-secondary" @click=${this._closeForm}>${a("common.cancel")}</button>
|
|
1342
|
+
<button
|
|
1343
|
+
class="btn btn-primary"
|
|
1344
|
+
@click=${this._submitForm}
|
|
1345
|
+
?disabled=${this._formSubmitting||!this._formSchedule||!this._formChatId||!this._formMessage}
|
|
1346
|
+
>
|
|
1347
|
+
${this._formSubmitting?a("common.loading"):this._formMode==="edit"?a("cron.save"):a("cron.create")}
|
|
1348
|
+
</button>
|
|
1349
|
+
</div>
|
|
1350
|
+
</div>
|
|
1351
|
+
</div>
|
|
1352
|
+
`:m}
|
|
1353
|
+
|
|
1354
|
+
<!-- Detail Drawer -->
|
|
1355
|
+
${this._detailOpen?o`
|
|
1356
|
+
<div class="drawer-backdrop" @click=${this._closeDetail}>
|
|
1357
|
+
<div class="drawer drawer--open" @click=${e=>e.stopPropagation()}>
|
|
1358
|
+
<div class="drawer-header">
|
|
1359
|
+
<div class="drawer-header__info">
|
|
1360
|
+
<div class="drawer-header__title">${this._detailJob?.name||this._detailJob?.id}</div>
|
|
1361
|
+
</div>
|
|
1362
|
+
<button class="btn-icon" @click=${this._closeDetail}>${p("x")}</button>
|
|
1363
|
+
</div>
|
|
1364
|
+
<div class="drawer-content ${this._detailLoading?"drawer-content--loading":""}">
|
|
1365
|
+
${this._detailLoading?o`
|
|
1366
|
+
<div class="spinner"></div>
|
|
1367
|
+
`:o`
|
|
1368
|
+
<div class="session-detail">
|
|
1369
|
+
<div class="session-detail__row">
|
|
1370
|
+
<span class="session-detail__label">${a("cron.scheduleLabel")}</span>
|
|
1371
|
+
<code>${this._detailJob?.schedule}</code>
|
|
1372
|
+
</div>
|
|
1373
|
+
<div class="session-detail__row">
|
|
1374
|
+
<span class="session-detail__label">${a("cron.messageLabel")}</span>
|
|
1375
|
+
<span>${this._detailJob?.message}</span>
|
|
1376
|
+
</div>
|
|
1377
|
+
<div class="session-detail__row">
|
|
1378
|
+
<span class="session-detail__label">${a("cron.status")}</span>
|
|
1379
|
+
<span>${this._detailJob?.enabled?a("cron.enabled"):a("cron.disabled")}</span>
|
|
1380
|
+
</div>
|
|
1381
|
+
<div class="session-detail__row">
|
|
1382
|
+
<span class="session-detail__label">${a("cron.nextRun")}</span>
|
|
1383
|
+
<span>${this._detailJob?.next_run?this._formatNextRun(this._detailJob.next_run):"N/A"}</span>
|
|
1384
|
+
</div>
|
|
1385
|
+
</div>
|
|
1386
|
+
`}
|
|
1387
|
+
</div>
|
|
1388
|
+
</div>
|
|
1389
|
+
</div>
|
|
1390
|
+
`:m}
|
|
1391
|
+
|
|
1392
|
+
<!-- Confirm Dialog -->
|
|
1393
|
+
<confirm-dialog
|
|
1394
|
+
.open=${this._confirmOpen}
|
|
1395
|
+
.title=${this._confirmTitle}
|
|
1396
|
+
.message=${this._confirmMessage}
|
|
1397
|
+
.confirmText=${this._confirmAction==="delete"?a("cron.delete"):a("cron.runNow")}
|
|
1398
|
+
.cancelText=${a("common.cancel")}
|
|
1399
|
+
.type=${this._confirmAction==="delete"?"danger":"warning"}
|
|
1400
|
+
@confirm=${this._handleConfirm}
|
|
1401
|
+
></confirm-dialog>
|
|
1402
|
+
`}_formatNextRun(e){const t=typeof e=="string"?new Date(e):e,s=new Date,i=t.getTime()-s.getTime();if(i<0)return a("cron.timeLabels.overdue");if(i<6e4)return a("cron.timeLabels.lessThanMinute");if(i<36e5){const n=Math.floor(i/6e4);return a("cron.timeLabels.minutes",{count:n})}if(i<864e5){const n=Math.floor(i/36e5);return a("cron.timeLabels.hours",{count:n})}return t.toLocaleString()}_formatLastActive(e){const t=new Date(e),i=new Date().getTime()-t.getTime();if(i<0||i<6e4)return a("cron.lastActiveLabels.justNow");if(i<36e5){const n=Math.floor(i/6e4);return a("cron.lastActiveLabels.minutesAgo",{count:n})}if(i<864e5){const n=Math.floor(i/36e5);return a("cron.lastActiveLabels.hoursAgo",{count:n})}if(i<6048e5){const n=Math.floor(i/864e5);return a("cron.lastActiveLabels.daysAgo",{count:n})}return t.toLocaleDateString()}_formatTime(e){return new Date(e).toLocaleString()}};v([u({attribute:!1})],_.prototype,"config",2);v([c()],_.prototype,"_jobs",2);v([c()],_.prototype,"_metrics",2);v([c()],_.prototype,"_channels",2);v([c()],_.prototype,"_availableModels",2);v([c()],_.prototype,"_defaultModel",2);v([c()],_.prototype,"_sessionChatIds",2);v([c()],_.prototype,"_loading",2);v([c()],_.prototype,"_error",2);v([c()],_.prototype,"_formOpen",2);v([c()],_.prototype,"_formMode",2);v([c()],_.prototype,"_formJobId",2);v([c()],_.prototype,"_formName",2);v([c()],_.prototype,"_formSchedule",2);v([c()],_.prototype,"_formChannel",2);v([c()],_.prototype,"_formChatId",2);v([c()],_.prototype,"_formMessage",2);v([c()],_.prototype,"_formSessionTarget",2);v([c()],_.prototype,"_formModel",2);v([c()],_.prototype,"_formSubmitting",2);v([c()],_.prototype,"_detailOpen",2);v([c()],_.prototype,"_detailJob",2);v([c()],_.prototype,"_detailHistory",2);v([c()],_.prototype,"_detailLoading",2);v([c()],_.prototype,"_confirmOpen",2);v([c()],_.prototype,"_confirmTitle",2);v([c()],_.prototype,"_confirmMessage",2);v([c()],_.prototype,"_confirmJobId",2);v([c()],_.prototype,"_confirmAction",2);_=v([k("cron-manager")],_);const ti=["trace","debug","info","warn","error","fatal"],fe={trace:"#9ca3af",debug:"#6b7280",info:"#3b82f6",warn:"#f59e0b",error:"#ef4444",fatal:"#dc2626"};class si{constructor(t,s){this.baseUrl=t.replace(/\/$/,""),this.token=s}async request(t,s,i){const n={"Content-Type":"application/json"};this.token&&(n.Authorization=`Bearer ${this.token}`);const r=await fetch(`${this.baseUrl}${s}`,{method:t,headers:n,body:i?JSON.stringify(i):void 0});if(!r.ok){const l=await r.json().catch(()=>({error:"Request failed"}));throw new Error(l.error||`HTTP ${r.status}`)}return r.json()}async queryLogs(t){const s=new URLSearchParams;t?.level?.length&&s.set("level",t.level.join(",")),t?.from&&s.set("from",t.from),t?.to&&s.set("to",t.to),t?.q&&s.set("q",t.q),t?.module&&s.set("module",t.module),t?.limit&&s.set("limit",String(t.limit)),t?.offset&&s.set("offset",String(t.offset));const i=s.toString(),n=`/api/logs${i?`?${i}`:""}`;return await this.request("GET",n)}async getLogFiles(){return(await this.request("GET","/api/logs/files")).files||[]}async getLogStats(){return await this.request("GET","/api/logs/stats")}async getLogLevels(){return(await this.request("GET","/api/logs/levels")).levels||[]}async getLogModules(){return(await this.request("GET","/api/logs/modules")).modules||[]}async getLogDir(){return(await this.request("GET","/api/logs/dir")).dir}}var ii=Object.defineProperty,ni=Object.getOwnPropertyDescriptor,C=(e,t,s,i)=>{for(var n=i>1?void 0:i?ni(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&ii(t,s,n),n};let $=class extends y{constructor(){super(...arguments),this._logs=[],this._loading=!1,this._hasMore=!1,this._files=[],this._modules=[],this._showFilesPanel=!1,this._selectedLevels=new Set,this._searchQuery="",this._selectedModule="",this._dateFrom="",this._dateTo="",this._offset=0,this._error=null,this._selectedLog=null,this._autoRefresh=!1,this._limit=50,this._initialized=!1,this._debouncedSearch=this._debounce(()=>{this._loadLogs(!0)},300)}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this._tryInitialize()}willUpdate(e){super.willUpdate(e),e.has("config")&&this._tryInitialize()}disconnectedCallback(){super.disconnectedCallback(),this._stopAutoRefresh()}firstUpdated(){this._tryInitialize()}_tryInitialize(){if(this._initialized||!this.config?.url)return;const e=this.config.url.replace(/\/+$/,"");this._api=new si(e,this.config.token),this._initialized=!0,this._loadLogs(),this._loadFiles(),this._loadModules()}async _loadLogs(e=!1){if(!this._loading){this._loading=!0,this._error=null,e&&(this._offset=0,this._logs=[]);try{const t={level:this._selectedLevels.size>0?Array.from(this._selectedLevels):void 0,from:this._dateFrom||void 0,to:this._dateTo||void 0,q:this._searchQuery||void 0,module:this._selectedModule||void 0,limit:this._limit,offset:this._offset},s=await this._api.queryLogs(t);e?this._logs=s.logs:this._logs=[...this._logs,...s.logs],console.log("[LogManager] Total logs in state:",this._logs.length),this._hasMore=s.logs.length===this._limit,this._offset=this._offset+s.logs.length}catch(t){this._error=t instanceof Error?t.message:"Failed to load logs",console.error("[LogManager] Load error:",t)}finally{this._loading=!1}}}async _loadFiles(){try{this._files=await this._api.getLogFiles()}catch(e){console.error("[LogManager] Files error:",e)}}async _loadModules(){try{this._modules=await this._api.getLogModules()}catch(e){console.error("[LogManager] Modules error:",e)}}_toggleLevel(e){this._selectedLevels.has(e)?this._selectedLevels.delete(e):this._selectedLevels.add(e),this._selectedLevels=new Set(this._selectedLevels),this._loadLogs(!0)}_handleSearch(e){const t=e.target;this._searchQuery=t.value,this._debouncedSearch()}_debounce(e,t){let s;return()=>{clearTimeout(s),s=setTimeout(e,t)}}_handleModuleChange(e){const t=e.target;this._selectedModule=t.value,this._loadLogs(!0)}_handleDateFromChange(e){const t=e.target;this._dateFrom=t.value,this._loadLogs(!0)}_handleDateToChange(e){const t=e.target;this._dateTo=t.value,this._loadLogs(!0)}_clearFilters(){this._selectedLevels.clear(),this._selectedLevels=new Set,this._searchQuery="",this._selectedModule="",this._dateFrom="",this._dateTo="",this._loadLogs(!0)}_selectLog(e){this._selectedLog=e}_closeDetail(){this._selectedLog=null}_toggleAutoRefresh(){this._autoRefresh=!this._autoRefresh,this._autoRefresh?this._startAutoRefresh():this._stopAutoRefresh()}_startAutoRefresh(){this._refreshInterval=window.setInterval(()=>{this._loadLogs(!0)},5e3)}_stopAutoRefresh(){this._refreshInterval&&(clearInterval(this._refreshInterval),this._refreshInterval=void 0)}_handleLoadMore(){this._loadLogs()}_formatTimestamp(e){try{return new Date(e).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return e}}_formatFileSize(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}render(){return o`
|
|
1403
|
+
<div class="log-manager">
|
|
1404
|
+
${this._renderHeader()}
|
|
1405
|
+
<div class="log-manager__main">
|
|
1406
|
+
${this._renderFilters()}
|
|
1407
|
+
${this._renderLogTable()}
|
|
1408
|
+
${this._renderFilesPanel()}
|
|
1409
|
+
</div>
|
|
1410
|
+
${this._error?o`<div class="error-banner">${this._error}</div>`:""}
|
|
1411
|
+
</div>
|
|
1412
|
+
|
|
1413
|
+
${this._selectedLog?this._renderDetailDrawer():""}
|
|
1414
|
+
`}_renderHeader(){return o`
|
|
1415
|
+
<div class="log-manager__header">
|
|
1416
|
+
<div class="log-manager__title">
|
|
1417
|
+
<span class="title-icon">${p("fileText")}</span>
|
|
1418
|
+
<div class="title-text">
|
|
1419
|
+
<h1>${a("logs.title")}</h1>
|
|
1420
|
+
<span class="title-subtitle">System logs and diagnostics</span>
|
|
1421
|
+
</div>
|
|
1422
|
+
</div>
|
|
1423
|
+
<div class="log-manager__actions">
|
|
1424
|
+
<button
|
|
1425
|
+
class="btn-icon"
|
|
1426
|
+
@click=${this._toggleFilesPanel}
|
|
1427
|
+
title="Toggle log files"
|
|
1428
|
+
>
|
|
1429
|
+
${p("folder")}
|
|
1430
|
+
${this._files.length>0?o`<span class="badge">${this._files.length}</span>`:""}
|
|
1431
|
+
</button>
|
|
1432
|
+
<button
|
|
1433
|
+
class="btn-icon ${this._autoRefresh?"btn-icon--active":""}"
|
|
1434
|
+
@click=${this._toggleAutoRefresh}
|
|
1435
|
+
title=${this._autoRefresh?a("logs.pause"):a("logs.autoRefresh")}
|
|
1436
|
+
>
|
|
1437
|
+
${p(this._autoRefresh?"pause":"play")}
|
|
1438
|
+
</button>
|
|
1439
|
+
<button
|
|
1440
|
+
class="btn-icon"
|
|
1441
|
+
@click=${()=>this._loadLogs(!0)}
|
|
1442
|
+
title=${a("logs.refresh")}
|
|
1443
|
+
>
|
|
1444
|
+
${p("refreshCw")}
|
|
1445
|
+
</button>
|
|
1446
|
+
</div>
|
|
1447
|
+
</div>
|
|
1448
|
+
`}_renderFilters(){return o`
|
|
1449
|
+
<div class="log-manager__filters">
|
|
1450
|
+
<div class="filter-group">
|
|
1451
|
+
<label class="filter-label">${a("logs.level")}</label>
|
|
1452
|
+
<div class="level-filters">
|
|
1453
|
+
${ti.map(e=>o`
|
|
1454
|
+
<button
|
|
1455
|
+
class="level-badge ${this._selectedLevels.has(e)?"level-badge--active":""}"
|
|
1456
|
+
style="--level-color: ${fe[e]}"
|
|
1457
|
+
@click=${()=>this._toggleLevel(e)}
|
|
1458
|
+
>
|
|
1459
|
+
${e}
|
|
1460
|
+
</button>
|
|
1461
|
+
`)}
|
|
1462
|
+
</div>
|
|
1463
|
+
</div>
|
|
1464
|
+
|
|
1465
|
+
<div class="filter-group">
|
|
1466
|
+
<label class="filter-label">${a("logs.search")}</label>
|
|
1467
|
+
<div class="search-box">
|
|
1468
|
+
${p("search")}
|
|
1469
|
+
<input
|
|
1470
|
+
type="text"
|
|
1471
|
+
placeholder="${a("logs.searchPlaceholder")}"
|
|
1472
|
+
.value=${this._searchQuery}
|
|
1473
|
+
@input=${this._handleSearch}
|
|
1474
|
+
/>
|
|
1475
|
+
</div>
|
|
1476
|
+
</div>
|
|
1477
|
+
|
|
1478
|
+
<div class="filter-row">
|
|
1479
|
+
<div class="filter-group">
|
|
1480
|
+
<label class="filter-label">Module</label>
|
|
1481
|
+
<select @change=${this._handleModuleChange}>
|
|
1482
|
+
<option value="">All modules</option>
|
|
1483
|
+
${this._modules.map(e=>o`<option value="${e}">${e}</option>`)}
|
|
1484
|
+
</select>
|
|
1485
|
+
</div>
|
|
1486
|
+
|
|
1487
|
+
<div class="filter-group">
|
|
1488
|
+
<label class="filter-label">From</label>
|
|
1489
|
+
<input
|
|
1490
|
+
type="datetime-local"
|
|
1491
|
+
.value=${this._dateFrom}
|
|
1492
|
+
@input=${this._handleDateFromChange}
|
|
1493
|
+
/>
|
|
1494
|
+
</div>
|
|
1495
|
+
|
|
1496
|
+
<div class="filter-group">
|
|
1497
|
+
<label class="filter-label">To</label>
|
|
1498
|
+
<input
|
|
1499
|
+
type="datetime-local"
|
|
1500
|
+
.value=${this._dateTo}
|
|
1501
|
+
@input=${this._handleDateToChange}
|
|
1502
|
+
/>
|
|
1503
|
+
</div>
|
|
1504
|
+
|
|
1505
|
+
<button class="btn btn-ghost" @click=${this._clearFilters}>
|
|
1506
|
+
${p("x")}
|
|
1507
|
+
Clear
|
|
1508
|
+
</button>
|
|
1509
|
+
</div>
|
|
1510
|
+
</div>
|
|
1511
|
+
`}_renderLogTable(){return this._loading&&this._logs.length===0?this._renderLoading():this._logs.length===0?o`
|
|
1512
|
+
<div class="log-manager__empty">
|
|
1513
|
+
<div class="empty-state">
|
|
1514
|
+
<div class="empty-state__icon">${p("fileText")}</div>
|
|
1515
|
+
<div class="empty-state__title">${a("logs.noLogs")}</div>
|
|
1516
|
+
<div class="empty-state__description">
|
|
1517
|
+
${a("logs.noLogsDescription")}
|
|
1518
|
+
</div>
|
|
1519
|
+
</div>
|
|
1520
|
+
</div>
|
|
1521
|
+
`:o`
|
|
1522
|
+
<div class="log-table-container">
|
|
1523
|
+
<table class="log-table">
|
|
1524
|
+
<thead>
|
|
1525
|
+
<tr>
|
|
1526
|
+
<th>${a("logs.time")}</th>
|
|
1527
|
+
<th>${a("logs.level")}</th>
|
|
1528
|
+
<th>${a("logs.module")}</th>
|
|
1529
|
+
<th>${a("logs.message")}</th>
|
|
1530
|
+
</tr>
|
|
1531
|
+
</thead>
|
|
1532
|
+
<tbody>
|
|
1533
|
+
${this._logs.length===0?o`
|
|
1534
|
+
<tr>
|
|
1535
|
+
<td colspan="4" style="padding: 2rem; text-align: center; color: var(--text-muted);">
|
|
1536
|
+
No logs to display
|
|
1537
|
+
</td>
|
|
1538
|
+
</tr>
|
|
1539
|
+
`:this._logs.map(e=>o`
|
|
1540
|
+
<tr class="log-row log-row--${e.level||"info"}" @click=${()=>this._selectLog(e)}>
|
|
1541
|
+
<td class="log-cell log-cell--time">${this._formatTimestamp(e.timestamp)}</td>
|
|
1542
|
+
<td class="log-cell log-cell--level">
|
|
1543
|
+
<span
|
|
1544
|
+
class="level-badge level-badge--small"
|
|
1545
|
+
style="--level-color: ${fe[e.level]||fe.info}"
|
|
1546
|
+
>
|
|
1547
|
+
${e.level||"info"}
|
|
1548
|
+
</span>
|
|
1549
|
+
</td>
|
|
1550
|
+
<td class="log-cell log-cell--module">${e.module||e.prefix||e.service||"-"}</td>
|
|
1551
|
+
<td class="log-cell log-cell--message">${e.message||JSON.stringify(e)}</td>
|
|
1552
|
+
</tr>
|
|
1553
|
+
`)}
|
|
1554
|
+
</tbody>
|
|
1555
|
+
</table>
|
|
1556
|
+
|
|
1557
|
+
${this._hasMore?o`
|
|
1558
|
+
<div class="log-table__load-more">
|
|
1559
|
+
<button class="btn btn-secondary" @click=${this._handleLoadMore} ?disabled=${this._loading}>
|
|
1560
|
+
${this._loading?o`<span class="spinner"></span>`:p("chevronDown")}
|
|
1561
|
+
Load More
|
|
1562
|
+
</button>
|
|
1563
|
+
</div>
|
|
1564
|
+
`:""}
|
|
1565
|
+
</div>
|
|
1566
|
+
`}_toggleFilesPanel(){this._showFilesPanel=!this._showFilesPanel}_renderFilesPanel(){return o`
|
|
1567
|
+
${this._showFilesPanel?o`
|
|
1568
|
+
<div class="drawer-overlay" @click=${this._toggleFilesPanel}></div>
|
|
1569
|
+
`:""}
|
|
1570
|
+
<div class="files-panel ${this._showFilesPanel?"files-panel--open":""}">
|
|
1571
|
+
<div class="files-panel__header">
|
|
1572
|
+
<span class="files-panel__title">
|
|
1573
|
+
${p("folder")}
|
|
1574
|
+
Log Files
|
|
1575
|
+
</span>
|
|
1576
|
+
<button class="btn btn-icon" @click=${this._toggleFilesPanel}>
|
|
1577
|
+
${p("x")}
|
|
1578
|
+
</button>
|
|
1579
|
+
</div>
|
|
1580
|
+
<div class="files-panel__content">
|
|
1581
|
+
${this._files.length===0?o`
|
|
1582
|
+
<div class="files-panel__empty">No log files found</div>
|
|
1583
|
+
`:o`
|
|
1584
|
+
<div class="file-list">
|
|
1585
|
+
${this._files.map(e=>o`
|
|
1586
|
+
<div class="file-item">
|
|
1587
|
+
<span class="file-name">${p("file")}${e.name}</span>
|
|
1588
|
+
<span class="file-meta">
|
|
1589
|
+
<span class="file-size">${this._formatFileSize(e.size)}</span>
|
|
1590
|
+
<span class="file-time">${this._formatTimestamp(e.modified)}</span>
|
|
1591
|
+
</span>
|
|
1592
|
+
</div>
|
|
1593
|
+
`)}
|
|
1594
|
+
</div>
|
|
1595
|
+
`}
|
|
1596
|
+
</div>
|
|
1597
|
+
</div>
|
|
1598
|
+
`}_renderDetailDrawer(){if(!this._selectedLog)return"";const e=this._selectedLog;return o`
|
|
1599
|
+
<div class="drawer-overlay" @click=${this._closeDetail}></div>
|
|
1600
|
+
<div class="drawer drawer--right">
|
|
1601
|
+
<div class="drawer-header">
|
|
1602
|
+
<h3 class="drawer-header__title">${a("logs.details")}</h3>
|
|
1603
|
+
<button class="btn btn-icon" @click=${this._closeDetail}>${p("x")}</button>
|
|
1604
|
+
</div>
|
|
1605
|
+
<div class="drawer__content">
|
|
1606
|
+
<div class="log-detail">
|
|
1607
|
+
<div class="log-detail__field">
|
|
1608
|
+
<label>${a("logs.time")}</label>
|
|
1609
|
+
<code>${e.timestamp}</code>
|
|
1610
|
+
</div>
|
|
1611
|
+
<div class="log-detail__field">
|
|
1612
|
+
<label>${a("logs.level")}</label>
|
|
1613
|
+
<span
|
|
1614
|
+
class="level-badge"
|
|
1615
|
+
style="--level-color: ${fe[e.level]}"
|
|
1616
|
+
>
|
|
1617
|
+
${e.level}
|
|
1618
|
+
</span>
|
|
1619
|
+
</div>
|
|
1620
|
+
<div class="log-detail__field">
|
|
1621
|
+
<label>${a("logs.module")}</label>
|
|
1622
|
+
<code>${e.module}</code>
|
|
1623
|
+
</div>
|
|
1624
|
+
<div class="log-detail__field">
|
|
1625
|
+
<label>${a("logs.message")}</label>
|
|
1626
|
+
<pre class="log-detail__message">${e.message}</pre>
|
|
1627
|
+
</div>
|
|
1628
|
+
${e.meta?o`
|
|
1629
|
+
<div class="log-detail__field">
|
|
1630
|
+
<label>Metadata</label>
|
|
1631
|
+
<pre class="log-detail__meta">${JSON.stringify(e.meta,null,2)}</pre>
|
|
1632
|
+
</div>
|
|
1633
|
+
`:""}
|
|
1634
|
+
</div>
|
|
1635
|
+
</div>
|
|
1636
|
+
</div>
|
|
1637
|
+
`}_renderLoading(){return o`
|
|
1638
|
+
<div class="log-manager__loading">
|
|
1639
|
+
<div class="skeleton-table">
|
|
1640
|
+
${Array.from({length:10}).map(()=>o`
|
|
1641
|
+
<div class="skeleton-row">
|
|
1642
|
+
<div class="skeleton skeleton--time"></div>
|
|
1643
|
+
<div class="skeleton skeleton--level"></div>
|
|
1644
|
+
<div class="skeleton skeleton--module"></div>
|
|
1645
|
+
<div class="skeleton skeleton--message"></div>
|
|
1646
|
+
</div>
|
|
1647
|
+
`)}
|
|
1648
|
+
</div>
|
|
1649
|
+
</div>
|
|
1650
|
+
`}};C([u({attribute:!1})],$.prototype,"config",2);C([c()],$.prototype,"_logs",2);C([c()],$.prototype,"_loading",2);C([c()],$.prototype,"_hasMore",2);C([c()],$.prototype,"_files",2);C([c()],$.prototype,"_modules",2);C([c()],$.prototype,"_showFilesPanel",2);C([c()],$.prototype,"_selectedLevels",2);C([c()],$.prototype,"_searchQuery",2);C([c()],$.prototype,"_selectedModule",2);C([c()],$.prototype,"_dateFrom",2);C([c()],$.prototype,"_dateTo",2);C([c()],$.prototype,"_offset",2);C([c()],$.prototype,"_error",2);C([c()],$.prototype,"_selectedLog",2);C([c()],$.prototype,"_autoRefresh",2);C([c()],$.prototype,"_refreshInterval",2);$=C([k("log-manager")],$);var oi=Object.defineProperty,ri=Object.getOwnPropertyDescriptor,D=(e,t,s,i)=>{for(var n=i>1?void 0:i?ri(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&oi(t,s,n),n};let P=class extends y{constructor(){super(...arguments),this._activeSection="agent",this._loading=!1,this._saving=!1,this._dirtyFields=new Set,this._errors=new Map,this._saveSuccess=!1,this._models=[],this._values={model:"anthropic/claude-sonnet-4-5",maxTokens:8192,temperature:.7,maxToolIterations:20,telegramEnabled:!1,telegramToken:"",telegramApiRoot:"",telegramDebug:!1,telegramAllowFrom:"",whatsappEnabled:!1,whatsappBridgeUrl:"ws://localhost:3001",whatsappAllowFrom:"",heartbeatEnabled:!0,heartbeatIntervalMs:6e4,openaiApiKey:"",anthropicApiKey:"",googleApiKey:"",qwenApiKey:"",kimiApiKey:"",minimaxApiKey:"",deepseekApiKey:"",grokApiKey:"",openrouterApiKey:"",workspace:"",theme:"system"},this._initialized=!1}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this._tryInitialize()}willUpdate(e){super.willUpdate(e),e.has("config")&&this._tryInitialize()}_tryInitialize(){this.config?.url&&this._loadSettings()}get _sections(){const e=this._models.map(t=>({value:t.id,label:`${t.provider}/${t.name}`}));return[{id:"agent",title:a("settings.sections.agent"),icon:"bot",fields:[{key:"model",label:a("settings.fields.model"),type:"select",description:a("settings.descriptionsFields.model"),options:e},{key:"workspace",label:a("settings.fields.workspace"),type:"text",description:a("settings.descriptionsFields.workspace"),placeholder:a("settings.placeholders.workspace")},{key:"maxTokens",label:a("settings.fields.maxTokens"),type:"number",description:a("settings.descriptionsFields.maxTokens"),validation:{min:256,max:128e3}},{key:"temperature",label:a("settings.fields.temperature"),type:"number",description:a("settings.descriptionsFields.temperature"),validation:{min:0,max:2}},{key:"maxToolIterations",label:a("settings.fields.maxToolIterations"),type:"number",description:a("settings.descriptionsFields.maxToolIterations"),validation:{min:1,max:100}}]},{id:"providers",title:a("settings.sections.providers"),icon:"cloud",fields:[{key:"openaiApiKey",label:a("settings.fields.openaiApiKey"),type:"password",description:a("settings.descriptionsFields.openaiApiKey"),placeholder:a("settings.placeholders.openaiApiKey")},{key:"anthropicApiKey",label:a("settings.fields.anthropicApiKey"),type:"password",description:a("settings.descriptionsFields.anthropicApiKey"),placeholder:a("settings.placeholders.anthropicApiKey")},{key:"googleApiKey",label:a("settings.fields.googleApiKey"),type:"password",description:a("settings.descriptionsFields.googleApiKey"),placeholder:a("settings.placeholders.googleApiKey")},{key:"qwenApiKey",label:a("settings.fields.qwenApiKey"),type:"password",description:a("settings.descriptionsFields.qwenApiKey"),placeholder:a("settings.placeholders.qwenApiKey")},{key:"kimiApiKey",label:a("settings.fields.kimiApiKey"),type:"password",description:a("settings.descriptionsFields.kimiApiKey"),placeholder:a("settings.placeholders.kimiApiKey")},{key:"minimaxApiKey",label:a("settings.fields.minimaxApiKey"),type:"password",description:a("settings.descriptionsFields.minimaxApiKey"),placeholder:a("settings.placeholders.minimaxApiKey")},{key:"deepseekApiKey",label:a("settings.fields.deepseekApiKey"),type:"password",description:a("settings.descriptionsFields.deepseekApiKey"),placeholder:a("settings.placeholders.deepseekApiKey")},{key:"openrouterApiKey",label:a("settings.fields.openrouterApiKey"),type:"password",description:a("settings.descriptionsFields.openrouterApiKey"),placeholder:a("settings.placeholders.openrouterApiKey")}]},{id:"channels",title:a("settings.sections.channels"),icon:"plug",fields:[{key:"telegramEnabled",label:a("settings.fields.telegramEnabled"),type:"boolean",description:a("settings.descriptionsFields.telegramEnabled")},...this._values.telegramEnabled?[{key:"telegramToken",label:a("settings.fields.telegramToken"),type:"password",description:a("settings.descriptionsFields.telegramToken"),placeholder:a("settings.placeholders.telegramToken")},{key:"telegramApiRoot",label:a("settings.fields.telegramApiRoot"),type:"text",description:a("settings.descriptionsFields.telegramApiRoot"),placeholder:a("settings.placeholders.telegramApiRoot")},{key:"telegramAllowFrom",label:a("settings.fields.telegramAllowFrom"),type:"text",description:a("settings.descriptionsFields.telegramAllowFrom"),placeholder:a("settings.placeholders.telegramAllowFrom")},{key:"telegramDebug",label:a("settings.fields.telegramDebug"),type:"boolean",description:a("settings.descriptionsFields.telegramDebug")}]:[],{key:"whatsappEnabled",label:a("settings.fields.whatsappEnabled"),type:"boolean",description:a("settings.descriptionsFields.whatsappEnabled")},...this._values.whatsappEnabled?[{key:"whatsappBridgeUrl",label:a("settings.fields.whatsappBridgeUrl"),type:"text",description:a("settings.descriptionsFields.whatsappBridgeUrl"),placeholder:a("settings.placeholders.whatsappBridgeUrl")},{key:"whatsappAllowFrom",label:a("settings.fields.whatsappAllowFrom"),type:"text",description:a("settings.descriptionsFields.whatsappAllowFrom"),placeholder:a("settings.placeholders.whatsappAllowFrom")}]:[]]},{id:"gateway",title:a("settings.sections.gateway"),icon:"globe",fields:[{key:"heartbeatEnabled",label:a("settings.fields.heartbeatEnabled"),type:"boolean",description:a("settings.descriptionsFields.heartbeatEnabled")},{key:"heartbeatIntervalMs",label:a("settings.fields.heartbeatIntervalMs"),type:"number",description:a("settings.descriptionsFields.heartbeatIntervalMs"),validation:{min:1e3,max:6e5}}]}]}async _loadSettings(){if(!this.config?.url)return;this._loading=!0;const{url:e,token:t}=this.config;try{await this._loadModels();const s=await fetch(`${e}/api/config`,{headers:t?{Authorization:`Bearer ${t}`}:{}});if(s.ok){const n=(await s.json()).payload?.config;if(n){let r=n.agents?.defaults?.model;r&&typeof r=="object"&&(r=r.primary||""),this._values={...this._values,model:r||"anthropic/claude-sonnet-4-5",workspace:n.agents?.defaults?.workspace||"",maxTokens:n.agents?.defaults?.maxTokens||8192,temperature:n.agents?.defaults?.temperature??.7,maxToolIterations:n.agents?.defaults?.maxToolIterations||20,openaiApiKey:n.providers?.openai?.apiKey||"",anthropicApiKey:n.providers?.anthropic?.apiKey||"",googleApiKey:n.providers?.google?.apiKey||"",qwenApiKey:n.providers?.qwen?.apiKey||"",kimiApiKey:n.providers?.kimi?.apiKey||"",minimaxApiKey:n.providers?.minimax?.apiKey||"",deepseekApiKey:n.providers?.deepseek?.apiKey||"",openrouterApiKey:n.providers?.openrouter?.apiKey||"",telegramEnabled:n.channels?.telegram?.enabled||!1,telegramToken:n.channels?.telegram?.token||"",telegramApiRoot:n.channels?.telegram?.apiRoot||"",telegramDebug:n.channels?.telegram?.debug||!1,telegramAllowFrom:(n.channels?.telegram?.allowFrom||[]).join(", "),whatsappEnabled:n.channels?.whatsapp?.enabled||!1,whatsappBridgeUrl:n.channels?.whatsapp?.bridgeUrl||"ws://localhost:3001",whatsappAllowFrom:(n.channels?.whatsapp?.allowFrom||[]).join(", "),heartbeatEnabled:n.gateway?.heartbeat?.enabled??!0,heartbeatIntervalMs:n.gateway?.heartbeat?.intervalMs||6e4}}}}catch(s){console.error("Failed to load settings:",s)}finally{this._loading=!1}}async _loadModels(){if(this.config?.url)try{const{url:e,token:t}=this.config,s=await fetch(`${e}/api/models`,{headers:t?{Authorization:`Bearer ${t}`}:{}});if(s.ok){const i=await s.json();i.payload?.models&&(this._models=i.payload.models)}}catch(e){console.error("Failed to load models:",e)}}async _saveSettings(){if(!this.config?.url||this._errors.size>0)return;this._saving=!0,this._saveSuccess=!1;const{url:e,token:t}=this.config,s={};(this._dirtyFields.has("model")||this._dirtyFields.has("maxTokens")||this._dirtyFields.has("temperature")||this._dirtyFields.has("maxToolIterations")||this._dirtyFields.has("workspace"))&&(s.agents={defaults:{}},this._dirtyFields.has("model")&&(s.agents.defaults.model=this._values.model),this._dirtyFields.has("workspace")&&(s.agents.defaults.workspace=this._values.workspace),this._dirtyFields.has("maxTokens")&&(s.agents.defaults.maxTokens=Number(this._values.maxTokens)),this._dirtyFields.has("temperature")&&(s.agents.defaults.temperature=Number(this._values.temperature)),this._dirtyFields.has("maxToolIterations")&&(s.agents.defaults.maxToolIterations=Number(this._values.maxToolIterations))),["openaiApiKey","anthropicApiKey","googleApiKey","qwenApiKey","kimiApiKey","minimaxApiKey","deepseekApiKey","openrouterApiKey"].filter(r=>this._dirtyFields.has(r)).length>0&&(s.providers={},this._dirtyFields.has("openaiApiKey")&&(s.providers.openai={apiKey:this._values.openaiApiKey}),this._dirtyFields.has("anthropicApiKey")&&(s.providers.anthropic={apiKey:this._values.anthropicApiKey}),this._dirtyFields.has("googleApiKey")&&(s.providers.google={apiKey:this._values.googleApiKey}),this._dirtyFields.has("qwenApiKey")&&(s.providers.qwen={apiKey:this._values.qwenApiKey}),this._dirtyFields.has("kimiApiKey")&&(s.providers.kimi={apiKey:this._values.kimiApiKey}),this._dirtyFields.has("minimaxApiKey")&&(s.providers.minimax={apiKey:this._values.minimaxApiKey}),this._dirtyFields.has("deepseekApiKey")&&(s.providers.deepseek={apiKey:this._values.deepseekApiKey}),this._dirtyFields.has("openrouterApiKey")&&(s.providers.openrouter={apiKey:this._values.openrouterApiKey})),(this._dirtyFields.has("telegramEnabled")||this._dirtyFields.has("whatsappEnabled")||this._dirtyFields.has("telegramToken")||this._dirtyFields.has("telegramApiRoot")||this._dirtyFields.has("telegramDebug")||this._dirtyFields.has("telegramAllowFrom")||this._dirtyFields.has("whatsappBridgeUrl")||this._dirtyFields.has("whatsappAllowFrom"))&&(s.channels={},(this._dirtyFields.has("telegramEnabled")||this._dirtyFields.has("telegramToken")||this._dirtyFields.has("telegramApiRoot")||this._dirtyFields.has("telegramDebug")||this._dirtyFields.has("telegramAllowFrom"))&&(s.channels={...s.channels,telegram:{}},this._dirtyFields.has("telegramEnabled")&&(s.channels.telegram.enabled=!!this._values.telegramEnabled),this._dirtyFields.has("telegramToken")&&(s.channels.telegram.token=this._values.telegramToken),this._dirtyFields.has("telegramApiRoot")&&(s.channels.telegram.apiRoot=this._values.telegramApiRoot||void 0),this._dirtyFields.has("telegramDebug")&&(s.channels.telegram.debug=!!this._values.telegramDebug),this._dirtyFields.has("telegramAllowFrom")&&(s.channels.telegram.allowFrom=this._values.telegramAllowFrom?this._values.telegramAllowFrom.split(",").map(r=>r.trim()).filter(r=>r):[])),(this._dirtyFields.has("whatsappEnabled")||this._dirtyFields.has("whatsappBridgeUrl")||this._dirtyFields.has("whatsappAllowFrom"))&&(s.channels={...s.channels,whatsapp:{}},this._dirtyFields.has("whatsappEnabled")&&(s.channels.whatsapp.enabled=!!this._values.whatsappEnabled),this._dirtyFields.has("whatsappBridgeUrl")&&(s.channels.whatsapp.bridgeUrl=this._values.whatsappBridgeUrl),this._dirtyFields.has("whatsappAllowFrom")&&(s.channels.whatsapp.allowFrom=this._values.whatsappAllowFrom?this._values.whatsappAllowFrom.split(",").map(r=>r.trim()).filter(r=>r):[]))),(this._dirtyFields.has("heartbeatEnabled")||this._dirtyFields.has("heartbeatIntervalMs"))&&(s.gateway={heartbeat:{}},this._dirtyFields.has("heartbeatEnabled")&&(s.gateway.heartbeat.enabled=!!this._values.heartbeatEnabled),this._dirtyFields.has("heartbeatIntervalMs")&&(s.gateway.heartbeat.intervalMs=Number(this._values.heartbeatIntervalMs)));try{const r=await fetch(`${e}/api/config`,{method:"PATCH",headers:{"Content-Type":"application/json",...t?{Authorization:`Bearer ${t}`}:{}},body:JSON.stringify(s)});if(!r.ok){const l=await r.json();throw new Error(l.error||"Failed to save settings")}this._dirtyFields.clear(),this._saveSuccess=!0,setTimeout(()=>{this._saveSuccess=!1},3e3)}catch(r){console.error("Failed to save settings:",r),alert(r instanceof Error?r.message:"Failed to save settings")}finally{this._saving=!1}}_handleInput(e,t){this._values={...this._values,[e]:t},this._dirtyFields.add(e),this.requestUpdate()}render(){return o`
|
|
1651
|
+
<div class="settings-page">
|
|
1652
|
+
<div class="settings-sidebar">
|
|
1653
|
+
<div class="sidebar-header">
|
|
1654
|
+
<h3>${a("settings.title")}</h3>
|
|
1655
|
+
</div>
|
|
1656
|
+
<nav class="sidebar-nav">
|
|
1657
|
+
${this._sections.map(e=>o`
|
|
1658
|
+
<button
|
|
1659
|
+
class="nav-item ${this._activeSection===e.id?"active":""}"
|
|
1660
|
+
@click=${()=>this._activeSection=e.id}
|
|
1661
|
+
>
|
|
1662
|
+
${p(e.icon)}
|
|
1663
|
+
<span>${e.title}</span>
|
|
1664
|
+
</button>
|
|
1665
|
+
`)}
|
|
1666
|
+
</nav>
|
|
1667
|
+
</div>
|
|
1668
|
+
|
|
1669
|
+
<div class="settings-main">
|
|
1670
|
+
${this._loading?o`
|
|
1671
|
+
<div class="loading-state">
|
|
1672
|
+
<div class="spinner"></div>
|
|
1673
|
+
<p>${a("settings.loading")}</p>
|
|
1674
|
+
</div>
|
|
1675
|
+
`:this._renderSection()}
|
|
1676
|
+
</div>
|
|
1677
|
+
|
|
1678
|
+
<!-- Save button floating -->
|
|
1679
|
+
${this._dirtyFields.size>0?o`
|
|
1680
|
+
<div class="floating-save">
|
|
1681
|
+
<span class="dirty-count">${a("settings.unsaved",{count:this._dirtyFields.size})}</span>
|
|
1682
|
+
<button
|
|
1683
|
+
class="btn btn-primary"
|
|
1684
|
+
?disabled=${this._saving||this._errors.size>0}
|
|
1685
|
+
@click=${this._saveSettings}
|
|
1686
|
+
>
|
|
1687
|
+
${this._saving?o`
|
|
1688
|
+
<span class="spinner-sm"></span>
|
|
1689
|
+
${a("settings.saving")}
|
|
1690
|
+
`:o`
|
|
1691
|
+
<span>${p("save")}</span>
|
|
1692
|
+
${a("settings.saveChanges")}
|
|
1693
|
+
`}
|
|
1694
|
+
</button>
|
|
1695
|
+
</div>
|
|
1696
|
+
`:""}
|
|
1697
|
+
</div>
|
|
1698
|
+
`}_renderSection(){const e=this._sections.find(s=>s.id===this._activeSection);if(!e)return o`<div>${a("settings.noSection")}</div>`;const t=`settings.descriptions.${e.id}`;return o`
|
|
1699
|
+
<div class="section-content">
|
|
1700
|
+
<div class="section-header">
|
|
1701
|
+
<h2>${e.title}</h2>
|
|
1702
|
+
<p class="section-desc">${a(t)}</p>
|
|
1703
|
+
</div>
|
|
1704
|
+
|
|
1705
|
+
<div class="fields-grid">
|
|
1706
|
+
${e.fields.map(s=>this._renderField(s))}
|
|
1707
|
+
</div>
|
|
1708
|
+
</div>
|
|
1709
|
+
`}_renderField(e){const t=this._values[e.key],s=this._errors.get(e.key);return o`
|
|
1710
|
+
<div class="field-group ${s?"has-error":""}">
|
|
1711
|
+
<div class="field-header">
|
|
1712
|
+
<label class="field-label">${e.label}</label>
|
|
1713
|
+
${e.validation?.required?o`<span class="required-mark">*</span>`:""}
|
|
1714
|
+
</div>
|
|
1715
|
+
|
|
1716
|
+
${e.description?o`<p class="field-desc">${e.description}</p>`:""}
|
|
1717
|
+
|
|
1718
|
+
${e.type==="boolean"?this._renderBooleanField(e,t):""}
|
|
1719
|
+
${e.type==="select"?this._renderSelectField(e,t):""}
|
|
1720
|
+
${["text","password","number"].includes(e.type)?this._renderInputField(e,t):""}
|
|
1721
|
+
|
|
1722
|
+
${s?o`
|
|
1723
|
+
<div class="field-error">
|
|
1724
|
+
<span>${s}</span>
|
|
1725
|
+
</div>
|
|
1726
|
+
`:""}
|
|
1727
|
+
</div>
|
|
1728
|
+
`}_renderInputField(e,t){return o`
|
|
1729
|
+
<input
|
|
1730
|
+
type=${e.type==="number"?"number":"text"}
|
|
1731
|
+
class="text-input"
|
|
1732
|
+
.value=${String(t??"")}
|
|
1733
|
+
placeholder=${e.placeholder||""}
|
|
1734
|
+
minlength=${e.validation?.min}
|
|
1735
|
+
maxlength=${e.validation?.max}
|
|
1736
|
+
min=${e.validation?.min}
|
|
1737
|
+
max=${e.validation?.max}
|
|
1738
|
+
@input=${s=>this._handleInput(e.key,s.target.value)}
|
|
1739
|
+
/>
|
|
1740
|
+
`}_renderSelectField(e,t){return o`
|
|
1741
|
+
<select
|
|
1742
|
+
class="select-input"
|
|
1743
|
+
.value=${String(t??"")}
|
|
1744
|
+
@change=${s=>this._handleInput(e.key,s.target.value)}
|
|
1745
|
+
>
|
|
1746
|
+
${e.options?.map(s=>o`
|
|
1747
|
+
<option value=${s.value} ?selected=${t===s.value}>${s.label}</option>
|
|
1748
|
+
`)}
|
|
1749
|
+
</select>
|
|
1750
|
+
`}_renderBooleanField(e,t){return o`
|
|
1751
|
+
<label class="toggle-label">
|
|
1752
|
+
<input
|
|
1753
|
+
type="checkbox"
|
|
1754
|
+
class="toggle-input"
|
|
1755
|
+
.checked=${!!t}
|
|
1756
|
+
@change=${s=>this._handleInput(e.key,s.target.checked)}
|
|
1757
|
+
/>
|
|
1758
|
+
<span class="toggle-switch"></span>
|
|
1759
|
+
<span class="toggle-text">${e.description||a("settings.enableFeature")}</span>
|
|
1760
|
+
</label>
|
|
1761
|
+
`}};D([u({attribute:!1})],P.prototype,"config",2);D([c()],P.prototype,"_activeSection",2);D([c()],P.prototype,"_loading",2);D([c()],P.prototype,"_saving",2);D([c()],P.prototype,"_dirtyFields",2);D([c()],P.prototype,"_errors",2);D([c()],P.prototype,"_saveSuccess",2);D([c()],P.prototype,"_models",2);D([c()],P.prototype,"_values",2);P=D([k("settings-page")],P);function ai(){return[{label:a("nav.chat"),tabs:["chat"]},{label:a("nav.management"),tabs:["sessions","cron","logs"]},{label:a("nav.settings"),tabs:["settings"]}]}function li(e){return a(`nav.${e}`)}const ci={chat:"messageSquare",sessions:"folderOpen",cron:"clock",logs:"fileText",settings:"settings"};function hi(e){const t=e.replace(/^#\/?chat\/?/,"");if(!t||t==="/")return{type:"recent"};const s=t.replace(/^\/?/,"");return s==="new"?{type:"new"}:s&&s.length>0?{type:"session",sessionKey:decodeURIComponent(s)}:{type:"recent"}}function st(e){switch(e.type){case"recent":return"#/chat";case"new":return"#/chat/new";case"session":return`#/chat/${encodeURIComponent(e.sessionKey)}`}}function di(e,t,s){const i=ci[e],n=li(e);return o`
|
|
1762
|
+
<button
|
|
1763
|
+
class="nav-item ${t?"nav-item--active":""}"
|
|
1764
|
+
@click=${s}
|
|
1765
|
+
role="tab"
|
|
1766
|
+
aria-selected=${t}
|
|
1767
|
+
>
|
|
1768
|
+
<span class="nav-item__icon">${p(i)}</span>
|
|
1769
|
+
<span class="nav-item__text">${n}</span>
|
|
1770
|
+
</button>
|
|
1771
|
+
`}var pi=Object.defineProperty,ui=Object.getOwnPropertyDescriptor,R=(e,t,s,i)=>{for(var n=i>1?void 0:i?ui(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&pi(t,s,n),n};let I=class extends y{constructor(){super(...arguments),this._activeTab="chat",this._navCollapsed=!1,this._navMobileOpen=!1,this._theme="system",this._language="en",this._chatRoute={type:"recent"}}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this._loadTheme(),this._loadLanguage(),this._loadRouteFromHash(),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{this._theme==="system"&&this._applyTheme()}),window.addEventListener("languagechange",()=>{this.requestUpdate()}),window.addEventListener("hashchange",()=>{this._loadRouteFromHash()})}_loadRouteFromHash(){const e=location.hash.slice(1);if(e.startsWith("chat")){const i=hi(e);i&&(this._activeTab!=="chat"&&(this._activeTab="chat"),JSON.stringify(this._chatRoute)!==JSON.stringify(i)&&(this._chatRoute=i));return}const t=e;["sessions","cron","logs","settings"].includes(t)&&this._activeTab!==t&&(this._activeTab=t)}_switchTab(e){this._activeTab=e;let t;e==="chat"?t=st(this._chatRoute):t=`#${e}`,location.hash!==t&&history.pushState(null,"",t),this._navMobileOpen=!1}_updateChatRoute(e){this._chatRoute=e;const t=st(e);history.pushState(null,"",t)}_loadTheme(){const e=localStorage.getItem("xopcbot-theme");e&&(this._theme=e),this._applyTheme()}_loadLanguage(){const e=localStorage.getItem("xopcbot-language");e&&(this._language=e,tt(e))}_applyTheme(){const e=document.documentElement;e.classList.remove("light","dark");let t=!1;this._theme==="dark"?t=!0:this._theme==="system"&&(t=window.matchMedia("(prefers-color-scheme: dark)").matches),t?e.classList.add("dark"):e.classList.add("light"),window.dispatchEvent(new CustomEvent("themechange",{detail:{theme:t?"dark":"light"}}))}_setTheme(e){this._theme=e,localStorage.setItem("xopcbot-theme",e),this._applyTheme()}_setLanguage(e){this._language=e,tt(e),localStorage.setItem("xopcbot-language",e),this.requestUpdate()}_renderThemeToggle(){return o`
|
|
1772
|
+
<div class="pill-toggle">
|
|
1773
|
+
<button
|
|
1774
|
+
class="pill-btn ${this._theme==="light"?"active":""}"
|
|
1775
|
+
@click=${()=>this._setTheme("light")}
|
|
1776
|
+
title="Light"
|
|
1777
|
+
>
|
|
1778
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1779
|
+
<circle cx="12" cy="12" r="5"></circle>
|
|
1780
|
+
<line x1="12" y1="1" x2="12" y2="3"></line>
|
|
1781
|
+
<line x1="12" y1="21" x2="12" y2="23"></line>
|
|
1782
|
+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
|
1783
|
+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
|
1784
|
+
<line x1="1" y1="12" x2="3" y2="12"></line>
|
|
1785
|
+
<line x1="21" y1="12" x2="23" y2="12"></line>
|
|
1786
|
+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
|
1787
|
+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
|
1788
|
+
</svg>
|
|
1789
|
+
</button>
|
|
1790
|
+
<button
|
|
1791
|
+
class="pill-btn ${this._theme==="dark"?"active":""}"
|
|
1792
|
+
@click=${()=>this._setTheme("dark")}
|
|
1793
|
+
title="Dark"
|
|
1794
|
+
>
|
|
1795
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1796
|
+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
|
1797
|
+
</svg>
|
|
1798
|
+
</button>
|
|
1799
|
+
<button
|
|
1800
|
+
class="pill-btn ${this._theme==="system"?"active":""}"
|
|
1801
|
+
@click=${()=>this._setTheme("system")}
|
|
1802
|
+
title="System"
|
|
1803
|
+
>
|
|
1804
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1805
|
+
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
|
|
1806
|
+
<line x1="8" y1="21" x2="16" y2="21"></line>
|
|
1807
|
+
<line x1="12" y1="17" x2="12" y2="21"></line>
|
|
1808
|
+
</svg>
|
|
1809
|
+
</button>
|
|
1810
|
+
</div>
|
|
1811
|
+
`}_renderLanguageToggle(){return o`
|
|
1812
|
+
<div class="pill-toggle">
|
|
1813
|
+
<button
|
|
1814
|
+
class="pill-btn ${this._language==="en"?"active":""}"
|
|
1815
|
+
@click=${()=>this._setLanguage("en")}
|
|
1816
|
+
title="English"
|
|
1817
|
+
>
|
|
1818
|
+
EN
|
|
1819
|
+
</button>
|
|
1820
|
+
<button
|
|
1821
|
+
class="pill-btn ${this._language==="zh"?"active":""}"
|
|
1822
|
+
@click=${()=>this._setLanguage("zh")}
|
|
1823
|
+
title="中文"
|
|
1824
|
+
>
|
|
1825
|
+
中
|
|
1826
|
+
</button>
|
|
1827
|
+
</div>
|
|
1828
|
+
`}_toggleNav(){window.innerWidth<768?this._navMobileOpen=!this._navMobileOpen:this._navCollapsed=!this._navCollapsed}_closeNavMobile(){this._navMobileOpen=!1}render(){return o`
|
|
1829
|
+
<div class="shell ${this._activeTab==="chat"?"shell--chat":""} ${this._navCollapsed?"shell--nav-collapsed":""}">
|
|
1830
|
+
<!-- Topbar -->
|
|
1831
|
+
<header class="topbar">
|
|
1832
|
+
<div class="topbar-left">
|
|
1833
|
+
<button
|
|
1834
|
+
class="nav-collapse-toggle"
|
|
1835
|
+
@click=${this._toggleNav}
|
|
1836
|
+
title="${this._navCollapsed?"Expand sidebar":"Collapse sidebar"}"
|
|
1837
|
+
aria-label="${this._navCollapsed?"Expand sidebar":"Collapse sidebar"}"
|
|
1838
|
+
>
|
|
1839
|
+
<span class="nav-collapse-toggle__icon">${p("menu")}</span>
|
|
1840
|
+
</button>
|
|
1841
|
+
|
|
1842
|
+
<div class="brand">
|
|
1843
|
+
<div class="brand-logo">
|
|
1844
|
+
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
1845
|
+
<rect width="24" height="24" rx="6" fill="url(#logo-gradient)"/>
|
|
1846
|
+
<path d="M8 12L11 15L16 9" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1847
|
+
<defs>
|
|
1848
|
+
<linearGradient id="logo-gradient" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
|
|
1849
|
+
<stop stop-color="#3b82f6"/>
|
|
1850
|
+
<stop offset="1" stop-color="#8b5cf6"/>
|
|
1851
|
+
</linearGradient>
|
|
1852
|
+
</defs>
|
|
1853
|
+
</svg>
|
|
1854
|
+
</div>
|
|
1855
|
+
<div class="brand-text">
|
|
1856
|
+
<div class="brand-title">XOPCBOT</div>
|
|
1857
|
+
<div class="brand-sub">Gateway</div>
|
|
1858
|
+
</div>
|
|
1859
|
+
</div>
|
|
1860
|
+
</div>
|
|
1861
|
+
|
|
1862
|
+
<div class="topbar-status">
|
|
1863
|
+
${this._renderLanguageToggle()}
|
|
1864
|
+
${this._renderThemeToggle()}
|
|
1865
|
+
</div>
|
|
1866
|
+
</header>
|
|
1867
|
+
|
|
1868
|
+
<!-- Mobile Overlay Backdrop -->
|
|
1869
|
+
${this._navMobileOpen?o`
|
|
1870
|
+
<div class="nav-overlay" @click=${this._closeNavMobile}></div>
|
|
1871
|
+
`:m}
|
|
1872
|
+
|
|
1873
|
+
<div class="shell-main">
|
|
1874
|
+
<!-- Sidebar Navigation -->
|
|
1875
|
+
<aside class="nav ${this._navCollapsed?"nav--collapsed":""} ${this._navMobileOpen?"nav--mobile-open":""}">
|
|
1876
|
+
${ai().map(e=>(e.tabs.some(t=>t===this._activeTab),o`
|
|
1877
|
+
<div class="nav-group">
|
|
1878
|
+
<div class="nav-label nav-label--static">
|
|
1879
|
+
<span class="nav-label__text">${e.label}</span>
|
|
1880
|
+
</div>
|
|
1881
|
+
<div class="nav-group__items">
|
|
1882
|
+
${e.tabs.map(t=>di(t,this._activeTab===t,()=>{this._switchTab(t)}))}
|
|
1883
|
+
</div>
|
|
1884
|
+
</div>
|
|
1885
|
+
`))}
|
|
1886
|
+
</aside>
|
|
1887
|
+
|
|
1888
|
+
<!-- Main Content -->
|
|
1889
|
+
<main class="content ${this._activeTab==="chat"?"content--chat":""}">
|
|
1890
|
+
${this._activeTab==="chat"?this._renderChat():m}
|
|
1891
|
+
${this._activeTab==="sessions"?this._renderSessions():m}
|
|
1892
|
+
${this._activeTab==="cron"?this._renderCron():m}
|
|
1893
|
+
${this._activeTab==="logs"?this._renderLogs():m}
|
|
1894
|
+
${this._activeTab==="settings"?this._renderSettings():m}
|
|
1895
|
+
</main>
|
|
1896
|
+
</div>
|
|
1897
|
+
</div>
|
|
1898
|
+
`}_renderChat(){return o`
|
|
1899
|
+
<xopcbot-gateway-chat
|
|
1900
|
+
.config=${this.gatewayConfig}
|
|
1901
|
+
.route=${this._chatRoute}
|
|
1902
|
+
.enableAttachments=${!0}
|
|
1903
|
+
.enableModelSelector=${!0}
|
|
1904
|
+
.enableThinkingSelector=${!0}
|
|
1905
|
+
@route-change=${e=>this._updateChatRoute(e.detail)}
|
|
1906
|
+
></xopcbot-gateway-chat>
|
|
1907
|
+
`}_renderSessions(){const e=this.gatewayConfig?.url||"",t=this.gatewayConfig?.token;return o`
|
|
1908
|
+
<session-manager
|
|
1909
|
+
.config=${{url:e,token:t}}
|
|
1910
|
+
></session-manager>
|
|
1911
|
+
`}_renderCron(){const e=this.gatewayConfig?.url||"",t=this.gatewayConfig?.token;return o`
|
|
1912
|
+
<cron-manager
|
|
1913
|
+
.config=${{url:e,token:t}}
|
|
1914
|
+
></cron-manager>
|
|
1915
|
+
`}_renderLogs(){const e=this.gatewayConfig?.url||"",t=this.gatewayConfig?.token;return o`
|
|
1916
|
+
<log-manager
|
|
1917
|
+
.config=${{url:e,token:t}}
|
|
1918
|
+
></log-manager>
|
|
1919
|
+
`}_renderSettings(){const e=this.gatewayConfig?.url||"",t=this.gatewayConfig?.token;return o`
|
|
1920
|
+
<settings-page
|
|
1921
|
+
.config=${{url:e,token:t}}
|
|
1922
|
+
></settings-page>
|
|
1923
|
+
`}showChat(){this._activeTab="chat"}get chatElement(){return this._chatElement}};R([u({attribute:!1})],I.prototype,"gatewayConfig",2);R([c()],I.prototype,"_activeTab",2);R([c()],I.prototype,"_navCollapsed",2);R([c()],I.prototype,"_navMobileOpen",2);R([c()],I.prototype,"_theme",2);R([c()],I.prototype,"_language",2);R([c()],I.prototype,"_chatRoute",2);R([ie("xopcbot-gateway-chat")],I.prototype,"_chatElement",2);I=R([k("xopcbot-app")],I);var gi=Object.defineProperty,mi=Object.getOwnPropertyDescriptor,O=(e,t,s,i)=>{for(var n=i>1?void 0:i?mi(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&gi(t,s,n),n};let F=class extends y{constructor(){super(...arguments),this.sections=[],this.values={},this.loading=!1,this._activeSection="",this._dirtyFields=new Set,this._showPasswords=new Set,this._errors=new Map}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this._updateActiveSection()}willUpdate(e){e.has("sections")&&this._updateActiveSection()}_updateActiveSection(){this.sections.length>0&&!this._activeSection&&(this._activeSection=this.sections[0].id)}_getIcon(e){return{user:o`<User class="w-5 h-5" />`,bot:o`<Bot class="w-5 h-5" />`,plug:o`<Plug class="w-5 h-5" />`,globe:o`<Globe class="w-5 h-5" />`,search:o`<Search class="w-5 h-5" />`,clock:o`<Clock class="w-5 h-5" />`,puzzle:o`<Puzzle class="w-5 h-5" />`,settings:o`<Settings class="w-5 h-5" />`}[e]||o`<Settings class="w-5 h-5" />`}render(){return o`
|
|
1924
|
+
<div class="settings-overlay" @click=${e=>e.target===e.currentTarget&&this.onClose?.()}>
|
|
1925
|
+
<div class="settings-dialog">
|
|
1926
|
+
${this.renderHeader()}
|
|
1927
|
+
<div class="settings-content">
|
|
1928
|
+
${this.renderSidebar()}
|
|
1929
|
+
${this.renderMain()}
|
|
1930
|
+
</div>
|
|
1931
|
+
${this.renderFooter()}
|
|
1932
|
+
</div>
|
|
1933
|
+
</div>
|
|
1934
|
+
`}renderHeader(){return o`
|
|
1935
|
+
<div class="settings-header">
|
|
1936
|
+
<div class="settings-title">
|
|
1937
|
+
<Settings class="w-5 h-5" />
|
|
1938
|
+
<span>Settings</span>
|
|
1939
|
+
</div>
|
|
1940
|
+
<button class="close-btn" @click=${()=>this.onClose?.()}>
|
|
1941
|
+
<X class="w-5 h-5" />
|
|
1942
|
+
</button>
|
|
1943
|
+
</div>
|
|
1944
|
+
`}renderSidebar(){return o`
|
|
1945
|
+
<nav class="settings-sidebar">
|
|
1946
|
+
${this.sections.map(e=>o`
|
|
1947
|
+
<button
|
|
1948
|
+
class="sidebar-item ${this._activeSection===e.id?"active":""}"
|
|
1949
|
+
@click=${()=>this._activeSection=e.id}
|
|
1950
|
+
>
|
|
1951
|
+
${this._getIcon(e.icon)}
|
|
1952
|
+
<span>${e.title}</span>
|
|
1953
|
+
<ChevronRight class="w-4 h-4 chevron" />
|
|
1954
|
+
</button>
|
|
1955
|
+
`)}
|
|
1956
|
+
</nav>
|
|
1957
|
+
`}renderMain(){const e=this.sections.find(s=>s.id===this._activeSection);if(!e)return o`<div class="settings-main">${a("settings.noSection")}</div>`;const t=`settings.descriptions.${e.id}`;return o`
|
|
1958
|
+
<div class="settings-main">
|
|
1959
|
+
<div class="section-header">
|
|
1960
|
+
<h2>${e.title}</h2>
|
|
1961
|
+
<p class="section-description">${a(t)}</p>
|
|
1962
|
+
</div>
|
|
1963
|
+
|
|
1964
|
+
<div class="fields-grid">
|
|
1965
|
+
${e.fields.map(s=>this.renderField(s,e.id))}
|
|
1966
|
+
</div>
|
|
1967
|
+
</div>
|
|
1968
|
+
`}renderField(e,t){const s=`${t}.${e.key}`,i=this._getValue(e.key),n=this._dirtyFields.has(s),r=this._errors.get(s),l=this._showPasswords.has(s);return o`
|
|
1969
|
+
<div class="field-group ${r?"has-error":""}">
|
|
1970
|
+
<div class="field-header">
|
|
1971
|
+
<label class="field-label">${e.label}</label>
|
|
1972
|
+
${e.validation?.required?o`<span class="required-mark">*</span>`:""}
|
|
1973
|
+
</div>
|
|
1974
|
+
|
|
1975
|
+
${e.description?o`<p class="field-description">${e.description}</p>`:""}
|
|
1976
|
+
|
|
1977
|
+
${e.type==="boolean"?this.renderBooleanField(e,i,s):""}
|
|
1978
|
+
|
|
1979
|
+
${e.type==="select"?this.renderSelectField(e,i,s):""}
|
|
1980
|
+
|
|
1981
|
+
${e.type==="textarea"?this.renderTextareaField(e,i,s):""}
|
|
1982
|
+
|
|
1983
|
+
${["text","password","number"].includes(e.type)?this.renderInputField(e,i,s,l):""}
|
|
1984
|
+
|
|
1985
|
+
${r?o`
|
|
1986
|
+
<div class="field-error">
|
|
1987
|
+
<AlertCircle class="w-4 h-4" />
|
|
1988
|
+
<span>${r}</span>
|
|
1989
|
+
</div>
|
|
1990
|
+
`:""}
|
|
1991
|
+
|
|
1992
|
+
${n&&!r?o`
|
|
1993
|
+
<div class="field-dirty">${a("settings.unsavedChanges")}</div>
|
|
1994
|
+
`:""}
|
|
1995
|
+
</div>
|
|
1996
|
+
`}renderInputField(e,t,s,i){const n=e.type==="password"?i?"text":"password":e.type;return o`
|
|
1997
|
+
<div class="input-wrapper">
|
|
1998
|
+
<input
|
|
1999
|
+
type=${n}
|
|
2000
|
+
class="text-input ${e.type==="password"?"has-toggle":""}"
|
|
2001
|
+
.value=${String(t??"")}
|
|
2002
|
+
placeholder=${e.placeholder||""}
|
|
2003
|
+
minlength=${e.validation?.min}
|
|
2004
|
+
maxlength=${e.validation?.max}
|
|
2005
|
+
pattern=${e.validation?.pattern||""}
|
|
2006
|
+
@input=${r=>this._handleInput(e,s,r.target.value)}
|
|
2007
|
+
/>
|
|
2008
|
+
${e.type==="password"?o`
|
|
2009
|
+
<button
|
|
2010
|
+
type="button"
|
|
2011
|
+
class="password-toggle"
|
|
2012
|
+
@click=${()=>this._togglePassword(s)}
|
|
2013
|
+
>
|
|
2014
|
+
${i?o`<EyeOff class="w-4 h-4" />`:o`<Eye class="w-4 h-4" />`}
|
|
2015
|
+
</button>
|
|
2016
|
+
`:""}
|
|
2017
|
+
</div>
|
|
2018
|
+
`}renderTextareaField(e,t,s){return o`
|
|
2019
|
+
<textarea
|
|
2020
|
+
class="textarea-input"
|
|
2021
|
+
.value=${String(t??"")}
|
|
2022
|
+
placeholder=${e.placeholder||""}
|
|
2023
|
+
rows="4"
|
|
2024
|
+
@input=${i=>this._handleInput(e,s,i.target.value)}
|
|
2025
|
+
></textarea>
|
|
2026
|
+
`}renderSelectField(e,t,s){return o`
|
|
2027
|
+
<select
|
|
2028
|
+
class="select-input"
|
|
2029
|
+
.value=${String(t??"")}
|
|
2030
|
+
@change=${i=>this._handleInput(e,s,i.target.value)}
|
|
2031
|
+
>
|
|
2032
|
+
${e.options?.map(i=>o`
|
|
2033
|
+
<option value=${i.value} ?selected=${t===i.value}>${i.label}</option>
|
|
2034
|
+
`)}
|
|
2035
|
+
</select>
|
|
2036
|
+
`}renderBooleanField(e,t,s){return o`
|
|
2037
|
+
<label class="toggle-label">
|
|
2038
|
+
<input
|
|
2039
|
+
type="checkbox"
|
|
2040
|
+
class="toggle-input"
|
|
2041
|
+
.checked=${!!t}
|
|
2042
|
+
@change=${i=>this._handleInput(e,s,i.target.checked)}
|
|
2043
|
+
/>
|
|
2044
|
+
<span class="toggle-switch"></span>
|
|
2045
|
+
<span class="toggle-text">${e.description||a("settings.enableFeature")}</span>
|
|
2046
|
+
</label>
|
|
2047
|
+
`}renderFooter(){const e=this._dirtyFields.size>0;return o`
|
|
2048
|
+
<div class="settings-footer">
|
|
2049
|
+
<button class="btn btn-ghost" @click=${()=>this.onClose?.()}>
|
|
2050
|
+
${a("settings.cancel")}
|
|
2051
|
+
</button>
|
|
2052
|
+
<button
|
|
2053
|
+
class="btn btn-primary"
|
|
2054
|
+
?disabled=${this.loading||!e}
|
|
2055
|
+
@click=${()=>this._save()}
|
|
2056
|
+
>
|
|
2057
|
+
${this.loading?o`
|
|
2058
|
+
<Loader2 class="w-4 h-4 animate-spin" />
|
|
2059
|
+
${a("settings.saving")}
|
|
2060
|
+
`:o`
|
|
2061
|
+
<Save class="w-4 h-4" />
|
|
2062
|
+
${a("settings.saveChanges")}
|
|
2063
|
+
`}
|
|
2064
|
+
</button>
|
|
2065
|
+
</div>
|
|
2066
|
+
`}_getValue(e){return this.values[e]}_handleInput(e,t,s){e.validation?.required&&!s?this._errors.set(t,a("settings.required",{field:e.label})):e.validation?.pattern&&s?new RegExp(e.validation.pattern).test(s)?this._errors.delete(t):this._errors.set(t,a("settings.invalidFormat")):this._errors.delete(t),this._dirtyFields.add(t),this.requestUpdate()}_togglePassword(e){this._showPasswords.has(e)?this._showPasswords.delete(e):this._showPasswords.add(e),this.requestUpdate()}_save(){this._errors.size>0||this.onSave&&this.onSave(this.values)}};O([u({attribute:!1})],F.prototype,"sections",2);O([u({attribute:!1})],F.prototype,"values",2);O([u({type:Boolean})],F.prototype,"loading",2);O([u({attribute:!1})],F.prototype,"onSave",2);O([u({attribute:!1})],F.prototype,"onClose",2);O([c()],F.prototype,"_activeSection",2);O([c()],F.prototype,"_dirtyFields",2);O([c()],F.prototype,"_showPasswords",2);O([c()],F.prototype,"_errors",2);F=O([k("xopcbot-settings")],F);var _i=Object.defineProperty,vi=Object.getOwnPropertyDescriptor,Z=(e,t,s,i)=>{for(var n=i>1?void 0:i?vi(t,s):t,r=e.length-1,l;r>=0;r--)(l=e[r])&&(n=(i?l(t,s,n):l(n))||n);return i&&n&&_i(t,s,n),n};let H=class extends y{constructor(){super(...arguments),this.enableAttachments=!0,this.enableModelSelector=!0,this.enableThinkingSelector=!0,this._autoScroll=!0,this._lastScrollTop=0,this._handleScroll=()=>{if(!this._scrollContainer)return;const e=this._scrollContainer.scrollTop,t=this._scrollContainer.scrollHeight,s=this._scrollContainer.clientHeight,i=t-e-s;if(s<this._lastClientHeight){this._lastClientHeight=s;return}e!==0&&e<this._lastScrollTop&&i>50?this._autoScroll=!1:i<10&&(this._autoScroll=!0),this._lastScrollTop=e,this._lastClientHeight=s}}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.style.display="flex",this.style.flexDirection="column",this.style.height="100%",this.style.minHeight="0",this.setupSessionSubscription()}disconnectedCallback(){super.disconnectedCallback(),this._resizeObserver?.disconnect(),this._scrollContainer?.removeEventListener("scroll",this._handleScroll),this._unsubscribeSession?.()}setupSessionSubscription(){this._unsubscribeSession&&this._unsubscribeSession(),this.agent&&(this._unsubscribeSession=this.agent.subscribe(async e=>{switch(e.type){case"message_start":case"message_end":case"turn_start":case"turn_end":case"agent_start":this.requestUpdate();break;case"agent_end":this._streamingContainer&&(this._streamingContainer.isStreaming=!1,this._streamingContainer.setMessage(null,!0)),this.requestUpdate();break;case"message_update":this._streamingContainer&&(this._streamingContainer.isStreaming=this.agent?.state.isStreaming||!1,this._streamingContainer.setMessage(e.message,!this._streamingContainer.isStreaming)),this.requestUpdate();break}}))}setInput(e,t){this._messageEditor&&(this._messageEditor.value=e,this._messageEditor.attachments=t||[])}setAutoScroll(e){this._autoScroll=e}async sendMessage(e,t){if(!(!e.trim()&&t?.length===0||this.agent?.state.isStreaming)){if(!this.agent)throw new Error("No agent set");if(!this.agent.state.model)throw new Error("No model set");this._messageEditor.value="",this._messageEditor.attachments=[],this._autoScroll=!0,t&&t.length>0?await this.agent.prompt({role:"user-with-attachments",content:e,attachments:t,timestamp:Date.now()}):await this.agent.prompt(e)}}renderMessages(){if(!this.agent)return o`<div class="p-4 text-center text-muted-foreground">${te("No session available")}</div>`;const e=this.agent.state;return o`
|
|
2067
|
+
<div class="flex flex-col gap-3">
|
|
2068
|
+
<message-list
|
|
2069
|
+
.messages=${this.agent.state.messages}
|
|
2070
|
+
.tools=${e.tools}
|
|
2071
|
+
.pendingToolCalls=${this.agent?this.agent.state.pendingToolCalls:new Set}
|
|
2072
|
+
.isStreaming=${e.isStreaming}
|
|
2073
|
+
></message-list>
|
|
2074
|
+
|
|
2075
|
+
<streaming-message-container
|
|
2076
|
+
class="${e.isStreaming?"":"hidden"}"
|
|
2077
|
+
.tools=${e.tools}
|
|
2078
|
+
.isStreaming=${e.isStreaming}
|
|
2079
|
+
.pendingToolCalls=${e.pendingToolCalls}
|
|
2080
|
+
.isStreaming=${e.isStreaming}
|
|
2081
|
+
></streaming-message-container>
|
|
2082
|
+
</div>
|
|
2083
|
+
`}render(){if(!this.agent)return o`<div class="p-4 text-center text-muted-foreground">${te("No agent set")}</div>`;const e=this.agent.state;return o`
|
|
2084
|
+
<div class="flex flex-col h-full bg-background text-foreground">
|
|
2085
|
+
<div class="flex-1 overflow-y-auto">
|
|
2086
|
+
<div class="max-w-3xl mx-auto p-4 pb-0">${this.renderMessages()}</div>
|
|
2087
|
+
</div>
|
|
2088
|
+
|
|
2089
|
+
<div class="shrink-0">
|
|
2090
|
+
<div class="max-w-3xl mx-auto px-2">
|
|
2091
|
+
<message-editor
|
|
2092
|
+
.isStreaming=${e.isStreaming}
|
|
2093
|
+
.currentModel=${e.model}
|
|
2094
|
+
.thinkingLevel=${e.thinkingLevel}
|
|
2095
|
+
.showAttachmentButton=${this.enableAttachments}
|
|
2096
|
+
.showModelSelector=${this.enableModelSelector}
|
|
2097
|
+
.showThinkingSelector=${this.enableThinkingSelector}
|
|
2098
|
+
.onSend=${(t,s)=>this.sendMessage(t,s)}
|
|
2099
|
+
.onAbort=${()=>this.agent?.abort()}
|
|
2100
|
+
></message-editor>
|
|
2101
|
+
</div>
|
|
2102
|
+
</div>
|
|
2103
|
+
</div>
|
|
2104
|
+
`}};Z([u({attribute:!1})],H.prototype,"agent",2);Z([u({type:Boolean})],H.prototype,"enableAttachments",2);Z([u({type:Boolean})],H.prototype,"enableModelSelector",2);Z([u({type:Boolean})],H.prototype,"enableThinkingSelector",2);Z([ie("message-editor")],H.prototype,"_messageEditor",2);Z([ie("streaming-message-container")],H.prototype,"_streamingContainer",2);H=Z([k("xopcbot-chat")],H);
|
|
2105
|
+
//# sourceMappingURL=main-CfIxL-cL.js.map
|