Skip to content

feat(core): implement 2-tier hybrid sync, Telegram & Zalo OA omnichannel gateways, and OpenAI engine - #1

Open
JOY (JOY) wants to merge 28 commits into
mainfrom
dev
Open

feat(core): implement 2-tier hybrid sync, Telegram & Zalo OA omnichannel gateways, and OpenAI engine#1
JOY (JOY) wants to merge 28 commits into
mainfrom
dev

Conversation

@JOY

@JOY JOY (JOY) commented Aug 25, 2026

Copy link
Copy Markdown

Summary

1. Tier 1: Identity & Relational Mirror via Webhook Sync

  • Company & Customer Inbound Sync: Added webhook handlers for company.created, company.updated, customer.created, customer.updated to ingest organizations and contacts from Twenty CRM / DOS.Me.
  • Outbound Event Dispatch: Automated dispatching of company.created and customer.created events with HMAC signature to ORG_SYNC_OUTBOUND_URL.
  • Signature Verification: Updated VerifySignature to support timestamped signatures ( =,v1=) and replay protection.
  • Route Aliases: Registered /crm-sync, /dos-events, and /events endpoints mapping to OrgSyncWebhook.

2. Native Telegram Channel Integration & Automated Zero-Config Webhook

  • Telegram Bot API Client: Implemented standard Telegram client in internal/telegram supporting getMe, setWebhook, deleteWebhook, sendMessage.
  • Automated Webhook Management: Creating or updating a Telegram channel automatically calls Telegram API setWebhook (or deleteWebhook upon disabling/deleting) with the public server URL (PUBLIC_URL / APP_URL).
  • Inbound Message Webhook: /api/third/telegram/webhook/:channel_id ingests customer messages, creates customer profile & conversation, and triggers the AI Agent loop automatically.
  • Outbound Message Delivery: Integrated asynchronous message delivery via TelegramOutboundService and channel outbox queue.

3. Native Zalo Official Account (OA) Channel Integration

  • Zalo OpenAPI Client: Implemented Zalo OA client in internal/zalo supporting Customer Support messaging (/v3.0/oa/message/cs) and user profile retrieval (/v3.0/oa/user/detail).
  • Inbound Webhook Handler: /api/third/zalo/webhook/:channel_id processes Zalo user messages (user_send_text), maps external identities, and starts customer conversations.
  • Outbound Queue Dispatcher: ZaloOAOutboundService asynchronously delivers agent & AI replies to Zalo OA customers via the outbox pattern.

4. OpenAI-Compatible AI Engine & Auto-Bootstrap

  • Added OpenAI-compatible LLM & Embedding provider support with full environment variable configuration (OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_LLM_MODEL, OPENAI_EMBEDDING_MODEL, OPENAI_EMBEDDING_DIMENSION).
  • Auto-seeded official Vietnamese FAQ Knowledge Base (Crove Desk Official FAQ) with vector index initialization on startup.
  • Dynamic branding via COMPANY_NAME and COMPANY_LOGO_URL.

5. Comprehensive Testing & Validation

  • Added unit and integration tests across Telegram, Zalo OA, webhook signatures, and company/customer upserts.
  • All Go tests and Next.js frontend typechecks passing.

Test Plan

  • Run go test -tags dev ./internal/... (all passed)
  • Run pnpm typecheck on frontend (all passed)

Note

Medium Risk
Touches webhook HMAC auth, OIDC token exchange, and new inbound third-party endpoints that create customers/conversations; misconfiguration or weak webhook secrets could allow spoofed events or message injection.

Overview
This PR turns the fork into Crove Desk with richer ops/docs (changelog, expanded .env.example, .gitignore for secrets) and a scheduled GitHub Action that merges upstream huabeitech/agent-desk releases into dev and publishes GHCR images.

Ecosystem sync extends org webhooks: more event names and payload fields, company/customer upsert handlers, outbound company.created / customer.created dispatch with X-DOS-Event, and HMAC verification supporting t=…,v1=… plus replay windows. Extra webhook route aliases (/crm-sync, /dos-events, /events, /ecosystem) hit the same handler.

