import { ChangeDetectionStrategy, Component, computed, effect, ElementRef, inject, signal, viewChild, } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { UiAlert, UiAvatar, UiButton, UiEmpty, UiSkeleton } from '../../../ui'; import { MessageBubbleComponent } from '../../../components/domain/message-bubble/message-bubble'; import { FilePreviewComponent } from '../../../components/preview/file-preview/file-preview'; import { ImageLightboxComponent } from '../../../components/preview/image-lightbox/image-lightbox'; import { previewKindOf } from '../../../components/preview/file-kind'; import { Agent, Message } from '../../../core/api/models'; import { ChatService } from '../../../core/chat.service'; import { crossOwnerWarning, detectCrossOwner } from '../../../core/cross-owner'; import { detectHijack, hijackHint, repliesAfter } from '../../../core/hijack-detect'; import { DeviceService } from '../../../core/device.service'; import { fmtPercent, fmtTokens, usageOf } from '../../../core/format'; import { GroupsService } from '../../../core/groups.service'; import { GroupRolesService } from '../../../core/group-roles.service'; import { LiveService } from '../../../core/live.service'; import { DeliverablesService } from '../../../core/deliverables.service'; import { Deliverable } from '../../../core/api/models'; import { Material, fromAttachment, fromDeliverable, mergeMaterials } from '../../../core/materials'; import { ARTIFACT_HINT, buildContext, looksLikeResume } from '../../../core/group-context'; import { availabilityOf } from '../../../core/target-availability'; import { leaderHealth } from '../../../core/leader-health'; import { MemberTaskStatus, memberTaskStatus } from '../../../core/member-task-timeout'; import { findLastDispatch } from '../../../core/dispatch-check'; import { diagnoseLeader } from '../../../core/leader-membership'; import { LEADER_PROMPT, MEMBER_PROMPT } from '../../../core/workgroup-brief'; import { applyMention, filterMentionCandidates, parseMentionQuery } from '../../../core/mention-autocomplete'; import { MatrixClientService } from '../../../core/matrix-client.service'; import { SessionService } from '../../../core/session.service'; import { FmodeApi } from '../../../core/api/fmode-api'; /** * 桌面·群聊(多数字生命协作) * * ## 与单聊页的区别 * * | | 单聊 `chat.ts` | 群聊(本页) | * |---|---|---| * | 消息归属 | `me` / `agent` 两态 | **每个 agent 都能发言**,要显示是谁 | * | 右栏 | 单容器运行状态 + 成果 | **成员列表**(含各自状态) | * | 输入 | 直接发 | 可 **@ 单个 / @ 多个** | * * ## 实测依据(2026-10-21 P0) * * - 群里 @ 单个 agent:3 秒响应 * - 群里 @ 多个 agent:两个都响应,互不干扰 * - **非主人发言会被拒绝**:容器只认自己的 owner * → 所以群成员必须是同一主人(或已授权的成员) */ @Component({ selector: 'app-dk-group-page', changeDetection: ChangeDetectionStrategy.OnPush, imports: [UiAlert, UiAvatar, UiButton, UiEmpty, UiSkeleton, MessageBubbleComponent, FilePreviewComponent, ImageLightboxComponent], template: `
{{ createError() }}
} @if (newCrossOwnerHint(); as hint) {{{ hint }}
}创建后你和所选数字生命会进入同一个群,可以 @ 一个或多个协作。
组长负责汇总方案、对外沟通;组员负责各自部分。用户据此知道该找谁。