@hybridaione/hybridclaw 0.25.7 → 0.26.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/AGENTS.md +1 -0
- package/CHANGELOG.md +81 -0
- package/README.md +10 -10
- package/config.example.json +25 -1
- package/console/dist/assets/chat-B3O0bG4k.js +4 -0
- package/console/dist/assets/{index-BpDn7FOM.js → index-CkDPeA4c.js} +38 -38
- package/console/dist/assets/index-ClyCVP4a.css +1 -0
- package/console/dist/assets/{terminal-ChyqBLWi.js → terminal-6wR9ID9V.js} +1 -1
- package/console/dist/icons/github.svg +3 -0
- package/console/dist/index.html +2 -2
- package/console/package.json +2 -2
- package/container/dist/tools.js +86 -7
- package/container/dist/tools.js.map +1 -1
- package/container/npm-shrinkwrap.json +27 -2723
- package/container/package-lock.json +27 -2723
- package/container/package.json +5 -5
- package/container/src/tools.ts +86 -9
- package/dist/a2a/a2a-inbound.d.ts.map +1 -1
- package/dist/a2a/a2a-inbound.js +7 -7
- package/dist/a2a/a2a-inbound.js.map +1 -1
- package/dist/a2a/pairing.d.ts +9 -1
- package/dist/a2a/pairing.d.ts.map +1 -1
- package/dist/a2a/pairing.js +132 -4
- package/dist/a2a/pairing.js.map +1 -1
- package/dist/a2a/trust-ledger.d.ts +74 -0
- package/dist/a2a/trust-ledger.d.ts.map +1 -1
- package/dist/a2a/trust-ledger.js +638 -74
- package/dist/a2a/trust-ledger.js.map +1 -1
- package/dist/a2a/webhook-inbound.d.ts +3 -2
- package/dist/a2a/webhook-inbound.d.ts.map +1 -1
- package/dist/a2a/webhook-inbound.js +22 -9
- package/dist/a2a/webhook-inbound.js.map +1 -1
- package/dist/auth/google-auth.d.ts +14 -0
- package/dist/auth/google-auth.d.ts.map +1 -1
- package/dist/auth/google-auth.js +4 -4
- package/dist/auth/google-auth.js.map +1 -1
- package/dist/auth/hybridai-auth.d.ts.map +1 -1
- package/dist/auth/hybridai-auth.js +23 -14
- package/dist/auth/hybridai-auth.js.map +1 -1
- package/dist/auth/microsoft-auth.d.ts +77 -0
- package/dist/auth/microsoft-auth.d.ts.map +1 -0
- package/dist/auth/microsoft-auth.js +348 -0
- package/dist/auth/microsoft-auth.js.map +1 -0
- package/dist/channels/discord/tool-actions.d.ts +8 -0
- package/dist/channels/discord/tool-actions.d.ts.map +1 -1
- package/dist/channels/discord/tool-actions.js.map +1 -1
- package/dist/channels/email/admin-mailbox.d.ts +24 -4
- package/dist/channels/email/admin-mailbox.d.ts.map +1 -1
- package/dist/channels/email/admin-mailbox.js +102 -0
- package/dist/channels/email/admin-mailbox.js.map +1 -1
- package/dist/channels/email/prompt-adapter.d.ts.map +1 -1
- package/dist/channels/email/prompt-adapter.js +2 -3
- package/dist/channels/email/prompt-adapter.js.map +1 -1
- package/dist/channels/email/runtime.d.ts +20 -0
- package/dist/channels/email/runtime.d.ts.map +1 -1
- package/dist/channels/email/runtime.js +27 -0
- package/dist/channels/email/runtime.js.map +1 -1
- package/dist/channels/message/tool-actions.d.ts.map +1 -1
- package/dist/channels/message/tool-actions.js +152 -1
- package/dist/channels/message/tool-actions.js.map +1 -1
- package/dist/channels/message-tool-advertising.js +1 -1
- package/dist/channels/message-tool-advertising.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +209 -5
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/help.d.ts +1 -0
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +42 -5
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/secret-command.d.ts.map +1 -1
- package/dist/cli/secret-command.js +17 -6
- package/dist/cli/secret-command.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +2 -2
- package/dist/command-registry.js.map +1 -1
- package/dist/config/runtime-config.d.ts +20 -2
- package/dist/config/runtime-config.d.ts.map +1 -1
- package/dist/config/runtime-config.js +124 -2
- package/dist/config/runtime-config.js.map +1 -1
- package/dist/gateway/gateway-admin-connectors.d.ts +67 -0
- package/dist/gateway/gateway-admin-connectors.d.ts.map +1 -0
- package/dist/gateway/gateway-admin-connectors.js +589 -0
- package/dist/gateway/gateway-admin-connectors.js.map +1 -0
- package/dist/gateway/gateway-http-proxy.d.ts.map +1 -1
- package/dist/gateway/gateway-http-proxy.js +272 -76
- package/dist/gateway/gateway-http-proxy.js.map +1 -1
- package/dist/gateway/gateway-http-server.d.ts.map +1 -1
- package/dist/gateway/gateway-http-server.js +101 -27
- package/dist/gateway/gateway-http-server.js.map +1 -1
- package/dist/gateway/gateway-http-utils.d.ts.map +1 -1
- package/dist/gateway/gateway-http-utils.js +105 -1
- package/dist/gateway/gateway-http-utils.js.map +1 -1
- package/dist/gateway/gateway-secret-injection.d.ts +2 -2
- package/dist/gateway/gateway-secret-injection.d.ts.map +1 -1
- package/dist/gateway/gateway-service.d.ts.map +1 -1
- package/dist/gateway/gateway-service.js +45 -14
- package/dist/gateway/gateway-service.js.map +1 -1
- package/dist/gateway/gateway-url-utils.d.ts +4 -0
- package/dist/gateway/gateway-url-utils.d.ts.map +1 -0
- package/dist/gateway/gateway-url-utils.js +71 -0
- package/dist/gateway/gateway-url-utils.js.map +1 -0
- package/dist/identity/resolver.js +1 -1
- package/dist/identity/resolver.js.map +1 -1
- package/dist/infra/container-runner.d.ts.map +1 -1
- package/dist/infra/container-runner.js +4 -1
- package/dist/infra/container-runner.js.map +1 -1
- package/dist/infra/host-runner.d.ts.map +1 -1
- package/dist/infra/host-runner.js +2 -1
- package/dist/infra/host-runner.js.map +1 -1
- package/dist/mcp/hybridai-connectors.d.ts +11 -0
- package/dist/mcp/hybridai-connectors.d.ts.map +1 -0
- package/dist/mcp/hybridai-connectors.js +43 -0
- package/dist/mcp/hybridai-connectors.js.map +1 -0
- package/dist/policy/secret-route-policy.d.ts.map +1 -1
- package/dist/policy/secret-route-policy.js +14 -7
- package/dist/policy/secret-route-policy.js.map +1 -1
- package/dist/security/admin-rbac.d.ts +13 -13
- package/dist/security/admin-rbac.d.ts.map +1 -1
- package/dist/security/admin-rbac.js +17 -0
- package/dist/security/admin-rbac.js.map +1 -1
- package/docs/content/README.md +7 -0
- package/docs/content/channels/admin-console.md +8 -1
- package/docs/content/channels/email.md +19 -0
- package/docs/content/extensibility/skills.md +10 -3
- package/docs/content/getting-started/authentication.md +60 -2
- package/docs/content/guides/bundled-skills.md +3 -3
- package/docs/content/guides/skills/README.md +3 -3
- package/docs/content/guides/skills/integrations.md +128 -6
- package/docs/content/guides/skills/productivity.md +59 -1
- package/docs/content/reference/commands.md +5 -2
- package/docs/content/reference/configuration.md +7 -2
- package/docs/content/reference/faq.md +5 -3
- package/docs/index.html +11 -31
- package/npm-shrinkwrap.json +950 -2509
- package/package.json +8 -5
- package/skills/airtable/SKILL.md +12 -4
- package/skills/alexa/SKILL.md +30 -9
- package/skills/blink/SKILL.md +8 -4
- package/skills/byd-battery/SKILL.md +12 -5
- package/skills/download-platform-invoices/SKILL.md +3 -0
- package/skills/fastbill/SKILL.md +1 -1
- package/skills/fastbill/references/operator-setup.md +9 -2
- package/skills/fax-send/SKILL.md +26 -7
- package/skills/firecrawl/SKILL.md +16 -4
- package/skills/fronius/SKILL.md +11 -3
- package/skills/ga4/SKILL.md +11 -1
- package/skills/gh-issues/SKILL.md +4 -1
- package/skills/google-ads/SKILL.md +11 -2
- package/skills/google-ads/references/setup-and-operations.md +11 -2
- package/skills/hermes3000-writing/SKILL.md +7 -3
- package/skills/hermes3000-writing/references/api-workflow.md +4 -2
- package/skills/hetzner-cloud/SKILL.md +1 -1
- package/skills/hetzner-cloud/references/operator-setup.md +6 -1
- package/skills/hetzner-dns/SKILL.md +1 -1
- package/skills/hetzner-dns/references/operator-setup.md +6 -1
- package/skills/hetzner-storage-box/SKILL.md +14 -4
- package/skills/hetzner-storage-box/references/operator-setup.md +12 -2
- package/skills/heygen/SKILL.md +7 -2
- package/skills/homematic/SKILL.md +11 -3
- package/skills/hubspot/SKILL.md +8 -2
- package/skills/hue/SKILL.md +8 -4
- package/skills/langfuse/SKILL.md +13 -4
- package/skills/langfuse/references/operator-setup.md +6 -2
- package/skills/lexware-office/SKILL.md +46 -9
- package/skills/lexware-office/evals/scenarios.json +31 -0
- package/skills/lexware-office/lexware_office.cjs +81 -4
- package/skills/lexware-office/references/operator-setup.md +13 -1
- package/skills/mailchimp/SKILL.md +16 -11
- package/skills/microsoft-365/SKILL.md +162 -0
- package/skills/microsoft-365/m365.cjs +495 -0
- package/skills/miro/SKILL.md +345 -0
- package/skills/miro/index.cjs +1 -0
- package/skills/miro/miro.cjs +1569 -0
- package/skills/mittwald/SKILL.md +8 -2
- package/skills/posthog/SKILL.md +8 -4
- package/skills/salesforce/SKILL.md +6 -2
- package/skills/salesforce/references/metadata-and-queries.md +5 -1
- package/skills/shelly/SKILL.md +2 -2
- package/skills/speech.detect-language/SKILL.md +3 -3
- package/skills/speech.transcribe/SKILL.md +3 -3
- package/skills/t-cloud-public/SKILL.md +4 -4
- package/skills/t-cloud-public/references/operator-setup.md +17 -3
- package/skills/video.from-script/SKILL.md +1 -1
- package/skills/zabbix/SKILL.md +12 -2
- package/skills/zoho/SKILL.md +114 -0
- package/console/dist/assets/chat-tXOB66fw.js +0 -4
- package/console/dist/assets/index-DOnfovHg.css +0 -1
package/AGENTS.md
CHANGED
|
@@ -276,6 +276,7 @@ hybridclaw gateway status # gateway liveness, PID, build/version dia
|
|
|
276
276
|
|
|
277
277
|
- Treat existing uncommitted changes as user work unless you created them.
|
|
278
278
|
- Run `npm run format` before creating commits that will be pushed to GitHub.
|
|
279
|
+
- Always run `npm run lint` before creating any commit.
|
|
279
280
|
- Conventional Commits preferred: `feat:`, `fix:`, `test:`, `refactor:`,
|
|
280
281
|
`chore:`, `docs:`.
|
|
281
282
|
- Group related changes; avoid bundling unrelated refactors.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,87 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## [0.26.0](https://github.com/HybridAIOne/hybridclaw/tree/v0.26.0) - 2026-07-03
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Admin connector setup**: `/admin/connectors` can connect HybridAI with an
|
|
10
|
+
API key, run Google Workspace OAuth from the browser, show connector
|
|
11
|
+
connection state, test connector health, and launch HybridAI-managed GitHub
|
|
12
|
+
and Microsoft 365 authorization flows.
|
|
13
|
+
- **HybridAI connector MCP**: Gateways with HybridAI credentials now
|
|
14
|
+
auto-register the HybridAI connector MCP server unless an operator disables
|
|
15
|
+
or overrides the `hybridai` MCP server entry.
|
|
16
|
+
- **Live email mailbox reads**: The `message` tool can search and read
|
|
17
|
+
configured email mailboxes directly, with folder, unread, sender, subject,
|
|
18
|
+
date, query, and UID filters plus thread snapshots for individual messages.
|
|
19
|
+
- **Microsoft 365 Graph skill**: Added a read-only `microsoft-365` skill for
|
|
20
|
+
Outlook mail, calendars, OneDrive/SharePoint files, Teams, chats, and profile
|
|
21
|
+
reads through Microsoft Graph, plus `hybridclaw auth login microsoft365` and
|
|
22
|
+
`microsoft-oauth` secret routes for gateway-injected Graph access tokens.
|
|
23
|
+
- **Miro skill**: Added the `miro` skill for board discovery, metadata and item
|
|
24
|
+
reads, guarded sticky/text/shape/connector/frame writes, OAuth token
|
|
25
|
+
exchange helpers, and Enterprise board export workflows.
|
|
26
|
+
- **Zoho MCP skill**: Added the `zoho` skill for Zoho CRM, Desk, Mail,
|
|
27
|
+
Calendar, Books, Projects, WorkDrive, Cliq, Campaigns, and related workflows
|
|
28
|
+
through a configured Zoho MCP server.
|
|
29
|
+
- **A2A trust ledger**: A2A JSON-RPC and webhook trust now share a durable
|
|
30
|
+
trusted-peer ledger with legacy migration, TOFU audit lineage, revocation
|
|
31
|
+
state, and sender/public-key lookup paths.
|
|
32
|
+
- **A2A delegation trust pairing**: Agent Cards can advertise delegation
|
|
33
|
+
signing keys and canonical sender ids, and pairing approval records the
|
|
34
|
+
advertised A2A senders for trusted outbound delegation.
|
|
35
|
+
- **Console navigation config**: The top navigation strip can be customized
|
|
36
|
+
from runtime config with local console paths or HTTP(S) URLs and link text.
|
|
37
|
+
- **Lexware quotations**: The `lexware-office` skill now covers quotation
|
|
38
|
+
listing, retrieval, creation, and PDF downloads with explicit draft vs.
|
|
39
|
+
finalized document guidance.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- **Skill credential guidance**: Bundled API-backed skills now point operators
|
|
44
|
+
to browser admin secrets first, then `/secret set` from chat or TUI, with
|
|
45
|
+
local `hybridclaw secret set` commands as the fallback path.
|
|
46
|
+
- **Admin console docs**: Public docs and examples cover the connector setup
|
|
47
|
+
surface, Microsoft Graph OAuth routes, the updated bundled-skill count, and
|
|
48
|
+
the new Microsoft 365, Miro, Zoho, and live email mailbox-read surfaces.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- **Dependency security updates**: Resolved high npm audit findings, refreshed
|
|
53
|
+
lockfiles and shrinkwrap files, and updated dependency policy baselines.
|
|
54
|
+
- **Connector auth hardening**: Connector flows isolate signed-payload secrets,
|
|
55
|
+
keep return URLs result-neutral, restrict TLS pin secret resolution, and avoid
|
|
56
|
+
connector taint paths flagged by CodeQL.
|
|
57
|
+
- **Vision artifact URLs**: `vision_analyze` accepts local
|
|
58
|
+
`/api/artifact?path=...` URLs copied from chat history and resolves them to
|
|
59
|
+
the underlying workspace or media-cache file.
|
|
60
|
+
- **Instruction restore prompt**: The TUI config restore prompt more clearly
|
|
61
|
+
distinguishes restoring the last known-good config from manually repairing an
|
|
62
|
+
invalid config file.
|
|
63
|
+
|
|
64
|
+
## [0.25.8](https://github.com/HybridAIOne/hybridclaw/tree/v0.25.8) - 2026-06-27
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- **Email admin layout**: Email channel advanced settings now collapse by
|
|
69
|
+
default above additional mailboxes, keeping default allowlist management
|
|
70
|
+
prominent while poll interval, chunk limit, media limit, and channel
|
|
71
|
+
instructions remain available on demand.
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- **Cloud MCP OAuth callbacks**: MCP OAuth setup now prefers the configured
|
|
76
|
+
deployment public URL and other public gateway origins over private internal
|
|
77
|
+
request hosts, rejects invalid configured public URLs, and covers IPv4, IPv6,
|
|
78
|
+
and local development fallback cases.
|
|
79
|
+
- **Cloud request origins**: Admin session-cookie origin checks and mobile chat
|
|
80
|
+
QR launch links now honor `deployment.public_url` when requests arrive through
|
|
81
|
+
internal gateway hosts.
|
|
82
|
+
- **Email allowlist autosave**: Adding a default allowed sender in the admin
|
|
83
|
+
console now saves immediately instead of leaving the new entry only in the
|
|
84
|
+
unsaved draft state.
|
|
85
|
+
|
|
5
86
|
## [0.25.7](https://github.com/HybridAIOne/hybridclaw/tree/v0.25.7) - 2026-06-25
|
|
6
87
|
|
|
7
88
|
### Added
|
package/README.md
CHANGED
|
@@ -21,9 +21,9 @@ approval tiers, and are validated against `Qwen/Qwen3.6-27B-FP8` as the
|
|
|
21
21
|
small-model baseline.
|
|
22
22
|
|
|
23
23
|
That is the useful difference: a compact model can operate Salesforce,
|
|
24
|
-
HubSpot, GA4, Google Ads, Lexware, Airtable,
|
|
25
|
-
ops, and office documents through structured
|
|
26
|
-
free-form prompting.
|
|
24
|
+
HubSpot, GA4, Google Ads, Lexware, Airtable, Miro, Zoho, Microsoft 365,
|
|
25
|
+
warehouse SQL, invoices, cloud ops, and office documents through structured
|
|
26
|
+
rails instead of fragile free-form prompting.
|
|
27
27
|
|
|
28
28
|
HybridClaw also treats agents as networked coworkers. Local agents, hosted
|
|
29
29
|
HybridAI proxy agents, and trusted peer HybridClaw instances can address one
|
|
@@ -101,7 +101,7 @@ After the gateway starts, open:
|
|
|
101
101
|
| Surface | URL / command | Use it for |
|
|
102
102
|
| --- | --- | --- |
|
|
103
103
|
| Web Chat | `http://127.0.0.1:9090/chat` | Chat, slash commands, model and agent switching |
|
|
104
|
-
| Admin Console | `http://127.0.0.1:9090/admin` | Channels, agents, approvals, audit, config, secrets, skills, distillation |
|
|
104
|
+
| Admin Console | `http://127.0.0.1:9090/admin` | Channels, connectors, agents, approvals, audit, config, secrets, skills, distillation |
|
|
105
105
|
| Agents UI | `http://127.0.0.1:9090/agents` | Agent fleet overview and prompt-file editing |
|
|
106
106
|
| TUI | `hybridclaw tui` | Terminal chat, approvals, status, resume |
|
|
107
107
|
| OpenAI-compatible API | `http://127.0.0.1:9090/v1/chat/completions` | Local evals and compatible clients |
|
|
@@ -121,13 +121,13 @@ npm run desktop
|
|
|
121
121
|
|
|
122
122
|
| Area | Built in |
|
|
123
123
|
| --- | --- |
|
|
124
|
-
| Skills |
|
|
124
|
+
| Skills | 79 bundled skills, production business helpers, eval fixtures, packaged skill lifecycle, and human-distillation workflows |
|
|
125
125
|
| Channels | Discord, Slack, Signal, WhatsApp, Telegram, Microsoft Teams, email, iMessage, fax, Twilio voice, web, and incoming webhooks |
|
|
126
126
|
| Runtime | Gateway service, TUI client, web chat, admin console, loopback OpenAI-compatible API, Docker or host execution |
|
|
127
127
|
| Governance | Encrypted runtime secrets, SecretRef credential isolation, approval policies, sandbox controls, audit trails with hash-chain integrity |
|
|
128
128
|
| Memory | Local memory files, SQLite persistence, semantic recall, session compaction, optional HybridAI cloud memory sync |
|
|
129
129
|
| Agents | Guided hatching, per-agent workspaces, models, budgets, prompt files, explicit addressing, proxy agents, A2A trust, peer-instance communication |
|
|
130
|
-
| Extensibility | Packaged business skills, plugins, MCP servers, SecretRef-backed HTTP tools |
|
|
130
|
+
| Extensibility | Packaged business skills, plugins, MCP servers, admin connector flows, SecretRef-backed HTTP tools |
|
|
131
131
|
|
|
132
132
|
## Product Strengths
|
|
133
133
|
|
|
@@ -153,9 +153,9 @@ npm run desktop
|
|
|
153
153
|
- **Model freedom**: use HybridAI, major hosted providers, local engines, or
|
|
154
154
|
named OpenAI-compatible endpoints from the same model picker and config
|
|
155
155
|
surface.
|
|
156
|
-
- **Operator visibility**: `/admin` covers channels,
|
|
157
|
-
statistics, output guard, secrets, fleet topology, A2A inbox/trust,
|
|
158
|
-
distillation without requiring shell access.
|
|
156
|
+
- **Operator visibility**: `/admin` covers channels, connectors, approvals,
|
|
157
|
+
audit, statistics, output guard, secrets, fleet topology, A2A inbox/trust,
|
|
158
|
+
and distillation without requiring shell access.
|
|
159
159
|
- **Business-ready extension model**: packaged skills, plugins, MCP servers,
|
|
160
160
|
and SecretRef-backed HTTP tools share the same approval and credential
|
|
161
161
|
boundaries.
|
|
@@ -228,7 +228,7 @@ Core pieces:
|
|
|
228
228
|
| Build desktop releases | [Desktop Release Builds](https://hybridaione.github.io/hybridclaw/docs/developer-guide/desktop-release) |
|
|
229
229
|
| Contribute | [CONTRIBUTING.md](./CONTRIBUTING.md), [docs/content/README.md](./docs/content/README.md) |
|
|
230
230
|
|
|
231
|
-
Latest release: [v0.
|
|
231
|
+
Latest release: [v0.26.0](https://github.com/HybridAIOne/hybridclaw/releases/tag/v0.26.0).
|
|
232
232
|
Release notes: [CHANGELOG.md](./CHANGELOG.md)
|
|
233
233
|
|
|
234
234
|
## Development
|
package/config.example.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 32,
|
|
3
3
|
"security": {
|
|
4
4
|
"trustModelAccepted": false,
|
|
5
5
|
"trustModelAcceptedAt": "",
|
|
@@ -15,6 +15,30 @@
|
|
|
15
15
|
"health_check_interval_ms": 30000
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
+
"ui": {
|
|
19
|
+
"navigation": [
|
|
20
|
+
{
|
|
21
|
+
"href": "/chat",
|
|
22
|
+
"label": "Chat"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"href": "/agents",
|
|
26
|
+
"label": "Agents"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"href": "/admin",
|
|
30
|
+
"label": "Admin"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"href": "https://github.com/HybridAIOne/hybridclaw",
|
|
34
|
+
"label": "GitHub"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"href": "/docs",
|
|
38
|
+
"label": "Docs"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
},
|
|
18
42
|
"browser": {
|
|
19
43
|
"provider": "local",
|
|
20
44
|
"local": {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Bh1tDfsg.js";import{C as t,a as n,n as r,o as i,r as a}from"./query-o_Dd9s85.js";import{d as o,l as s}from"./router-DoNPHesn.js";import{$ as c,A as l,B as u,C as d,D as f,E as p,F as m,G as h,H as g,I as _,J as v,K as y,L as b,M as ee,N as x,O as S,P as C,Q as w,R as T,S as te,T as ne,U as re,V as ie,W as E,X as ae,Y as D,Z as oe,_ as se,_t as O,a as k,at as ce,b as A,bt as le,c as ue,ct as de,d as fe,dt as pe,et as me,f as j,ft as M,g as he,gt as ge,h as _e,ht as ve,i as N,it as ye,k as be,l as xe,m as P,mt as Se,n as F,nt as I,o as L,ot as Ce,p as we,pt as Te,q as Ee,r as R,rt as De,s as z,st as Oe,t as B,tt as ke,u as Ae,ut as V,w as H,x as je,xt as Me,y as Ne,z as Pe}from"./index-CkDPeA4c.js";var U=e(t(),1);function Fe(e,t,n=`web`,r=10,i,a){let o=new URLSearchParams({userId:t,channelId:n,limit:String(r)});return i&&o.set(`q`,i),a&&o.set(`scope`,a),O(`/api/chat/recent?${o.toString()}`,{token:e})}function Ie(e,t){let n=new URLSearchParams({channelId:t.channelId||`web`});return t.keepSessionId&&n.set(`keepSessionId`,t.keepSessionId),O(`/api/chat/cleanup?${n.toString()}`,{token:e,method:`POST`})}function Le(e,t,n=80,r,i){let a=new URLSearchParams({sessionId:t,limit:String(n)});return r&&a.set(`userId`,r),i?.trim()&&a.set(`agentId`,i.trim()),O(`/api/history?${a.toString()}`,{token:e})}function Re(e,t){return O(`/api/chat/context?${new URLSearchParams({sessionId:t}).toString()}`,{token:e})}function ze(e,t){return O(t?`/api/chat/commands?q=${encodeURIComponent(t)}`:`/api/chat/commands`,{token:e})}function Be(e,t){return O(`/api/chat/mobile-qr`,{token:e,method:`POST`,body:t})}function Ve(e,t,n){return O(`/api/chat/branch`,{token:e,method:`POST`,body:{sessionId:t,beforeMessageId:n}})}function He(e,t){return O(`/api/chat/rating`,{token:e,method:`POST`,body:t})}function Ue(e,t,n,r){return O(`/api/command`,{token:e,method:`POST`,body:V({sessionId:t,args:r,userId:n,username:`web`})})}function We(e,t){return O(`/api/media/upload`,{token:e,method:`POST`,rawBody:t,extraHeaders:{"Content-Type":t.type||`application/octet-stream`,"X-Hybridclaw-Filename":encodeURIComponent(t.name||`upload`)}})}function Ge(e){return`/api/artifact?${new URLSearchParams({path:e}).toString()}`}function Ke(e){return e}async function W(e,t){let n=await fetch(t,{headers:ge(e),cache:`no-store`});if(!n.ok){let e=(n.headers.get(`content-type`)||``).toLowerCase().trim(),t=`${n.status} ${n.statusText}`;if(e.includes(`application/json`)){let e=await n.json().catch(()=>null);t=e?.error||e?.text||t}else{let e=(await n.text().catch(()=>``)).trim();e&&(t=e)}throw n.status===401&&M(t),Error(t)}return n.blob()}async function qe(e,t){return W(e,Ge(t))}function Je(e,t){return W(e,Ke(t))}var Ye={maxRecentSessions:10,maxSearchResults:50};function Xe(e,t){let[n,r]=(0,U.useState)(e);return(0,U.useEffect)(()=>{let n=window.setTimeout(()=>{r(e)},t);return()=>{window.clearTimeout(n)}},[e,t]),n}var Ze=`[A-Za-z0-9._-]+(?:@[A-Za-z0-9._-]+@[A-Za-z0-9._-]+)?`,G=String.raw`(?=$|[\s:.,!?;)\]}])`;RegExp(`^@(${Ze})${G}`,`u`);var K=RegExp(`@(${Ze})${G}`,`gu`);function Qe(e){let t=[];for(let n of e.matchAll(K)){let r=n[0],i=n[1]??``,a=n.index??0;if(!i)continue;let o=a===0?``:e[a-1];o&&!/[\s([{]/u.test(o)||t.push({mention:r,agentId:i,index:a})}return t}var $e=new Map;function et(e){return String(e??``).trim().toLowerCase()}function q(e,t){let n=e.sessionId??t,r=new Map((e.branchFamilies??[]).map(e=>[`${e.anchorSessionId}:${e.anchorMessageId}`,e.variants])),i=new Map;for(let[e,t]of r.entries()){let r=t.find(e=>e.sessionId===n);r&&i.set(r.messageId,e)}let a=e.history??[],o=et(e.agentId),s=null;return{messages:a.map((e,t)=>{let r=a.slice(t+1).find(e=>e.role!==`system`),c=et(r?.agent_id??r?.assistantPresentation?.agentId),l=e.role===`user`&&r?.role===`assistant`&&c&&c!==o?r?.assistantPresentation??null:null;e.role===`user`&&(s=e.content);let u=e.role===`user`?e.content:e.role===`assistant`?s:null;return{id:H(),role:e.role,content:e.content,rawContent:e.content,sessionId:n,messageId:e.id??null,media:[],artifacts:e.artifacts??[],replayRequest:u===null?null:{content:u,media:[]},assistantPresentation:e.assistantPresentation??null,addressedAgentPresentation:l,responseRating:e.response_rating??null,branchKey:e.id!==void 0&&e.id!==null?i.get(e.id)??null:null}}),branchFamilies:r,requestedSessionId:t,resolvedSessionId:n,agentId:e.agentId?.trim()||null,bootstrapAutostart:e.bootstrapAutostart??null}}function J(e,t){return[`chat-history`,e,t]}async function tt(e,t,n,r){return q(await Le(e,t,80,n,r),t)}var Y=i();function nt(e){let t=de(),n=re(),r=e.searchQuery.trim().length>0;return(0,U.useEffect)(()=>{n.openMobile&&e.onRefreshRecent?.()},[e.onRefreshRecent,n.openMobile]),(0,Y.jsxs)(b,{side:`left`,collapsible:`icon`,children:[(0,Y.jsxs)(u,{children:[(0,Y.jsxs)(`div`,{className:E.headerRow,children:[(0,Y.jsx)(C,{}),(0,Y.jsx)(g,{className:E.sidebarToggle})]}),(0,Y.jsxs)(`button`,{type:`button`,className:R.newChatButton,onClick:e.onNewChat,children:[(0,Y.jsx)(`span`,{"aria-hidden":`true`,children:`+`}),(0,Y.jsx)(`span`,{children:`New Conversation`})]}),(0,Y.jsx)(`div`,{className:R.sidebarSearchWrap,children:(0,Y.jsx)(`input`,{type:`search`,className:R.sidebarSearch,value:e.searchQuery,onChange:t=>e.onSearchQueryChange(t.target.value),placeholder:`Search`,"aria-label":`Search conversations`})})]}),(0,Y.jsx)(T,{children:(0,Y.jsx)(rt,{...e,isSearching:r})}),(0,Y.jsx)(Pe,{children:(0,Y.jsxs)(`div`,{className:E.footerBlock,children:[(0,Y.jsx)(m,{version:t.gatewayStatus?.version}),(0,Y.jsx)(h,{labelClassName:E.themeToggleLabel})]})})]})}function rt(e){return(0,Y.jsxs)(`div`,{className:R.chatSidebarContent,children:[(0,Y.jsxs)(`div`,{className:R.sidebarListHeader,children:[(0,Y.jsx)(`div`,{className:R.sidebarLabel,children:e.isSearching?`Search Results`:`Recent Chats`}),(0,Y.jsx)(`div`,{className:R.sidebarScopeToggle,children:[`user`,`all`].map(t=>(0,Y.jsx)(`button`,{type:`button`,className:I(R.sidebarScopeButton,e.recentScope===t&&R.sidebarScopeButtonActive),"aria-pressed":e.recentScope===t,onClick:()=>e.onRecentScopeChange(t),children:t===`user`?`User`:`All`},t))})]}),e.isLoading&&e.isSearching?(0,Y.jsx)(`div`,{className:R.sidebarStatus,children:`Searching...`}):e.sessions.length===0?(0,Y.jsx)(`div`,{className:R.sidebarStatus,children:e.isSearching?`No matching conversations.`:`No recent chats yet.`}):(0,Y.jsx)(`ul`,{className:R.sessionList,"aria-live":`polite`,children:e.sessions.map(t=>(0,Y.jsx)(`li`,{children:(0,Y.jsxs)(`div`,{className:R.sessionItemRow,children:[(0,Y.jsxs)(`button`,{type:`button`,className:I(R.sessionItem,t.sessionId===e.activeSessionId&&R.sessionItemActive,t.sessionId===e.activeSessionId&&e.isPending&&R.sessionItemPending),"aria-current":t.sessionId===e.activeSessionId?`page`:void 0,onMouseEnter:()=>e.onHoverSession?.(t.sessionId),onClick:()=>e.onOpenSession(t.sessionId),children:[(0,Y.jsx)(`span`,{className:R.sessionTitle,children:t.title||`Untitled`}),t.searchSnippet?(0,Y.jsx)(`span`,{className:R.sessionSnippet,children:t.searchSnippet}):null,(0,Y.jsx)(`span`,{className:R.sessionTime,children:S(t.lastActive)})]}),(0,Y.jsx)(`button`,{type:`button`,className:R.sessionDeleteButton,"aria-label":`Delete ${t.title||`Untitled`} session`,title:`Delete session`,disabled:e.deleteDisabled,onClick:()=>e.onRequestDeleteSession(t),children:(0,Y.jsx)(De,{className:R.sessionDeleteIcon})})]})},t.sessionId))})]})}var it=new Map;function at(e,t){return`${e}\u0000${t}`}function ot(e,t){let n=at(e,t),r=it.get(n);return r||(r={objectUrl:null,loading:!1,promise:null,listeners:new Set},it.set(n,r)),r}function st(e){for(let t of e.listeners)t()}function X(e,t){let n=t?.trim(),r=e.trim();if(!n)return null;let i=ot(r,n);return i.objectUrl?Promise.resolve(i.objectUrl):i.promise?i.promise:(i.loading=!0,i.promise=Je(r,n).then(e=>{let t=URL.createObjectURL(e);return i.objectUrl=t,i.loading=!1,i.promise=null,st(i),t}).catch(()=>(i.objectUrl=null,i.loading=!1,i.promise=null,st(i),null)),st(i),i.promise)}function Z(e){let t=e.token.trim(),n=e.imageUrl?.trim()??``,[r,i]=(0,U.useState)(()=>{if(!n)return{objectUrl:null,loading:!1};let e=ot(t,n);return{objectUrl:e.objectUrl,loading:e.loading}});return(0,U.useEffect)(()=>{if(!n){i({objectUrl:null,loading:!1});return}let e=ot(t,n),r=()=>{i({objectUrl:e.objectUrl,loading:e.loading})};return e.listeners.add(r),r(),X(t,n),()=>{e.listeners.delete(r)}},[t,n]),r}function ct(){return(0,Y.jsx)(`svg`,{"aria-hidden":`true`,focusable:`false`,viewBox:`0 0 24 24`,width:`14`,height:`14`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:(0,Y.jsx)(`path`,{d:`m6 9 6 6 6-6`})})}function lt(e){let t=e.agents.find(t=>t.id===e.selectedAgentId),n=t?.name?.trim()||t?.id||`Agent`,{localAgents:r,remoteGroups:i}=(0,U.useMemo)(()=>{let t=e.agents.filter(e=>e.source?.type!==`remote`),n=new Map;for(let t of e.agents){if(t.source?.type!==`remote`)continue;let e=t.source.instanceId;n.set(e,[...n.get(e)??[],t])}return{localAgents:t,remoteGroups:[...n.entries()]}},[e.agents]),a=i.length>0;return e.agents.length===0?null:(0,Y.jsxs)(N,{value:e.selectedAgentId,disabled:e.disabled,onValueChange:t=>{if(!t||t===e.selectedAgentId)return;let n=e.agents.find(e=>e.id===t);n&&e.onSwitch(n)},children:[(0,Y.jsxs)(j,{className:R.composerPill,"aria-label":`Switch agent`,disabled:e.disabled,children:[(0,Y.jsx)(we,{children:n}),(0,Y.jsx)(ue,{className:R.composerPillChevron,children:(0,Y.jsx)(ct,{})})]}),(0,Y.jsxs)(k,{className:R.agentSelectPopup,children:[a?(0,Y.jsxs)(L,{children:[(0,Y.jsx)(z,{children:`Local`}),r.map(t=>(0,Y.jsx)(ut,{agent:t,token:e.token},t.id))]}):r.map(t=>(0,Y.jsx)(ut,{agent:t,token:e.token},t.id)),i.map(([t,n])=>(0,Y.jsxs)(L,{children:[(0,Y.jsxs)(z,{className:R.remoteAgentGroupLabel,children:[(0,Y.jsx)(Ce,{"aria-hidden":`true`,className:R.remoteAgentGroupIcon,width:13,height:13}),(0,Y.jsx)(`span`,{children:t})]}),n.map(t=>(0,Y.jsx)(ut,{agent:t,token:e.token},t.id))]},t))]})]})}function ut(e){let t=e.agent.name?.trim()||e.agent.id,n=e.agent.source?.type===`remote`;return(0,Y.jsxs)(xe,{value:e.agent.id,textValue:t,className:R.agentSelectItem,children:[(0,Y.jsx)(dt,{agent:e.agent,token:e.token}),n?(0,Y.jsxs)(Ae,{children:[(0,Y.jsx)(`span`,{className:R.agentSelectItemText,children:t}),(0,Y.jsx)(fe,{children:e.agent.id})]}):(0,Y.jsx)(`span`,{className:R.agentSelectItemText,children:t})]})}function dt(e){let t=e.agent.imageUrl?.trim(),n=Z({token:e.token??``,imageUrl:t});return n.objectUrl?(0,Y.jsx)(`img`,{className:R.agentSelectAvatar,src:n.objectUrl,alt:``}):t?(0,Y.jsx)(`span`,{className:R.agentSelectAvatarLoading,"aria-hidden":`true`}):null}function ft(e,t){let n=e.lastIndexOf(`
|
|
2
|
+
`,t-1)+1,r=-1;for(let i=n;i<t;i++)e[i]===`/`&&(i===n||/\s/.test(e[i-1]))&&(r=i);return r===-1?null:{query:e.slice(r+1,t),tokenStart:r}}function pt(e,t){return`${e}-opt-${t}`}function mt({mode:e,kind:t=`slash`,suggestions:n,activeIdx:r,query:i,listboxId:a,token:o,onSelect:s,onActiveChange:c}){(0,U.useEffect)(()=>{e!==`list`||n.length===0||document.getElementById(pt(a,r))?.scrollIntoView({block:`nearest`})},[r,e,n.length,a]);let l=i.trim().toLowerCase(),u=t===`agent`?`@`:`/`,d=t===`agent`?`Agents`:`Slash commands`,f=t===`agent`?`No agents match ${u}${i}`:`No commands match ${u}${i}`;return(0,Y.jsx)(v,{side:`top`,focusOnOpen:`none`,closeOnEscape:!1,closeOnOutsideClick:!0,sideOffset:4,className:R.slashSuggestions,children:(0,Y.jsxs)(P,{className:R.slashSuggestionsScroll,children:[(0,Y.jsx)(se,{id:a,role:`listbox`,"aria-label":d,className:R.slashSuggestionsList,children:e===`list`?n.map((e,n)=>(0,Y.jsxs)(`div`,{id:pt(a,n),className:I(R.suggestionItem,t===`agent`&&R.suggestionItemAgent,n===r&&R.suggestionItemActive,(e.depth??1)>=2&&R.suggestionItemSub),role:`option`,tabIndex:-1,"aria-selected":n===r,onMouseDown:t=>{t.preventDefault(),s(e)},onMouseEnter:()=>c(n),title:e.description||void 0,children:[t===`agent`?(0,Y.jsx)(ht,{item:e,token:o}):null,(0,Y.jsxs)(`span`,{className:R.suggestionText,children:[(0,Y.jsx)(`span`,{className:R.suggestionLabel,children:_t(e.label,l)}),e.description?(0,Y.jsx)(`span`,{className:R.suggestionDesc,children:e.description}):null]})]},e.id)):(0,Y.jsx)(`div`,{className:R.suggestionEmpty,role:`status`,children:f})}),(0,Y.jsx)(_e,{children:(0,Y.jsx)(he,{})})]})})}function ht(e){let t=e.item.imageUrl?.trim(),n=Z({token:e.token??``,imageUrl:t});return n.objectUrl?(0,Y.jsx)(`img`,{className:R.suggestionAvatar,src:n.objectUrl,alt:``}):t?(0,Y.jsx)(`span`,{className:R.suggestionAvatarLoading,"aria-hidden":`true`}):null}var gt=/<[^>]+>|\[[^\]]+\]/g;function _t(e,t){let n=[],r=0,i=0,a=(e,r)=>{if(!e)return;let a=r?R.suggestionLabelMono:void 0,o=t?e.toLowerCase().indexOf(t):-1;n.push(o===-1?(0,Y.jsx)(`span`,{className:a,children:e},i++):(0,Y.jsxs)(`span`,{className:a,children:[e.slice(0,o),(0,Y.jsx)(`mark`,{className:R.suggestionMatch,children:e.slice(o,o+t.length)}),e.slice(o+t.length)]},i++))};for(let t of e.matchAll(gt)){let n=t.index??0;a(e.slice(r,n),!1),a(t[0],!0),r=n+t[0].length}return a(e.slice(r),!1),n}var vt=RegExp(`(?:^|[\\s([{])@([A-Za-z0-9._-]*(?:@[A-Za-z0-9._-]*){0,2})$`,`u`),yt=RegExp(`@(${Ze})(?=$|[\\s:])`,`gu`),bt=RegExp(`^@${Ze}(?=$|[\\s:])\\s*`,`u`);function xt(e,t){let n=e.slice(0,t),r=vt.exec(n);if(!r)return null;let i=r[1]??``;return{tokenStart:n.length-i.length-1,query:i}}function St(e){let t=(0,U.useRef)(null),n=(0,U.useRef)(null),r=(0,U.useRef)(null),[i,a]=(0,U.useState)([]),[o,s]=(0,U.useState)(0),[c,l]=(0,U.useState)([]),[u,d]=(0,U.useState)(`slash`),[f,p]=(0,U.useState)(0),[m,h]=(0,U.useState)(`closed`),[g,_]=(0,U.useState)(``),[v,b]=(0,U.useState)(``),[ee,x]=(0,U.useState)(0),S=(0,U.useRef)(null),C=(0,U.useRef)(null),w=(0,U.useRef)(null),T=(0,U.useRef)(0),ne=(0,U.useRef)(null),re=(0,U.useId)(),ie=m!==`closed`,E=m===`closed`?``:u===`agent`?m===`list`?`${be(c.length,`agent`)} available`:`No agents match @${g}`:m===`list`?`${be(c.length,`command`)} available`:`No commands match /${g}`;(0,U.useEffect)(()=>()=>{C.current&&clearTimeout(C.current),w.current&&clearTimeout(w.current),T.current+=1},[]),(0,U.useEffect)(()=>{let e=r.current;if(!e)return;let t=()=>{let t=e.getBoundingClientRect().height;!Number.isFinite(t)||t<=0||document.documentElement.style.setProperty(`--chat-composer-height`,`${Math.ceil(t)}px`)};t();let n=typeof ResizeObserver>`u`?null:new ResizeObserver(t);return n?.observe(e),window.addEventListener(`resize`,t),()=>{n?.disconnect(),window.removeEventListener(`resize`,t),document.documentElement.style.removeProperty(`--chat-composer-height`)}},[]);let ae=(0,U.useRef)(e.isStreaming);(0,U.useEffect)(()=>{ae.current&&!e.isStreaming&&t.current?.focus(),ae.current=e.isStreaming},[e.isStreaming]);let D=(0,U.useCallback)(()=>{let e=t.current;e&&(e.style.height=`36px`,e.style.height=`${Math.max(36,Math.min(e.scrollHeight,180))}px`)},[]),oe=(0,U.useCallback)(()=>{let e=t.current;e&&x(e.selectionStart??e.value.length)},[]),se=(0,U.useCallback)(e=>{let n=()=>{let n=t.current;if(!n)return;let r=Math.max(0,Math.min(e,n.value.length));n.focus(),n.setSelectionRange(r,r),x(r)};n(),w.current&&clearTimeout(w.current),w.current=setTimeout(()=>{w.current=null,n()},0)},[]);(0,U.useEffect)(()=>{let n=e.initialValue?.trim()||``;if(S.current===n||(S.current=n,!n))return;let r=t.current;r&&(r.value=n,r.setSelectionRange(n.length,n.length),b(n),x(n.length),h(`closed`),T.current+=1,D(),r.focus())},[e.initialValue,D]);let O=(0,U.useCallback)(()=>{C.current&&=(clearTimeout(C.current),null),T.current+=1},[]),k=(0,U.useCallback)(()=>{O(),h(`closed`)},[O]),ce=(0,U.useCallback)(async t=>{let n=T.current;try{let r=await ze(e.token,t||void 0);if(n!==T.current)return;let i=r.commands??[];l(i),p(0),_(t),i.length>0?h(`list`):h(t===``?`closed`:`empty`)}catch{if(n!==T.current)return;l([]),h(`closed`)}},[e.token]),A=(0,U.useCallback)(t=>{let n=t.trim().toLowerCase();return(e.agents??[]).filter(e=>n?e.id.toLowerCase().includes(n)||(e.name??``).toLowerCase().includes(n):!0).map(e=>{let t=e.name?.trim();return{id:`agent:${e.id}`,label:`@${e.id}`,insertText:`@${e.id}`,description:t&&t!==e.id?t:``,imageUrl:e.imageUrl??null}})},[e.agents]);(0,U.useEffect)(()=>{for(let t of e.agents??[])X(e.token,t.imageUrl)},[e.agents,e.token]);let le=()=>{D();let n=t.current;if(!n)return;b(n.value);let r=n.selectionStart??n.value.length;x(r);let i=ft(n.value,r);if(i){let e=i.query.trim();d(`slash`),O(),C.current=setTimeout(()=>{ce(e)},150);return}let a=xt(n.value,r);if(a&&(e.agents?.length??0)>0){O();let e=A(a.query);l(e),d(`agent`),p(0),_(a.query),h(e.length>0?`list`:a.query===``?`closed`:`empty`)}else k()},ue=e=>{let n=t.current;if(!n)return;let r=n.value,i=n.selectionStart??r.length,a=e.insertText.replace(/\s+$/,``),o=n.value.length;if(u===`agent`){let e=xt(r,i);if(e){let t=r.slice(0,e.tokenStart),s=r.slice(i),c=s.startsWith(` `)?a:`${a} `;n.value=t+c+s,o=t.length+c.length,n.setSelectionRange(o,o)}else n.value=`${a} `,o=n.value.length,n.setSelectionRange(o,o);b(n.value),x(o),k(),D(),n.focus();return}let s=ft(r,i);if(s){let e=r.slice(0,s.tokenStart),t=r.slice(i),c=t.startsWith(` `)?a:`${a} `;n.value=e+c+t,o=e.length+c.length,n.setSelectionRange(o,o)}else n.value=`${a} `,o=n.value.length,n.setSelectionRange(o,o);b(n.value),x(o),k(),D(),n.focus()},de=(0,U.useCallback)(e=>{let n=t.current;if(!n)return;let r=`${`@${e}`} `,i=n.value,a=bt.exec(i),o;o=i.trim()?a?`${r}${i.slice(a[0].length).trimStart()}`:`${r}${i.trimStart()}`:r,n.value=o,b(n.value),x(r.length),k(),D(),se(r.length)},[k,D,se]),fe=()=>{if(e.isStreaming){e.onStop();return}let n=(t.current?.value??``).trim();!n&&i.length===0||o>0||(e.onSend(n,i),t.current&&(t.current.value=``),b(``),x(0),a([]),k(),D())},pe=()=>{let e=t.current,n=ne.current;!e||!n||(n.scrollTop=e.scrollTop,n.scrollLeft=e.scrollLeft)},me=e=>{if(!(e.nativeEvent.isComposing||e.nativeEvent.keyCode===229)){if(m===`list`&&c.length>0){if(e.key===`ArrowDown`){e.preventDefault(),p(e=>(e+1)%c.length);return}if(e.key===`ArrowUp`){e.preventDefault(),p(e=>(e-1+c.length)%c.length);return}if(e.key===`Home`){e.preventDefault(),p(0);return}if(e.key===`End`){e.preventDefault(),p(c.length-1);return}if(e.key===`Tab`){e.preventDefault(),ue(c[f]);return}}if(e.key===`Escape`){let t=ie;if(k(),t){e.preventDefault();return}}e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),fe())}},j=e=>{let t=te(e.clipboardData);t.length>0&&(e.preventDefault(),M(t))},M=async t=>{s(e=>e+t.length);try{let n=await e.onUploadFiles(t);n.length>0&&a(e=>[...e,...n])}finally{s(e=>Math.max(0,e-t.length))}},he=e=>{let t=Array.from(e.target.files??[]);t.length>0&&M(t),e.target.value=``},ge=e=>{a(t=>t.filter((t,n)=>n!==e))},_e=e.agents??[],ve=(0,U.useMemo)(()=>new Map(_e.map(e=>[e.id,e])),[_e]),N=e.selectedAgentId??``,ye=e.models??[],xe=e.selectedModelId??``;return(0,Y.jsxs)(`div`,{className:R.composerWrapper,ref:r,children:[(0,Y.jsxs)(y,{open:ie,onOpenChange:e=>{e||k()},children:[(0,Y.jsxs)(`div`,{className:R.composer,children:[i.length>0||o>0?(0,Y.jsxs)(`div`,{className:R.pendingMediaRow,children:[i.map((e,t)=>(0,Y.jsxs)(`span`,{className:R.mediaChip,children:[(0,Y.jsx)(`span`,{className:R.mediaChipName,children:e.filename}),(0,Y.jsx)(`button`,{type:`button`,className:R.mediaChipRemove,onClick:()=>ge(t),children:`×`})]},e.path)),o>0?(0,Y.jsx)(`span`,{className:R.mediaChip,children:`Uploading…`}):null]}):null,(0,Y.jsxs)(Ee,{className:R.composerInputWrap,children:[v?(0,Y.jsx)(`div`,{ref:ne,className:R.composerInputOverlay,"aria-hidden":`true`,children:(0,Y.jsx)(Ct,{value:v,caretIndex:ee,agents:ve,token:e.token})}):null,(0,Y.jsx)(`textarea`,{ref:t,className:I(R.composerInput,v&&R.composerInputHasOverlay),rows:1,placeholder:`Message HybridClaw`,disabled:e.isStreaming,onInput:le,onSelect:oe,onClick:oe,onKeyUp:oe,onFocus:oe,onKeyDown:me,onPaste:j,onScroll:pe,"aria-label":`Message input`,role:`combobox`,"aria-autocomplete":`list`,"aria-haspopup":`listbox`,"aria-controls":re,"aria-expanded":ie,"aria-activedescendant":m===`list`&&c.length>0?pt(re,f):void 0})]}),(0,Y.jsxs)(`div`,{className:R.composerActions,children:[(0,Y.jsxs)(`div`,{className:R.composerLeftActions,children:[(0,Y.jsx)(`button`,{type:`button`,className:R.attachButton,onClick:()=>n.current?.click(),"aria-label":`Attach files`,children:`+`}),(0,Y.jsx)(lt,{agents:_e,selectedAgentId:N,token:e.token,disabled:e.isStreaming,onSwitch:t=>{if(t.source?.type===`remote`){de(t.id);return}e.onAgentSwitch?.(t.id)}}),(0,Y.jsx)(F,{models:ye,selectedModelId:xe,disabled:e.isStreaming,onSwitch:t=>e.onModelSwitch?.(t)})]}),(0,Y.jsx)(`button`,{type:`button`,className:I(R.sendButton,e.isStreaming&&R.stopping),onClick:fe,"aria-label":e.isStreaming?`Stop`:`Send message`,children:e.isStreaming?(0,Y.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`16`,height:`16`,fill:`currentColor`,"aria-hidden":`true`,children:(0,Y.jsx)(`rect`,{x:`6`,y:`6`,width:`12`,height:`12`,rx:`2`})}):(0,Y.jsxs)(`svg`,{viewBox:`0 0 24 24`,width:`16`,height:`16`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.4`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[(0,Y.jsx)(`path`,{d:`M12 19V5`}),(0,Y.jsx)(`path`,{d:`m5 12 7-7 7 7`})]})}),(0,Y.jsx)(`input`,{ref:n,type:`file`,hidden:!0,multiple:!0,onChange:he})]})]}),m===`closed`?null:(0,Y.jsx)(mt,{mode:m,kind:u,suggestions:c,activeIdx:f,query:g,listboxId:re,token:e.token,onSelect:ue,onActiveChange:p})]}),(0,Y.jsx)(`div`,{className:R.slashLiveRegion,"aria-live":`polite`,"aria-atomic":`true`,children:E})]})}function Ct(e){let t=[],n=0,r=0,i=!1,a=Math.max(0,Math.min(e.caretIndex,e.value.length)),o=()=>{i||=(t.push((0,Y.jsx)(`span`,{className:R.composerOverlayCaret,"aria-hidden":`true`},`caret-${r++}`)),!0)},s=(e,n)=>{let r=n+e.length;if(a<n||a>r){t.push(e);return}let i=a-n;i>0&&t.push(e.slice(0,i)),o(),i<e.length&&t.push(e.slice(i))};for(let i of e.value.matchAll(yt)){let c=i[0],l=i[1]??``,u=i.index??0,d=u+c.length,f=e.agents.get(l);f&&(u>n&&s(e.value.slice(n,u),n),a>u&&a<d?s(c,u):(a===u&&o(),t.push((0,Y.jsx)(wt,{mention:c,imageUrl:f.imageUrl??null,token:e.token},`mention-${r++}`)),a===d&&o()),n=d)}return n<e.value.length&&s(e.value.slice(n),n),!i&&a===e.value.length&&o(),t.length>0?t:e.value}function wt(e){let t=Z({token:e.token,imageUrl:e.imageUrl});return(0,Y.jsxs)(`span`,{className:R.composerMentionPill,children:[t.objectUrl?(0,Y.jsx)(`img`,{className:R.composerMentionAvatar,src:t.objectUrl,alt:``}):null,(0,Y.jsx)(`span`,{children:e.mention})]})}var Q={wrap:`_wrap_jrif0_1`,trigger:`_trigger_jrif0_11`,ring:`_ring_jrif0_33`,ringTrack:`_ringTrack_jrif0_37`,ringFill:`_ringFill_jrif0_43`,ringFillNominal:`_ringFillNominal_jrif0_52`,ringFillWarn:`_ringFillWarn_jrif0_56`,ringFillDanger:`_ringFillDanger_jrif0_60`,ringLabel:`_ringLabel_jrif0_64`,ringLabelUnknown:`_ringLabelUnknown_jrif0_77`,popover:`_popover_jrif0_81`,popoverTitle:`_popoverTitle_jrif0_112`,popoverTitleValue:`_popoverTitleValue_jrif0_121`,popoverRow:`_popoverRow_jrif0_126`,popoverRowValue:`_popoverRowValue_jrif0_133`,popoverProgress:`_popoverProgress_jrif0_138`,popoverProgressFill:`_popoverProgressFill_jrif0_148`,popoverProgressFillWarn:`_popoverProgressFillWarn_jrif0_157`,popoverProgressFillDanger:`_popoverProgressFillDanger_jrif0_161`,popoverFoot:`_popoverFoot_jrif0_165`},Tt=14,Et=2*Math.PI*Tt;function $(e){if(e==null)return`n/a`;let t=Math.abs(e);return t>=1e6?`${(t>=1e7?(e/1e6).toFixed(0):(e/1e6).toFixed(1)).replace(/\.0$/,``)}M`:t>=1e3?`${(t>=1e4?(e/1e3).toFixed(0):(e/1e3).toFixed(1)).replace(/\.0$/,``)}k`:String(Math.round(e))}function Dt(e){return e==null||!Number.isFinite(e)?0:Math.max(0,Math.min(100,e))}function Ot(e){return e==null?`nominal`:e>=90?`danger`:e>=70?`warn`:`nominal`}function kt(e){let t=e.sessionId,n=e.enabled&&!!t,r=a({queryKey:[`chat-context`,e.token,t],queryFn:()=>Re(e.token,t),enabled:n,staleTime:15e3,refetchOnWindowFocus:!1}).data?.snapshot??null,i=r?.contextUsagePercent??null,o=Dt(i),s=Ot(i),c=r?.contextBudgetTokens!=null&&r.contextUsedTokens!=null,l=c?Et*(1-o/100):Et,u=i!=null&&Number.isFinite(i)?Math.max(0,Math.round(i)):null,d=u==null?`–`:`${u}%`,f=r&&c&&u!=null?`Context usage ${u} percent (${$(r.contextUsedTokens)} of ${$(r.contextBudgetTokens)} tokens)`:`Context usage unavailable`;return(0,Y.jsxs)(`div`,{className:Q.wrap,children:[(0,Y.jsxs)(`button`,{type:`button`,className:Q.trigger,"aria-label":f,children:[(0,Y.jsxs)(`svg`,{width:34,height:34,viewBox:`0 0 34 34`,className:Q.ring,"aria-hidden":`true`,children:[(0,Y.jsx)(`circle`,{cx:17,cy:17,r:Tt,className:Q.ringTrack}),(0,Y.jsx)(`circle`,{cx:17,cy:17,r:Tt,className:I(Q.ringFill,s===`warn`&&Q.ringFillWarn,s===`danger`&&Q.ringFillDanger,s===`nominal`&&Q.ringFillNominal),strokeDasharray:Et,strokeDashoffset:l})]}),(0,Y.jsx)(`span`,{className:I(Q.ringLabel,u==null&&Q.ringLabelUnknown),children:d})]}),(0,Y.jsxs)(`div`,{role:`tooltip`,className:Q.popover,children:[(0,Y.jsxs)(`div`,{className:Q.popoverTitle,children:[(0,Y.jsx)(`span`,{children:`Context`}),(0,Y.jsx)(`span`,{className:Q.popoverTitleValue,children:r?.model||`unknown model`})]}),r&&c?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`div`,{className:Q.popoverProgress,children:(0,Y.jsx)(`div`,{className:I(Q.popoverProgressFill,s===`warn`&&Q.popoverProgressFillWarn,s===`danger`&&Q.popoverProgressFillDanger),style:{width:`${o}%`}})}),(0,Y.jsxs)(`div`,{className:Q.popoverRow,children:[(0,Y.jsx)(`span`,{children:`Used`}),(0,Y.jsxs)(`span`,{className:Q.popoverRowValue,children:[$(r.contextUsedTokens),` /`,` `,$(r.contextBudgetTokens),` tokens`]})]}),(0,Y.jsxs)(`div`,{className:Q.popoverRow,children:[(0,Y.jsx)(`span`,{children:`Headroom`}),(0,Y.jsxs)(`span`,{className:Q.popoverRowValue,children:[$(r.contextRemainingTokens),` tokens`]})]})]}):(0,Y.jsxs)(`div`,{className:Q.popoverRow,children:[(0,Y.jsx)(`span`,{children:`Used`}),(0,Y.jsx)(`span`,{className:Q.popoverRowValue,children:r?.contextUsedTokens==null?`no usage recorded yet`:`${$(r.contextUsedTokens)} tokens`})]}),(0,Y.jsxs)(`div`,{className:Q.popoverRow,children:[(0,Y.jsx)(`span`,{children:`Compactions`}),(0,Y.jsx)(`span`,{className:Q.popoverRowValue,children:r?`${r.compactionCount} · ${$(r.compactionMessageThreshold)} msgs / ${$(r.compactionTokenBudget)} tokens`:`n/a`})]}),(0,Y.jsxs)(`div`,{className:Q.popoverFoot,children:[`Run `,(0,Y.jsx)(`code`,{children:`/context`}),` for full details · `,(0,Y.jsx)(`code`,{children:`/compact`}),` to archive older history.`]})]})]})}var At=[{label:`Trust session`,action:`session`,isAvailable:e=>e.allowSession===!0},{label:`Trust agent`,action:`agent`,isAvailable:e=>e.allowAgent===!0},{label:`Always allow`,action:`all`,isAvailable:e=>e.allowAll===!0}],jt=/^([^:\n]{2,44}):\s+(.+)$/,Mt=/^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+/i;function Nt(e){return e===`yellow`?`Amber`:e===`red`?`Red`:null}function Pt(e){return/^reply\b/i.test(e)||/^approval expires\b/i.test(e)||/^approval id\b/i.test(e)}function Ft(e){let t=e.trim();return/^proposed action$/i.test(t)?`Request`:/^why$/i.test(t)?`Reason`:t}function It(e){let t=[],n,r=e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);for(let e of r){if(Pt(e)||/^classifier reasoning$/i.test(e)||/^if you skip this/i.test(e))continue;let r=e.match(jt);if(r){let e=Ft(r[1]??``);/^classifier reasoning$/i.test(e)||t.push({label:e,value:r[2]??``});continue}n??=e}return{introLine:n,rows:t}}function Lt(e){let t=[],n=new Set,r=(e,r)=>{let i=e.trim(),a=String(r??``).trim();if(!i||!a)return;let o=`${i.toLowerCase()}:${a}`;n.has(o)||(n.add(o),t.push({label:i,value:a}))};e.intent&&r(`Action`,e.intent),e.commandPreview&&r(Mt.test(e.commandPreview)?`Request`:`Preview`,e.commandPreview),e.toolName&&r(`Tool`,e.toolName);for(let t of It(e.prompt).rows)r(t.label,t.value);if(r(`Approval ID`,e.approvalId),e.expiresAt&&Number.isFinite(e.expiresAt)){let t=new Date(e.expiresAt);Number.isNaN(t.getTime())||r(`Expires`,t.toLocaleTimeString())}return t}function Rt(e){let{introLine:t}=It(e.prompt);return t||(e.summary?e.summary.split(/\r?\n/)[0]??``:e.intent?`Confirmation required for ${e.intent}.`:`Confirmation required before this action can continue.`)}function zt(e){let{approval:t}=e,n=(0,U.useMemo)(()=>Lt(t),[t]),r=(0,U.useMemo)(()=>Rt(t),[t]),i=At.filter(e=>e.isAvailable(t)),a=Nt(t.approvalTier),o=n=>{e.onAction(n,t.approvalId)};return(0,Y.jsxs)(`div`,{className:R.approvalCard,children:[(0,Y.jsxs)(`div`,{className:R.approvalHeader,children:[a?(0,Y.jsx)(`span`,{className:R.approvalTier,children:a}):null,(0,Y.jsx)(`span`,{className:R.approvalTitle,children:`Confirmation required`})]}),(0,Y.jsx)(`p`,{className:R.approvalIntro,children:r}),n.length>0?(0,Y.jsx)(`dl`,{className:R.approvalDetails,children:n.map(e=>(0,Y.jsxs)(`div`,{className:R.approvalDetailRow,children:[(0,Y.jsx)(`dt`,{children:e.label}),(0,Y.jsx)(`dd`,{children:e.value})]},`${e.label}:${e.value}`))}):null,(0,Y.jsxs)(`div`,{className:R.approvalPrimaryActions,children:[(0,Y.jsx)(f,{size:`sm`,disabled:e.busy,onClick:()=>o(`once`),children:`Allow once`}),(0,Y.jsx)(f,{variant:`danger`,size:`sm`,disabled:e.busy,onClick:()=>o(`deny`),children:`Cancel`})]}),i.length>0?(0,Y.jsx)(`div`,{className:R.approvalTrustActions,children:i.map(t=>(0,Y.jsx)(f,{variant:`outline`,size:`sm`,className:R.approvalAllow,disabled:e.busy,onClick:()=>o(t.action),children:t.label},t.action))}):null]})}var Bt=120;function Vt(e,t,n){let[r,i]=(0,U.useState)(e),a=(0,U.useRef)(e),o=(0,U.useRef)(null);a.current=e,(0,U.useEffect)(()=>{if(!t){o.current!==null&&(window.clearTimeout(o.current),o.current=null),i(``);return}if(!n){o.current!==null&&(window.clearTimeout(o.current),o.current=null),i(e);return}o.current!==null||e===r||(o.current=window.setTimeout(()=>{o.current=null,(0,U.startTransition)(()=>{i(a.current)})},Bt))},[e,t,n,r]),(0,U.useEffect)(()=>()=>{o.current!==null&&window.clearTimeout(o.current)},[]);let s=t?n?r:e:``;return(0,U.useMemo)(()=>t?B(s,{highlight:!n}):``,[t,s,n])}var Ht=`<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg>`,Ut=`<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>`,Wt=`<svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 7-5 5 5 5"/><path d="m15 7 5 5-5 5"/><path d="m13.5 5-3 14"/></svg>`,Gt=/^\/([A-Za-z0-9][A-Za-z0-9._-]*)(?=$|[\s:.,!?;)\]}])/u,Kt=new Set([`text`,`plaintext`,`plain`,`txt`]);function qt(e){let t=e.querySelector(`code`)?.className.match(/language-([\w#.+-]+)/)?.[1]??``;return Kt.has(t)?``:t}function Jt(e){if(e.querySelector(`button[data-copy-btn]`))return;let t=qt(e);if(t){e.classList.add(R.codeBlockLabeled);let n=document.createElement(`span`);n.className=R.codeLangLabel,n.setAttribute(`aria-hidden`,`true`),n.innerHTML=Wt;let r=document.createElement(`span`);r.textContent=t,n.appendChild(r),e.appendChild(n)}let n=document.createElement(`button`);n.type=`button`,n.dataset.copyBtn=``,n.className=R.codeCopyButton,n.innerHTML=Ht;let r=e=>{n.setAttribute(`aria-label`,e),n.title=e};r(`Copy code`);let i=null;n.addEventListener(`click`,()=>{je((e.querySelector(`code`)??e).textContent??``).then(e=>{e&&(n.innerHTML=Ut,n.classList.add(R.codeCopyButtonDone),r(`Copied`),i!==null&&window.clearTimeout(i),i=window.setTimeout(()=>{n.innerHTML=Ht,n.classList.remove(R.codeCopyButtonDone),r(`Copy code`)},1500))})}),e.appendChild(n)}function Yt(){let e=(0,U.useRef)(null);return(0,U.useCallback)(t=>{if(e.current?.disconnect(),e.current=null,!t)return;let n=()=>{for(let e of t.querySelectorAll(`pre`))Jt(e)};n();let r=new MutationObserver(n);r.observe(t,{childList:!0,subtree:!0}),e.current=r},[])}function Xt(e,t){let n=t.split(`;`)[0]?.trim().toLowerCase()||``;return!n||n!==`application/pdf`&&!n.startsWith(`image/`)&&!n.startsWith(`video/`)||e.type.toLowerCase()===n?e:new Blob([e],{type:n})}function Zt(e){let{artifact:t,token:n}=e,r=(0,U.useRef)(null),[i,a]=(0,U.useState)(null),[o,s]=(0,U.useState)(!1),c=(t.mimeType??``).toLowerCase(),l=t.filename??`artifact`,u=c.startsWith(`image/`),d=c.startsWith(`video/`)||/\.(mp4|m4v|mov|webm)$/i.test(t.filename??``)||/\.(mp4|m4v|mov|webm)$/i.test(t.path??``),f=c===`application/pdf`||/\.pdf$/i.test(t.filename??``)||/\.pdf$/i.test(t.path??``),p=u||d||f;(0,U.useEffect)(()=>{let e=r.current;if(r.current=null,e&&URL.revokeObjectURL(e),a(null),!p||!t.path)return;let i=!1;return qe(n,t.path).then(e=>{if(i)return;let t=URL.createObjectURL(Xt(e,c));r.current=t,a(t)}).catch(()=>{i||a(null)}),()=>{i=!0;let e=r.current;r.current=null,e&&URL.revokeObjectURL(e)}},[t.path,p,c,n]);let m=o?`Downloading…`:`Download`,h=async()=>{if(!(!t.path||o)){s(!0);try{let e=i??URL.createObjectURL(await qe(n,t.path)),r=document.createElement(`a`);r.href=e,r.download=t.filename??`artifact`,r.rel=`noopener noreferrer`,document.body.appendChild(r),r.click(),r.remove(),i||window.setTimeout(()=>URL.revokeObjectURL(e),0)}catch{}finally{s(!1)}}};return(0,Y.jsxs)(`div`,{className:I(R.artifactCard,i&&R.artifactCardWithPreview),children:[(0,Y.jsxs)(`div`,{className:R.artifactHeader,children:[(0,Y.jsx)(`span`,{className:R.artifactFilename,children:l}),t.type?(0,Y.jsx)(`span`,{className:R.artifactBadge,children:t.type}):null,t.path?(0,Y.jsx)(`button`,{type:`button`,className:R.artifactDownload,disabled:o,onClick:()=>{h()},children:m}):null]}),u&&i?(0,Y.jsx)(`div`,{className:R.artifactPreview,children:(0,Y.jsx)(`img`,{src:i,alt:l})}):null,f&&i?(0,Y.jsx)(`div`,{className:I(R.artifactPreview,R.artifactPdfPreview),children:(0,Y.jsx)(`iframe`,{src:i,title:`${l} preview`,sandbox:``})}):null,d&&i?(0,Y.jsx)(`div`,{className:I(R.artifactPreview,R.artifactVideoPreview),children:(0,Y.jsx)(`video`,{controls:!0,preload:`metadata`,src:i,children:(0,Y.jsxs)(`a`,{href:i,download:l,children:[`Download `,l]})})}):null]})}function Qt(e){let t=(0,U.useRef)(null),[n,r]=(0,U.useState)(null);return(0,U.useEffect)(()=>{let n=t.current;if(t.current=null,n&&URL.revokeObjectURL(n),r(null),!e.imageUrl)return;let i=!1;return Je(e.token,e.imageUrl).then(e=>{if(i)return;let n=URL.createObjectURL(e);t.current=n,r(n)}).catch(()=>{i||r(null)}),()=>{i=!0;let e=t.current;t.current=null,e&&URL.revokeObjectURL(e)}},[e.imageUrl,e.token]),n}var $t=(0,U.memo)(function(e){let{message:t,token:n}=e,[r,i]=(0,U.useState)(!1),a=()=>{e.onCopy(t.rawContent??t.content),i(!0),setTimeout(()=>i(!1),900)},o=(0,U.useMemo)(()=>{let e=new Map;return(t.artifacts??[]).map(t=>{let n=[t.path,t.filename,t.mimeType,t.type].filter(Boolean),r=n.length>0?n.join(`|`):`artifact`,i=e.get(r)??0;return e.set(r,i+1),{artifact:t,key:`${r}:${i}`}})},[t.artifacts]),s=t.role===`approval`,c=s&&!!t.pendingApproval,l=t.role===`assistant`||t.role===`command`||s&&!c,u=Vt(t.content,l,e.isStreaming),d=Yt(),p=t.assistantPresentation,m=p?.displayName??`Assistant`,h=Qt({token:n,imageUrl:p?.imageUrl});if(t.role===`thinking`)return(0,Y.jsxs)(`div`,{className:R.thinking,role:`status`,"aria-label":`Assistant is thinking`,children:[(0,Y.jsx)(`span`,{className:R.thinkingDot}),(0,Y.jsx)(`span`,{className:R.thinkingDot}),(0,Y.jsx)(`span`,{className:R.thinkingDot})]});let g=t.role===`user`,_=t.role===`assistant`,v=g||t.content.trim().length>0||o.length===0||s,y=I(R.messageBlock,g&&R.messageBlockUser,(_||t.role===`system`||t.role===`command`||s)&&R.messageBlockAssistant),b=I(R.bubble,g&&R.bubbleUser,(_||s)&&R.bubbleAssistant,s&&R.bubbleApproval,t.role===`system`&&R.bubbleSystem,t.role===`command`&&R.bubbleCommand);return(0,Y.jsxs)(`div`,{className:y,children:[_?(0,Y.jsxs)(`div`,{className:R.agentLabel,children:[h?(0,Y.jsx)(`img`,{className:R.agentAvatar,src:h,alt:``}):(0,Y.jsx)(`span`,{className:R.agentInitial,children:m.charAt(0).toUpperCase()}),(0,Y.jsx)(`span`,{children:m})]}):null,v?(0,Y.jsx)(`div`,{className:b,children:c&&t.pendingApproval?(0,Y.jsx)(zt,{approval:t.pendingApproval,busy:e.approvalBusy,onAction:e.onApprovalAction}):l?(0,Y.jsx)(`div`,{ref:d,className:R.markdownContent,dangerouslySetInnerHTML:{__html:u}}):g?(0,Y.jsx)(en,{content:t.content,presentation:t.addressedAgentPresentation,skillInvocationTargets:e.skillInvocationTargets,token:n}):t.content}):null,o.map(({artifact:e,key:t})=>(0,Y.jsx)(Zt,{artifact:e,token:n},t)),e.isStreaming?null:(0,Y.jsxs)(`div`,{className:R.messageActions,children:[_&&t.replayRequest?(0,Y.jsx)(f,{variant:`ghost`,size:`icon`,className:R.actionButton,title:`Regenerate`,"aria-label":`Regenerate response`,onClick:()=>e.onRegenerate(t),children:`↻`}):null,_?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(f,{variant:`ghost`,size:`icon`,className:I(R.actionButton,t.responseRating===`up`&&R.actionButtonSelected),title:t.responseRating===`up`?`Clear thumbs up`:`Thumbs up`,"aria-label":t.responseRating===`up`?`Clear thumbs up rating`:`Rate response thumbs up`,"aria-pressed":t.responseRating===`up`,"data-rating-locked":t.responseRating?`true`:void 0,disabled:e.ratingBusy===!0||!t.messageId||t.responseRating===`down`,onClick:()=>e.onRate?.(t,t.responseRating===`up`?null:`up`),children:(0,Y.jsx)(ye,{width:`13`,height:`13`,filled:t.responseRating===`up`})}),(0,Y.jsx)(f,{variant:`ghost`,size:`icon`,className:I(R.actionButton,t.responseRating===`down`&&R.actionButtonSelected),title:t.responseRating===`down`?`Clear thumbs down`:`Thumbs down`,"aria-label":t.responseRating===`down`?`Clear thumbs down rating`:`Rate response thumbs down`,"aria-pressed":t.responseRating===`down`,"data-rating-locked":t.responseRating?`true`:void 0,disabled:e.ratingBusy===!0||!t.messageId||t.responseRating===`up`,onClick:()=>e.onRate?.(t,t.responseRating===`down`?null:`down`),children:(0,Y.jsx)(ce,{width:`13`,height:`13`,filled:t.responseRating===`down`})})]}):null,(0,Y.jsx)(f,{variant:`ghost`,size:`icon`,className:I(R.actionButton,r&&R.actionButtonSuccess),title:`Copy`,"aria-label":r?`Copied`:`Copy message`,onClick:a,children:r?`✓`:`⧉`}),g?(0,Y.jsx)(f,{variant:`ghost`,size:`icon`,className:R.actionButton,title:`Edit`,"aria-label":`Edit message`,onClick:()=>e.onEdit(t),children:`✎`}):null,e.branchInfo&&e.branchInfo.total>1?(0,Y.jsxs)(`div`,{className:R.branchSwitcher,children:[(0,Y.jsx)(f,{variant:`ghost`,size:`icon`,className:R.branchButton,"aria-label":`Previous branch`,disabled:e.branchInfo.current<=1,onClick:()=>e.onBranchNav(t,-1),children:`‹`}),(0,Y.jsxs)(`span`,{children:[e.branchInfo.current,`/`,e.branchInfo.total]}),(0,Y.jsx)(f,{variant:`ghost`,size:`icon`,className:R.branchButton,"aria-label":`Next branch`,disabled:e.branchInfo.current>=e.branchInfo.total,onClick:()=>e.onBranchNav(t,1),children:`›`})]}):null]})]})});function en(e){let t=Qe(e.content),n=[],r=0;for(let[i,a]of t.entries()){a.index>r&&tn(n,e.content.slice(r,a.index),`text-${i}`,r===0,e.skillInvocationTargets);let t=e.presentation?.agentId?.toLowerCase()===a.agentId.toLowerCase()?e.presentation:null;n.push((0,Y.jsx)(nn,{mention:a.mention,imageUrl:t?.imageUrl??null,token:e.token},`${a.index}-${i}`)),r=a.index+a.mention.length}return r<e.content.length&&tn(n,e.content.slice(r),`text-tail`,r===0,e.skillInvocationTargets),(0,Y.jsx)(Y.Fragment,{children:n})}function tn(e,t,n,r,i){if(!t)return;if(!r||!i){e.push(t);return}let a=Gt.exec(t),o=a?.[1]??``,s=i.get(o.toLowerCase());if(!a||!o||!s){e.push(t);return}let c=a[0];e.push((0,Y.jsx)(`a`,{className:R.userSkillCommandLink,href:`/admin/skills/${encodeURIComponent(s)}`,children:c},`${n}-skill-command`));let l=t.slice(c.length);l&&e.push(l)}function nn(e){let t=Qt({token:e.token,imageUrl:e.imageUrl});return(0,Y.jsxs)(`span`,{className:R.userAgentMentionPill,children:[t?(0,Y.jsx)(`img`,{className:R.userAgentMentionAvatar,src:t,alt:``}):null,(0,Y.jsx)(`span`,{children:e.mention})]})}function rn(e){let[t,n]=(0,U.useState)(e.initial);return(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`textarea`,{className:R.editArea,value:t,onChange:e=>n(e.target.value),"aria-label":`Edit message`,autoFocus:!0}),(0,Y.jsxs)(`div`,{className:R.editButtons,children:[(0,Y.jsx)(f,{onClick:()=>e.onSave(t.trim()),disabled:!t.trim(),children:`Save`}),(0,Y.jsx)(f,{variant:`ghost`,onClick:e.onCancel,children:`Cancel`})]})]})}function an(){let e=o({strict:!1}),t=s(),n=e.sessionId,r=(0,U.useRef)(null),i=(0,U.useRef)(new Set);if(!n&&!r.current){let e=d();r.current=e,i.current.add(e)}let a=n??r.current??``,c=(0,U.useRef)(a);c.current=a,(0,U.useEffect)(()=>{n&&(r.current=null)},[n]),(0,U.useEffect)(()=>{a&&p(a)},[a]);let l=(0,U.useCallback)(()=>c.current,[]),u=(0,U.useCallback)((e,n)=>t({to:`/chat/$sessionId`,params:{sessionId:e},...n}),[t]);return(0,U.useEffect)(()=>{n||!a||u(a,{replace:!0})},[u,a,n]),{sessionId:a,getSessionId:l,navigateToSession:u,switchToSession:(0,U.useCallback)((e,t)=>(r.current=e,c.current=e,u(e,t)),[u]),startFreshChat:(0,U.useCallback)(e=>{let t=d();return r.current=t,c.current=t,i.current.add(t),u(t,e),t},[u]),ensureSessionForSend:(0,U.useCallback)(()=>{if(c.current)return c.current;let e=d();return r.current=e,c.current=e,i.current.add(e),u(e,{replace:!0}),e},[u]),isLocallyCreatedSession:(0,U.useCallback)(e=>i.current.has(e),[]),handleSessionIdCorrection:(0,U.useCallback)(e=>{e!==c.current&&u(e,{replace:!0})},[u])}}async function on(e,t){let n=await fetch(e,{method:`POST`,headers:{...ge(t.token,t.body),Accept:`application/x-ndjson`},body:JSON.stringify(t.body),signal:t.signal});n.ok||await le(n);let{callbacks:r}=t,i=e=>{let t=String(e||``).trim();if(!t)return null;let n;try{n=JSON.parse(t)}catch{return console.warn(`Ignoring malformed chat stream line`,t),null}return!n||typeof n!=`object`?null:n.type===`text`&&typeof n.delta==`string`?(r.onTextDelta(n.delta),null):n.type===`approval`&&typeof n.approvalId==`string`&&typeof n.prompt==`string`?(r.onApproval(n),null):n.type===`result`&&n.result&&typeof n.result==`object`?n.result:typeof n.status==`string`&&Array.isArray(n.toolsUsed)?n:null};if(!n.body){let e=await n.text().catch(()=>``),t=null;for(let n of e.split(`
|
|
3
|
+
`)){let e=i(n);e&&(t=e)}if(!t)throw Error(`Chat stream ended without a result payload.`);return t}let a=n.body.getReader(),o=new TextDecoder,s=``,c=null,l=(e=!1)=>{let t=s.split(`
|
|
4
|
+
`),n=e?t.pop()??``:null;s=e?``:t.pop()??``;for(let e of t){let t=i(e);t&&(c=t)}if(e&&n?.trim()){let e=i(n);e&&(c=e)}};try{for(;;){let{done:e,value:t}=await a.read();if(e)break;s+=o.decode(t,{stream:!0}),l()}s+=o.decode(),l(!0)}finally{a.releaseLock()}if(!c)throw Error(`Chat stream ended without a result payload.`);return c}function sn(e){let t=e.trim().split(/\s+/),n=t[0]?.replace(/^\/+/,``).toLowerCase(),r=t[1]?.toLowerCase();return(n===`agent`||n===`agents`)&&(r===`create`||r===`install`)}function cn(e){let t=e.trim().split(/\s+/),n=t[0]?.replace(/^\/+/,``).toLowerCase();if(n!==`agent`&&n!==`agents`||t[1]?.toLowerCase()!==`switch`)return null;let r=t[2]?.trim();return r&&!/\s/.test(r)?r:null}function ln(e){return/^Session agent set to\b/i.test(e.trim())}function un(e){return/\bBOOTSTRAP\.md\b/i.test(e)}function dn(e){let{token:t,userId:r,getSessionId:i,setError:a,refreshRecent:o,onSessionIdCorrection:s,onModelResolved:c,resolveAddressedAgentPresentation:u}=e,d=n(),f=(0,U.useRef)(null),[p,m]=(0,U.useState)(!1),[h,g]=(0,U.useState)(null),[_,v]=(0,U.useState)(null),y=(0,U.useCallback)((e,n)=>{let r=J(t,e);d.setQueryData(r,t=>{let r=t?.messages??[],i=typeof n==`function`?n(r):n;return i===r?t:{messages:i,branchFamilies:t?.branchFamilies??new Map,requestedSessionId:t?.requestedSessionId??e,resolvedSessionId:t?.resolvedSessionId??e,agentId:t?.agentId??null,bootstrapAutostart:t?.bootstrapAutostart??null}})},[d,t]);return{sendMessage:(0,U.useCallback)(async(e,n,p)=>{if(f.current)return a(`Wait for the current run to finish before sending another message.`),!1;let h=i(),_=e=>y(h,e),b=p?.hideUser?null:H();if(a(``),b){let t=u?.(e)??null,r={id:b,role:`user`,content:e,rawContent:e,sessionId:h,media:n,artifacts:[],replayRequest:{content:e,media:n},addressedAgentPresentation:t};_(e=>[...e,r])}let ee=H();_(e=>[...e,{id:ee,role:`thinking`,content:``,sessionId:h}]);let x=H();g(x);let S={controller:new AbortController,sessionId:h,messageRole:`assistant`,assistantText:``,lastRenderedText:``,pendingApproval:null,renderFrame:0,stopping:!1};f.current=S,v(h),m(!0);let C=()=>{if(S.renderFrame=0,S.assistantText===S.lastRenderedText&&!S.pendingApproval)return;S.lastRenderedText=S.assistantText;let e=S.assistantText,t=S.pendingApproval;_(n=>{let r=n.filter(e=>e.id!==ee),i=r.find(e=>e.id===x);return i?r.map(n=>n===i?{...n,role:S.messageRole,content:e,pendingApproval:t}:n):[...r,{id:x,role:S.messageRole,content:e,sessionId:S.sessionId,artifacts:[],pendingApproval:t}]})},w=()=>{S.renderFrame&&=(cancelAnimationFrame(S.renderFrame),0),C()},T=()=>{S.renderFrame||=requestAnimationFrame(C)};try{let i=await on(`/api/chat`,{token:t,body:{sessionId:h,channelId:`web`,userId:r,username:`web`,content:e,stream:!0,...n.length>0?{media:n}:{}},signal:S.controller.signal,callbacks:{onTextDelta:e=>{S.assistantText+=e,T()},onApproval:e=>{S.pendingApproval=e,S.messageRole=`approval`,S.assistantText.trim()||(S.assistantText=A(e)),T()}}});if(i.status===`error`)throw Error(i.error??`Unknown error`);i.sessionId&&i.sessionId!==h&&s(i.sessionId);let a=i.model?.trim();a&&c?.(a),w();let l=i.result??S.assistantText??``,u=S.pendingApproval,f=i.artifacts??[],p=typeof i.addressEnvelope?.to==`string`?i.addressEnvelope.to:null;if(!i.messageRole)throw Error(`Gateway chat result is missing messageRole.`);let m=i.messageRole,g=m===`command`&&l.trim().length===0&&f.length===0,v=(t,r,a)=>({...a,id:t,role:m,content:l,sessionId:r,messageId:i.assistantMessageId??null,artifacts:f,assistantPresentation:i.assistantPresentation??null,pendingApproval:u,responseRating:null,replayRequest:{content:e,media:n}});_(e=>{let t=e.filter(e=>e.id!==ee),n=t.some(e=>e.id===x),r=e=>e.id===x?v(x,i.sessionId??e.sessionId,e):b&&e.id===b&&e.role===`user`?{...e,addressedAgentPresentation:p?i.assistantPresentation??null:null,messageId:e.messageId??i.userMessageId??null,sessionId:i.sessionId??e.sessionId}:e;if(g)return t.filter(e=>e.id!==x).map(r);let a=t.map(r);return n?a:[...a,v(x,i.sessionId??S.sessionId)]}),o();let y=m===`command`&&ln(l)?cn(e):null;if(y){let e=i.sessionId??h,n=J(t,e);d.setQueryData(n,e=>e&&{...e,agentId:y,bootstrapAutostart:un(l)?{status:`starting`,fileName:`BOOTSTRAP.md`}:e.bootstrapAutostart}),d.invalidateQueries({queryKey:n,refetchType:`none`}),d.invalidateQueries({queryKey:[`chat-context`,t,e]})}m===`command`&&sn(e)&&d.invalidateQueries({queryKey:[`agents-list`,t]})}catch(e){S.renderFrame&&cancelAnimationFrame(S.renderFrame);let t=l(e);_(e=>{let n=e.filter(e=>e.id!==ee);return S.stopping?n:[...n,{id:H(),role:`system`,content:`Error: ${t}`,sessionId:h}]})}finally{f.current=null,v(null),m(!1),g(null)}return!0},[t,r,i,y,s,c,u,d,a,o]),stopRequest:(0,U.useCallback)(async()=>{let e=f.current;if(!(!e||e.stopping)){e.stopping=!0;try{await Ue(t,e.sessionId,r,[`stop`])}catch(e){a(`Failed to stop: ${l(e)}`)}finally{e.controller.abort()}}},[t,r,a]),isStreaming:p,streamingMsgId:h,activeSessionId:_,isActive:(0,U.useCallback)(()=>f.current!==null,[])}}var fn=120,pn=220;function mn(){let e=(0,U.useRef)(null),t=(0,U.useRef)(null),n=(0,U.useRef)(null),r=(0,U.useRef)(0),[i,a]=(0,U.useState)(!0),o=(0,U.useRef)(!0),s=(0,U.useRef)(!1),c=(0,U.useCallback)(e=>{o.current!==e&&(o.current=e,a(e))},[]),l=(0,U.useCallback)((e,t)=>{let n=Math.max(0,e.scrollHeight-e.clientHeight),r=Math.max(0,Math.min(t,n));r!==e.scrollTop&&(s.current=!0,e.scrollTop=r)},[]),u=(0,U.useCallback)(()=>{let t=e.current;!t||!o.current||t.scrollHeight<=t.clientHeight||l(t,t.scrollHeight)},[l]),d=(0,U.useCallback)(n=>{if(t.current?.abort(),t.current=null,e.current=n,!n)return;let r=new AbortController;t.current=r,n.addEventListener(`scroll`,()=>{if(s.current){s.current=!1;return}c(n.scrollHeight-n.scrollTop-n.clientHeight<=fn)},{passive:!0,signal:r.signal}),u()},[c,u]),f=(0,U.useCallback)(e=>{if(n.current?.disconnect(),n.current=null,!e||typeof ResizeObserver>`u`)return;let t=new ResizeObserver(()=>u());t.observe(e),n.current=t},[u]),p=(0,U.useCallback)(()=>{let t=e.current;if(!t)return;if(r.current&&=(cancelAnimationFrame(r.current),0),c(!0),typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(`(prefers-reduced-motion: reduce)`).matches){l(t,t.scrollHeight);return}let n=t.scrollTop;if(t.scrollHeight-t.clientHeight-n<=0)return;let i=performance.now(),a=()=>{let t=e.current;if(!t){r.current=0;return}let o=Math.min(1,(performance.now()-i)/pn),s=1-(1-o)**3;l(t,n+(t.scrollHeight-t.clientHeight-n)*s),r.current=o<1?requestAnimationFrame(a):0};r.current=requestAnimationFrame(a)},[c,l]),m=(0,U.useCallback)(()=>{c(!0);let t=e.current;t&&l(t,t.scrollHeight)},[c,l]);return(0,U.useEffect)(()=>()=>{t.current?.abort(),n.current?.disconnect(),r.current&&cancelAnimationFrame(r.current)},[]),{scrollRef:d,contentRef:f,isPinned:i,jumpToBottom:p,resetToBottom:m}}var hn=[],gn=[],_n=5e3,vn=`bootstrap-autostart-thinking`,yn=1500,bn=`Ready to claw through your to-do list?`,xn=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function Sn(){let e=new URLSearchParams(window.location.search).get(`agent`)?.trim();return e&&xn.test(e)?e:``}function Cn(e,t){let n=new Map;if(t.size===0)return n;for(let r of e){let e=r.branchKey;if(!e)continue;let i=t.get(e);if(!i||i.length<2)continue;let a=i.findIndex(e=>e.sessionId===r.sessionId);a<0||n.set(r.id,{current:a+1,total:i.length})}return n}function wn(e,t,n=``,r=`user`){return[`chat-recent`,e,t,n,r]}function Tn(e,t){return[`chat-recent`,e,t]}function En(e,t){return[`chat-context`,e,t]}function Dn(){let e=de(),t=n(),i=(0,U.useRef)(ne()).current,o=(0,U.useMemo)(()=>new URLSearchParams(window.location.search).get(`prompt`)||``,[]),s=(0,U.useMemo)(Sn,[]),[u,d]=(0,U.useState)({message:``,version:0}),f=u.message,p=(0,U.useCallback)(e=>{d(t=>({message:typeof e==`function`?e(t.message):e,version:t.version+1}))},[]),[m,h]=(0,U.useState)(!1),[g,v]=(0,U.useState)(null),[y,b]=(0,U.useState)(!1),[S,C]=(0,U.useState)(null),[T,te]=(0,U.useState)(!1),[re,E]=(0,U.useState)(s||null),[se,O]=(0,U.useState)(``),[k,ce]=(0,U.useState)(`user`),[A,le]=(0,U.useState)(null),[ue,fe]=(0,U.useState)(``),j=(0,U.useRef)(null),M=Xe(ue,160).trim(),{scrollRef:he,contentRef:ge,isPinned:_e,jumpToBottom:N,resetToBottom:ye}=mn(),be=(0,U.useRef)(null),xe=(0,U.useRef)(null);(0,U.useEffect)(()=>{let e=()=>{let e=window.visualViewport?.height??window.innerHeight;!Number.isFinite(e)||e<=0||(document.documentElement.style.setProperty(`--chat-visual-viewport-height`,`${Math.round(e)}px`),document.scrollingElement?.scrollTo({left:0}),document.body.scrollLeft=0,document.documentElement.scrollLeft=0)};return e(),window.addEventListener(`resize`,e),window.addEventListener(`orientationchange`,e),window.visualViewport?.addEventListener(`resize`,e),window.visualViewport?.addEventListener(`scroll`,e),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`orientationchange`,e),window.visualViewport?.removeEventListener(`resize`,e),window.visualViewport?.removeEventListener(`scroll`,e),document.documentElement.style.removeProperty(`--chat-visual-viewport-height`)}},[]);let{sessionId:P,getSessionId:F,navigateToSession:I,switchToSession:L,startFreshChat:Ce,ensureSessionForSend:we,handleSessionIdCorrection:Ee}=an();s&&P&&!j.current&&(j.current=P);let De=P&&j.current===P?s:``,z=(0,U.useCallback)(()=>{t.invalidateQueries({queryKey:Tn(e.token,i)}),t.invalidateQueries({queryKey:J(e.token,F()),refetchType:`none`})},[t,e.token,i,F]),B=Oe(e),Ae=x(e.token),V=a({queryKey:[`app-status`,e.token],queryFn:()=>Me(e.token),staleTime:1/0,enabled:B,initialData:e.status===`ready`&&e.gatewayStatus?e.gatewayStatus:void 0}),Pe=a({queryKey:[`agents-list`,e.token],queryFn:()=>Te(e.token),staleTime:3e4,enabled:B}),Le=a({queryKey:[`models`,e.token],queryFn:()=>Se(e.token),staleTime:3e4,enabled:B}),ze=a({queryKey:[`skills`,e.token],queryFn:()=>ve(e.token),staleTime:6e4,retry:!1,enabled:B});(0,U.useEffect)(()=>{O(V.data?.defaultModel?.trim()??``)},[P,V.data?.defaultModel]),(0,U.useEffect)(()=>{V.error&&(console.error(`Failed to load gateway status for chat page`,V.error),p(`Failed to load the default agent. New chats will use main until gateway status loads.`))},[V.error,p]),(0,U.useEffect)(()=>{Le.error&&(console.error(`Failed to load models list for chat page`,Le.error),p(`Failed to load the model list. Model switching is unavailable.`))},[Le.error,p]);let Ge=a({queryKey:wn(e.token,i,M,k),queryFn:()=>Fe(e.token,i,`web`,M?Ye.maxSearchResults:Ye.maxRecentSessions,M||void 0,k),staleTime:1e4,enabled:B}),Ke=Ge.data?.sessions??[],W=(0,U.useMemo)(()=>(Pe.data??[]).map(e=>({id:e.id,name:e.name,imageUrl:e.imageUrl??null,emptyChatHeader:e.emptyChatHeader??null,source:e.source})),[Pe.data]),qe=(0,U.useMemo)(()=>new Map((ze.data?.skills??[]).filter(e=>e.userInvocable).map(e=>[e.name.toLowerCase(),e.name])),[ze.data?.skills]),Je=(0,U.useCallback)(e=>{let t=Qe(e);for(let e of t){let t=W.find(t=>t.id.toLowerCase()===e.agentId.toLowerCase());if(t)return{agentId:t.id,displayName:t.name??t.id,imageUrl:t.imageUrl??null}}return null},[W]),Ze=Le.data?.models??gn,G=dn({token:e.token,userId:i,getSessionId:F,setError:p,refreshRecent:z,onSessionIdCorrection:Ee,onModelResolved:O,resolveAddressedAgentPresentation:Je});(0,U.useEffect)(()=>{let e=u.message;if(h(!1),!e)return;let t=window.setTimeout(()=>{h(!0)},_n),n=window.setTimeout(()=>{p(``),h(!1)},5200);return()=>{window.clearTimeout(t),window.clearTimeout(n)}},[u,p]);let K=a({queryKey:J(e.token,P),queryFn:()=>tt(e.token,P,i,De||void 0),enabled:B&&!!P,staleTime:1/0}),et=a({queryKey:En(e.token,P),queryFn:()=>Re(e.token,P),enabled:B&&!!P,staleTime:15e3,refetchOnWindowFocus:!1}),q=K.data?.messages??hn,rt=K.data?.bootstrapAutostart?.status===`starting`,it=(0,U.useMemo)(()=>rt?[...q,{id:vn,role:`thinking`,content:``,sessionId:P}]:q,[rt,q,P]),at=K.data?.branchFamilies??$e,ot=re?.trim().toLowerCase()||K.data?.agentId?.trim().toLowerCase()||V.data?.defaultAgentId?.trim().toLowerCase()||`main`,st=W.find(e=>e.id.toLowerCase()===ot)?.emptyChatHeader?.trim()||bn,X=r({mutationFn:t=>pe(e.token,t),onSuccess:n=>{if(!n.deleted){p(`Delete failed: session was not found.`);return}let r=n.sessionId;t.removeQueries({queryKey:J(e.token,r)}),t.removeQueries({queryKey:En(e.token,r)}),t.invalidateQueries({queryKey:Tn(e.token,i)}),t.invalidateQueries({queryKey:[`overview`],refetchType:`none`}),le(null),r===F()&&Ce({replace:!0})},onError:e=>{p(`Delete failed: ${l(e)}`)}}),Z=r({mutationFn:t=>{if(!t.message.messageId)throw Error(`This response cannot be rated right now.`);return He(e.token,{sessionId:t.message.sessionId,messageId:t.message.messageId,userId:i,rating:t.rating})},onSuccess:(n,r)=>{let i=r.message.sessionId;t.setQueryData(J(e.token,i),e=>e&&{...e,messages:e.messages.map(e=>e.messageId===n.messageId?{...e,responseRating:n.rating}:e)})},onError:e=>{p(`Rating failed: ${l(e)}`)}});(0,U.useEffect)(()=>{let e=et.data?.snapshot?.model?.trim()??``;e&&O(e)},[et.data?.snapshot?.model]),(0,U.useEffect)(()=>{if(s&&j.current===P){E(s);return}E(null)},[s,P]),(0,U.useEffect)(()=>{K.error&&p(l(K.error))},[K.error,p]),(0,U.useEffect)(()=>{if(K.data?.bootstrapAutostart?.status!==`starting`||K.isFetching)return;let e=window.setTimeout(()=>{K.refetch()},yn);return()=>window.clearTimeout(e)},[K.data?.bootstrapAutostart?.status,K.isFetching,K.refetch]),(0,U.useEffect)(()=>{if(!S)return;let e=document.body.style.overflow,t=document.activeElement;document.body.style.overflow=`hidden`,xe.current?.focus();let n=e=>{if(e.key===`Escape`){e.preventDefault(),C(null);return}if(e.key!==`Tab`)return;let t=Array.from(be.current?.querySelectorAll(`a[href], button:not(:disabled)`)??[]);if(t.length===0)return;let n=t[0],r=t[t.length-1];e.shiftKey&&document.activeElement===n?(e.preventDefault(),r?.focus()):!e.shiftKey&&document.activeElement===r&&(e.preventDefault(),n?.focus())};return document.addEventListener(`keydown`,n),()=>{document.removeEventListener(`keydown`,n),document.body.style.overflow=e,t instanceof HTMLElement&&t.focus()}},[S]),(0,U.useEffect)(()=>{if(K.isPending||K.fetchStatus!==`idle`||K.data?.requestedSessionId!==P)return;let e=K.data?.resolvedSessionId;!e||e===P||I(e,{replace:!0})},[K.data?.requestedSessionId,K.data?.resolvedSessionId,K.fetchStatus,K.isPending,P,I]);let ct=(0,U.useMemo)(()=>Cn(q,at),[q,at]),lt=(0,U.useRef)(!1);(0,U.useEffect)(()=>{lt.current&&!G.isStreaming&&P&&t.invalidateQueries({queryKey:En(e.token,P)}),lt.current=G.isStreaming},[G.isStreaming,t,e.token,P]),(0,U.useEffect)(()=>{P&&ye()},[P,ye]);let ut=(0,U.useCallback)(async(n,r)=>{if(!n.messageId||!n.sessionId){p(`This message cannot be edited right now.`);return}v(null);try{let a=await Ve(e.token,n.sessionId,n.messageId);t.invalidateQueries({queryKey:J(e.token,n.sessionId),refetchType:`none`}),await t.ensureQueryData({queryKey:J(e.token,a.sessionId),queryFn:()=>tt(e.token,a.sessionId,i)}),await L(a.sessionId),G.sendMessage(r,n.media??[])}catch(e){p(l(e))}},[e.token,t,p,L,G.sendMessage,i]),dt=(0,U.useCallback)(e=>{e.replayRequest&&(N(),G.sendMessage(e.replayRequest.content,e.replayRequest.media,{hideUser:!0}))},[N,G.sendMessage]),ft=(0,U.useCallback)(async(e,t)=>{let n=Ne(e,t);if(n){b(!0);try{N(),await G.sendMessage(n,[],{hideUser:!0})}finally{b(!1)}}},[N,G.sendMessage]),pt=(0,U.useCallback)((e,t)=>{Z.mutate({message:e,rating:t})},[Z]),mt=(0,U.useCallback)(async t=>{let n=await Promise.allSettled(t.map(t=>We(e.token,t))),r=[];for(let e of n)e.status===`fulfilled`&&e.value.media?r.push(e.value.media):e.status===`rejected`&&p(l(e.reason));return r},[e.token,p]),ht=(0,U.useCallback)(n=>{Ie(e.token,{channelId:`web`,keepSessionId:n}).then(n=>{if(n.deletedCount!==0){for(let r of n.deletedSessionIds)t.removeQueries({queryKey:J(e.token,r)}),t.removeQueries({queryKey:En(e.token,r)});t.invalidateQueries({queryKey:Tn(e.token,i)}),t.invalidateQueries({queryKey:[`overview`],refetchType:`none`})}}).catch(e=>{console.warn(`Failed to clean up no-user chat session`,e)})},[e.token,t,i]),gt=(0,U.useCallback)(()=>{if(G.isActive()){p(`Stop the current run before starting a new chat.`);return}ht(Ce()),z()},[G.isActive,Ce,ht,z,p]),_t=(0,U.useCallback)((e,t)=>{we(),N(),G.sendMessage(e,t)},[we,N,G.sendMessage]),vt=(0,U.useCallback)((n,r)=>{let i=r.trim();i&&t.setQueryData(J(e.token,n),e=>{let t=e?.messages??[];return t.some(e=>e.role===`command`&&(e.rawContent||e.content).trim()===i)?e:{messages:[...t,{id:H(),role:`command`,content:i,rawContent:i,sessionId:n,artifacts:[],replayRequest:null}],branchFamilies:e?.branchFamilies??new Map,requestedSessionId:e?.requestedSessionId??n,resolvedSessionId:n,agentId:e?.agentId??null,bootstrapAutostart:e?.bootstrapAutostart??null}})},[e.token,t]),yt=(0,U.useCallback)(async n=>{let r=J(e.token,n);return t.fetchQuery({queryKey:r,queryFn:()=>tt(e.token,n,i),staleTime:0}).catch(e=>(console.warn(`Failed to prefetch chat history before appending switch result`,e),null))},[e.token,t,i]),bt=(0,U.useCallback)(async(n,r,a,o)=>{if(!r||/\s/.test(r))return;if(G.isActive()){p(o);return}we();let s=F();try{let o=await Ue(e.token,s,i,[...n,r]),c=o.sessionId?.trim()||s,l=await yt(c);vt(c,o.text),c!==s&&await L(c,{replace:!0}),t.invalidateQueries({queryKey:En(e.token,c)}),n[0]===`agent`&&n[1]===`switch`&&l?.bootstrapAutostart?.fileName===`BOOTSTRAP.md`&&(l.bootstrapAutostart.status===`idle`||l.bootstrapAutostart.status===`starting`)&&(t.setQueryData(J(e.token,c),e=>e&&{...e,bootstrapAutostart:{status:`starting`,fileName:`BOOTSTRAP.md`}}),N()),z(),a(r)}catch(e){p(l(e))}},[vt,e.token,we,yt,F,N,t,z,p,G.isActive,L,i]),xt=(0,U.useCallback)(e=>bt([`agent`,`switch`],e,E,`Could not switch agent — stop the current run and try again.`),[bt]),Ct=(0,U.useCallback)(e=>bt([`model`,`set`],e,O,`Could not switch model — stop the current run and try again.`),[bt]),wt=(0,U.useCallback)(e=>{if(G.isActive()){p(`Stop the current run before switching chats.`);return}I(e)},[G.isActive,I,p]),Q=(0,U.useCallback)(e=>G.activeSessionId===e?(p(`Stop the current run before deleting this chat.`),!1):!X.isPending,[X.isPending,G.activeSessionId,p]),Tt=(0,U.useCallback)(e=>{Q(e.sessionId)&&le(e)},[Q]),Et=(0,U.useCallback)(()=>{if(!A)throw Error(`Delete confirmation is missing a session.`);Q(A.sessionId)&&X.mutate(A.sessionId)},[Q,X,A]),$=(0,U.useCallback)(n=>{n!==F()&&t.prefetchQuery({queryKey:J(e.token,n),queryFn:()=>tt(e.token,n,i),staleTime:3e4})},[t,e.token,F,i]),Dt=(0,U.useCallback)(()=>{t.invalidateQueries({queryKey:wn(e.token,i,M,k)})},[t,e.token,i,M,k]),Ot=(0,U.useCallback)(async()=>{let t=F();if(!t){p(`Open or send a chat before creating a mobile QR code.`);return}te(!0);try{C(await Be(e.token,{userId:i,sessionId:t,baseUrl:window.location.origin}))}catch(e){p(l(e))}finally{te(!1)}},[e.token,F,i,p]),At=(0,U.useCallback)(e=>{v(e.id)},[]),jt=(0,U.useCallback)((e,t)=>{let n=e.branchKey;if(!n)return;let r=at.get(n);if(!r||r.length<2)return;let i=r.findIndex(t=>t.sessionId===e.sessionId);if(i<0)return;let a=i+t;if(a<0||a>=r.length)return;let o=r[a];o&&wt(o.sessionId)},[at,wt]),Mt=it.length===0,Nt=K.isFetching,Pt={sessions:Ke,activeSessionId:P,onNewChat:gt,onOpenSession:wt,onHoverSession:$,onRequestDeleteSession:Tt,deleteDisabled:X.isPending,isPending:Nt,searchQuery:ue,onSearchQueryChange:fe,recentScope:k,onRecentScopeChange:ce,isLoading:Ge.isFetching,onRefreshRecent:Dt};return(0,Y.jsx)(ie,{children:(0,Y.jsxs)(`div`,{className:R.chatPage,"aria-busy":Nt,children:[(0,Y.jsx)(nt,{...Pt}),(0,Y.jsxs)(`div`,{className:R.chatMain,children:[(0,Y.jsxs)(`div`,{className:R.chatTopbar,children:[(0,Y.jsx)(_,{className:R.chatMobileTrigger}),(0,Y.jsx)(kt,{sessionId:P,token:e.token,enabled:B}),(0,Y.jsx)(`button`,{type:`button`,className:R.mobileQrButton,onClick:()=>void Ot(),disabled:T,"aria-label":`Show mobile QR code`,title:`Show mobile QR code`,children:(0,Y.jsxs)(`span`,{"aria-hidden":`true`,className:R.mobileQrIcon,children:[(0,Y.jsx)(`span`,{}),(0,Y.jsx)(`span`,{}),(0,Y.jsx)(`span`,{}),(0,Y.jsx)(`span`,{})]})}),(0,Y.jsx)(ee,{items:Ae})]}),S?(0,Y.jsx)(`div`,{className:R.mobileQrOverlay,children:(0,Y.jsxs)(`div`,{ref:be,className:R.mobileQrDialog,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`mobile-qr-title`,children:[(0,Y.jsxs)(`div`,{className:R.mobileQrHeader,children:[(0,Y.jsx)(`h2`,{id:`mobile-qr-title`,children:`Open on mobile`}),(0,Y.jsx)(`button`,{ref:xe,type:`button`,className:R.mobileQrClose,onClick:()=>C(null),"aria-label":`Close mobile QR code`,children:`x`})]}),(0,Y.jsx)(`div`,{className:R.mobileQrImage,children:(0,Y.jsx)(`img`,{src:`data:image/svg+xml;charset=utf-8,${encodeURIComponent(S.qrSvg)}`,alt:`Mobile session QR code`})}),(0,Y.jsx)(`a`,{className:R.mobileQrLink,href:S.launchUrl,children:`Open link`})]})}):null,Mt?(0,Y.jsx)(`div`,{className:R.emptyState,children:(0,Y.jsx)(`h1`,{className:R.greeting,children:st})}):(0,Y.jsx)(`div`,{className:R.messageArea,ref:he,children:(0,Y.jsx)(`div`,{className:R.messageList,ref:ge,children:it.map(t=>g===t.id&&t.role!==`thinking`?(0,Y.jsx)(`div`,{className:R.messageBlock,children:(0,Y.jsx)(rn,{initial:t.rawContent??t.content,onSave:e=>void ut(t,e),onCancel:()=>v(null)})},t.id):(0,Y.jsx)($t,{message:t,token:e.token,isStreaming:t.id===G.streamingMsgId,onCopy:je,onEdit:At,onRegenerate:dt,onRate:pt,ratingBusy:Z.isPending&&Z.variables?.message.id===t.id,skillInvocationTargets:qe,onApprovalAction:ft,approvalBusy:y,branchInfo:ct.get(t.id)??null,onBranchNav:jt},t.id))})}),!Mt&&!_e?(0,Y.jsxs)(`button`,{type:`button`,className:R.jumpToLatest,onClick:N,"aria-label":`Jump to latest message`,children:[(0,Y.jsx)(`span`,{"aria-hidden":`true`,children:`↓`}),(0,Y.jsx)(`span`,{children:`Latest`})]}):null,f?(0,Y.jsx)(`div`,{className:`${R.errorBanner} ${m?R.errorBannerExiting:``}`,children:f}):null,(0,Y.jsx)(St,{isStreaming:G.isStreaming,onSend:_t,onStop:()=>void G.stopRequest(),onUploadFiles:mt,token:e.token,agents:W,selectedAgentId:ot,onAgentSwitch:e=>void xt(e),models:Ze,selectedModelId:se,onModelSwitch:e=>void Ct(e),initialValue:o})]}),(0,Y.jsx)(D,{open:A!==null,onOpenChange:e=>{!e&&!X.isPending&&le(null)},children:(0,Y.jsxs)(oe,{size:`sm`,role:`alertdialog`,preventCloseOnOutsideClick:X.isPending,children:[(0,Y.jsxs)(me,{children:[(0,Y.jsx)(ke,{children:`Delete session?`}),(0,Y.jsx)(w,{children:`This permanently removes the conversation and associated session records.`})]}),(0,Y.jsxs)(c,{children:[(0,Y.jsx)(ae,{className:`ghost-button`,disabled:X.isPending,children:`Cancel`}),(0,Y.jsx)(`button`,{type:`button`,className:`danger-button`,disabled:X.isPending,onClick:Et,children:X.isPending?`Deleting...`:`Delete`})]})]})})]})})}export{Dn as ChatPage};
|