Omnichannel adds Telegram, Zalo OA, and email as first-class channel types—config parsing, inbound webhooks under /api/third/*, outbox enqueue from agent/AI replies, and cron dispatch. Telegram channels can auto register/delete webhooks from PUBLIC_URL. Email adds a Brevo/SMTP client, inbound parsing (generic + Brevo), and outbound ticket replies.

AI & knowledge: new ai config/env bindings, InitAI upserts default LLM/embedding rows on startup, InitDefaultKnowledgeBase seeds Vietnamese Crove FAQs with background Qdrant indexing, MCP CRM server injection from env, and OIDC client auth style selection. Public API exposes favicon branding.

Tests and live integration suites cover webhooks, channels, and DOS.AI; MCP tool catalog skips failing servers instead of failing the whole catalog.

Reviewed by Cursor Bugbot for commit 3817f4d. Configure here.

…les and dynamic branding

- Add AIConfig environment variable bindings (OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_LLM_MODEL, OPENAI_EMBEDDING_MODEL, etc.)

- Auto-bootstrap and sync LLM and Embedding models to database on startup

- Support dynamic COMPANY_NAME and COMPANY_LOGO_URL in legal document page and support center header

- Add unit tests for AI config initialization and env parsing

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 25, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_324bacf8-7cbf-415b-9d67-f787a31e143f)

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for AI models and OpenAI-compatible providers, bootstrapping default LLM and Embedding configurations on startup. It also adds branding configurations to dynamically customize the brand name and logo across the legal document page and support header. Feedback on these changes highlights a critical issue where user-customized active AI configurations could be silently overwritten on server restart, and suggests returning errors from InitAI rather than always returning nil. Additionally, it is recommended to use the translation helper t("app.brand") as a fallback in the support header instead of hardcoding the brand name.

Comment thread internal/bootstrap/ai.go
Comment on lines +120 to +154
existing := repositories.AIConfigRepository.FindOne(db, sqls.NewCnd().
Eq("model_type", item.ModelType).
Eq("name", item.Name))

if existing == nil {
// Also check if there is an active config of this model type
existing = repositories.AIConfigRepository.GetEnabled(db, item.ModelType)
}

if existing == nil {
item.AuditFields = models.AuditFields{
CreatedAt: now,
CreateUserID: constants.SystemAuditUserID,
CreateUserName: constants.SystemAuditUserName,
UpdatedAt: now,
UpdateUserID: constants.SystemAuditUserID,
UpdateUserName: constants.SystemAuditUserName,
}
return repositories.AIConfigRepository.Create(db, &item)
}

// If existing config exists, update connection & model details to match .env
return repositories.AIConfigRepository.Updates(db, existing.ID, map[string]any{
"provider": item.Provider,
"base_url": item.BaseURL,
"api_key": item.APIKey,
"model_name": item.ModelName,
"dimension": item.Dimension,
"timeout_ms": item.TimeoutMS,
"max_retry_count": item.MaxRetryCount,
"status": enums.StatusOk,
"update_user_id": constants.SystemAuditUserID,
"update_user_name": constants.SystemAuditUserName,
"updated_at": now,
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Overwriting an existing active AI configuration (found via GetEnabled) that was created/customized by the user in the UI is highly destructive. If a user has set up a custom active LLM config, restarting the server with environment variables set will silently overwrite their custom configuration's API key, base URL, and model name.

Instead, we should only update the configuration if it is the bootstrapped one (i.e., its name matches "Default LLM" or "Default Embedding"). If a different active configuration already exists, we should skip bootstrapping entirely to preserve the user's custom database settings.

	existing := repositories.AIConfigRepository.FindOne(db, sqls.NewCnd().
		Eq("model_type", item.ModelType).
		Eq("name", item.Name))

	if existing != nil {
		// If the default config already exists, update connection & model details to match .env
		return repositories.AIConfigRepository.Updates(db, existing.ID, map[string]any{
			"provider":         item.Provider,
			"base_url":         item.BaseURL,
			"api_key":          item.APIKey,
			"model_name":       item.ModelName,
			"dimension":        item.Dimension,
			"timeout_ms":       item.TimeoutMS,
			"max_retry_count":  item.MaxRetryCount,
			"status":           enums.StatusOk,
			"update_user_id":   constants.SystemAuditUserID,
			"update_user_name": constants.SystemAuditUserName,
			"updated_at":       now,
		})
	}

	// Check if there is already an active config of this model type to avoid overwriting custom configs
	if active := repositories.AIConfigRepository.GetEnabled(db, item.ModelType); active != nil {
		return nil
	}

	item.AuditFields = models.AuditFields{
		CreatedAt:      now,
		CreateUserID:   constants.SystemAuditUserID,
		CreateUserName: constants.SystemAuditUserName,
		UpdatedAt:      now,
		UpdateUserID:   constants.SystemAuditUserID,
		UpdateUserName: constants.SystemAuditUserName,
	}
	return repositories.AIConfigRepository.Create(db, &item)

Comment thread internal/bootstrap/ai.go
Comment on lines +85 to +112
if err := upsertBootstrapAIConfig(db, llmItem); err != nil {
slog.Error("failed to bootstrap LLM AI config", "error", err)
} else {
slog.Info("bootstrapped LLM AI config", "model", llmModel, "baseUrl", baseURL)
}

// 2. Ensure Embedding config
embeddingItem := models.AIConfig{
Name: "Default Embedding",
Provider: provider,
BaseURL: baseURL,
APIKey: apiKey,
ModelType: enums.AIModelTypeEmbedding,
ModelName: embeddingModel,
Dimension: dimension,
MaxContextTokens: 8191,
MaxOutputTokens: 0,
TimeoutMS: timeoutMS,
MaxRetryCount: maxRetryCount,
Status: enums.StatusOk,
SortNo: 20,
Remark: "Auto-configured from environment variables",
}
if err := upsertBootstrapAIConfig(db, embeddingItem); err != nil {
slog.Error("failed to bootstrap Embedding AI config", "error", err)
} else {
slog.Info("bootstrapped Embedding AI config", "model", embeddingModel, "dimension", dimension, "baseUrl", baseURL)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The function InitAI has an error return type, but it currently always returns nil even if bootstrapping fails. This makes the error handling in internal/bootstrap/init.go (which logs a warning if InitAI returns an error) dead code.

We should return the error directly when upsertBootstrapAIConfig fails, which also simplifies the code by removing the nested if/else blocks.

	if err := upsertBootstrapAIConfig(db, llmItem); err != nil {
		return err
	}
	slog.Info("bootstrapped LLM AI config", "model", llmModel, "baseUrl", baseURL)

	// 2. Ensure Embedding config
	embeddingItem := models.AIConfig{
		Name:             "Default Embedding",
		Provider:         provider,
		BaseURL:          baseURL,
		APIKey:           apiKey,
		ModelType:        enums.AIModelTypeEmbedding,
		ModelName:        embeddingModel,
		Dimension:        dimension,
		MaxContextTokens: 8191,
		MaxOutputTokens:  0,
		TimeoutMS:        timeoutMS,
		MaxRetryCount:    maxRetryCount,
		Status:           enums.StatusOk,
		SortNo:           20,
		Remark:           "Auto-configured from environment variables",
	}
	if err := upsertBootstrapAIConfig(db, embeddingItem); err != nil {
		return err
	}
	slog.Info("bootstrapped Embedding AI config", "model", embeddingModel, "dimension", dimension, "baseUrl", baseURL)

}
}, [])

const brandName = publicConfig?.companyName || "AGENT DESK"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Avoid hardcoding the fallback brand name as "AGENT DESK". To ensure consistency and support internationalization (i18n), use the translation key t("app.brand") as the fallback, matching the implementation in LegalDocumentPage.

Suggested change
const brandName = publicConfig?.companyName || "AGENT DESK"
const brandName = publicConfig?.companyName || t("app.brand")

….example

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 25, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_482d3695-0a2a-455a-b712-978146ef1b1d)

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 25, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_657069c5-5801-438d-a75f-1d431994841f)

… path lookup

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 25, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_9999a6f4-b2e2-4dcb-883d-74ac5d2eff6d)

…n permissions to existing roles

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 25, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_8da24d82-6550-47e8-92b4-5b601eebce2e)

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agentic security review found one critical issue: this change replaces placeholders in a tracked Docker example config with live production credentials (database password, session secret, AI API key, and OIDC client secret). Restore placeholders and rotate every exposed secret before merging.

Open in Web View Automation 

Sent by Cursor Security Agent: Security Reviewer

Comment thread docker/agent-desk.supabase.example.yaml Outdated
type: postgres
# Supabase Session Pooler (port 5432) with schema desk
dsn: "host=aws-1-ap-southeast-1.pooler.supabase.com user=postgres.gulptwduchsjcsbndmua password=<PASSWORD> dbname=postgres port=5432 sslmode=require search_path=desk"
dsn: "host=aws-1-ap-southeast-1.pooler.supabase.com user=postgres.gulptwduchsjcsbndmua password=06nmFQaSw6nLzWHE dbname=postgres port=5432 sslmode=require search_path=desk"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review
Severity: CRITICAL

This PR replaces documented placeholders in a tracked example config with live production credentials, including the Supabase Postgres password, customer-session HMAC secret, DOS.AI API key, and OIDC client secret for the production project/host in this file.

Impact: Anyone with access to the PR, clone, or git history can authenticate to production data stores, forge customer sessions, call the billed AI provider, and act as the confidential OIDC client. Secrets remain recoverable from git history even after a later revert unless they are rotated.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 60e0840. Configure here.

…x global font inheritance

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 42f698fe-db7c-4462-a2c6-270da092cc14

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Aug 25, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_f1404cd3-a570-4ce6-960e-d60e7ec669b6)

…, and translate AI Agent config workbench

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 25, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_b22fa5b6-049a-4bcd-8c79-71bfb257a148)

…roper Inter font-family

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_66791781-5685-435a-a822-60f3a700915f)

… AI agent loop tests

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_5ad3ff17-9d9c-449f-b539-4e9530e50f74)

…Me organization webhook specs with i18n

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_b5e14455-d72e-4be6-8012-103504571456)

… Admin pages across EN, VI, ZH

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_2e97591e-fe4f-44cb-85ab-9b14161be66a)

…, wxwork outbox, and workflows across EN, VI, and ZH

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_969e618e-3fa6-4a59-8971-211f9480cbd6)

…ities via webhook events

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_5f19e760-e0ee-48d7-9941-6ec56ecb9068)

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_fc640df8-1ba1-457c-a82d-66ce8dfcde36)

…reation and register webhook route aliases

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_dda91314-7d68-41ee-8cf6-9923cd839e88)

…-connect gateway

- Add Telegram Bot API client and types in internal/telegram
- Implement inbound webhook handler and customer message ingestion in TelegramInboundService
- Implement asynchronous outbound message delivery via TelegramOutboundService and channel outbox queue
- Add Telegram channel management and automated setup in Dashboard Channels UI
- Update webhook signature verification and timestamp checking for event synchronizations
- Add full unit and integration tests across Telegram and Webhook services

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_0e7255a3-0c71-4c95-8ac2-b2de6c534cdb)

…upabase example config

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_16035c66-6cf8-4dfd-a93c-71f8416efd4f)

@JOY JOY (JOY) changed the title feat(ai): support OpenAI-compatible API config via environment variables and dynamic branding feat(core): implement 2-tier hybrid sync, native Telegram channel gateway & OpenAI-compatible engine Aug 26, 2026
…am webhook sync

- Add Zalo Official Account client in internal/zalo supporting CS messaging and profile lookup
- Implement Zalo OA inbound webhook handler and outbound queue dispatcher
- Add automated Telegram setWebhook/deleteWebhook trigger on channel create, update, and status change
- Add Zalo OA channel configuration and connection guide to Dashboard Channels UI
- Add comprehensive unit and integration tests for Zalo OA and Telegram webhook lifecycle

Co-authored-by: Cursor <cursoragent@cursor.com>
@JOY JOY (JOY) changed the title feat(core): implement 2-tier hybrid sync, native Telegram channel gateway & OpenAI-compatible engine feat(core): implement 2-tier hybrid sync, Telegram & Zalo OA omnichannel gateways, and OpenAI engine Aug 27, 2026
@cursor

cursor Bot commented Aug 27, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_82cccce4-9ac9-4a90-a010-f7f1f1c4c752)

… OS sync

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 27, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_c7f836dd-8c20-4842-b2f6-0a295d7ac622)

…upport crove_crm MCP namespace

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Aug 27, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_7e7c4f0a-50d7-4e50-b449-07b80203f740)

…ts, and dynamic favicon/title synchronization

- Add companyFaviconUrl to ServerConfig and PublicConfigResponse
- Bind environment variable COMPANY_FAVICON_URL with aliases
- Add native Crove SVG logo (/images/logo.svg) and favicon (/favicon.svg)
- Dynamically update document title and favicon link in AppI18nProvider based on backend public config
- Update Login form and root layouts with branding and metadata icon tags
@cursor

cursor Bot commented Aug 27, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_6a433fc1-0092-4bd7-9209-9f8112bb1cc5)

…nd replace all remaining Chinese strings with i18n

- Change Promise.all to Promise.allSettled in AI Agent workbench so MCP errors do not block loading AI configs and teams
- Gracefully handle MCP server connection errors in ToolCatalogService
- Auto-select first available AI config when creating a new AI Agent
- Localize all hardcoded Chinese toasts, node graphs, and UI warnings across AI Agents and AI Workflows
- Update vi-VN and en-US localization keys for complete multilingual support
@cursor

cursor Bot commented Aug 28, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_99c15346-4d4b-4d60-a811-c9402df510d0)

@cursor

cursor Bot commented Aug 28, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_d63c8e67-60bd-42aa-a659-067e55a1727f)

…d pipeline

- Add .github/workflows/sync-upstream.yml with cron schedule and manual trigger
- Auto-detect new releases from upstream huabeitech/agent-desk and merge into dev
- Create synced GitHub release and tags on repository
- Build & push Docker images for :beta, :<version>, and :latest
- Keep production deployment isolated while generating deployable release artifacts
@cursor

cursor Bot commented Aug 28, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_edb87c5a-13d5-4609-bc65-fb917210bfd9)

…ntegration

- Support inbound email webhook ingestion (/api/third/email/webhook) for Brevo and generic JSON
- Support outbound reply dispatching via Brevo API and standard SMTP with automatic retry
- Map email senders into customer identity (help@crove.com) and trigger AI agent conversation loop
- Add Email Channel configuration UI in Dashboard with full bilingual localization
@cursor

cursor Bot commented Aug 28, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_10085499-7196-4752-81af-855d8e335a97)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant