@wowyuarm/dsh-agent-team 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -11
- package/README.zh.md +17 -11
- package/package.json +61 -47
- package/packages/agent-team/README.md +6 -4
- package/packages/agent-team/README.zh.md +6 -3
- package/packages/agent-team/lib/context-management.js +48 -55
- package/packages/agent-team/lib/context-projection.js +22 -8
- package/packages/agent-team/lib/context-source.js +163 -23
- package/packages/agent-team/lib/index.js +349 -176
- package/packages/agent-team/lib/invariant.js +38 -4
- package/packages/agent-team/lib/ledger.js +658 -294
- package/packages/agent-team/lib/member-context.js +6 -2
- package/packages/agent-team/lib/member-time-context.js +141 -0
- package/packages/agent-team/lib/pressure-policy.js +34 -11
- package/packages/agent-team/lib/progress-nudge.js +12 -4
- package/packages/agent-team/lib/session-event-cursor.js +116 -0
- package/packages/agent-team/lib/session-remediation.js +493 -0
- package/packages/agent-team/lib/spec.js +49 -36
- package/packages/agent-team/lib/stored-session-reader.js +138 -0
- package/packages/agent-team/lib/time-format.js +56 -0
- package/packages/agent-team/lib/typert.host.js +163 -63
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +105 -32
- package/packages/agent-team/lib/types/context-management.d.ts +13 -1
- package/packages/agent-team/lib/types/context-management.d.ts.map +1 -1
- package/packages/agent-team/lib/types/context-projection.d.ts +8 -0
- package/packages/agent-team/lib/types/context-projection.d.ts.map +1 -1
- package/packages/agent-team/lib/types/context-source.d.ts +70 -36
- package/packages/agent-team/lib/types/context-source.d.ts.map +1 -1
- package/packages/agent-team/lib/types/index.d.ts +110 -9
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/invariant.d.ts.map +1 -1
- package/packages/agent-team/lib/types/ledger.d.ts +205 -7
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-time-context.d.ts +83 -0
- package/packages/agent-team/lib/types/member-time-context.d.ts.map +1 -0
- package/packages/agent-team/lib/types/pressure-policy.d.ts +18 -0
- package/packages/agent-team/lib/types/pressure-policy.d.ts.map +1 -1
- package/packages/agent-team/lib/types/progress-nudge.d.ts.map +1 -1
- package/packages/agent-team/lib/types/session-event-cursor.d.ts +119 -0
- package/packages/agent-team/lib/types/session-event-cursor.d.ts.map +1 -0
- package/packages/agent-team/lib/types/session-remediation.d.ts +172 -0
- package/packages/agent-team/lib/types/session-remediation.d.ts.map +1 -0
- package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
- package/packages/agent-team/lib/types/stored-session-reader.d.ts +92 -0
- package/packages/agent-team/lib/types/stored-session-reader.d.ts.map +1 -0
- package/packages/agent-team/lib/types/time-format.d.ts +28 -0
- package/packages/agent-team/lib/types/time-format.d.ts.map +1 -0
- package/packages/agent-team/lib/types/types/entities.d.ts +36 -2
- package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/operations.d.ts +45 -19
- package/packages/agent-team/lib/types/types/operations.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/requests-results.d.ts +50 -3
- package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
- package/packages/agent-team/preset/team-member/agent.cordis.yml +21 -4
- package/packages/client-agent-team/README.md +1 -1
- package/packages/client-agent-team/README.zh.md +1 -1
- package/packages/client-agent-team/lib/client.js +1121 -402
- package/packages/client-agent-team/lib/client.js.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +24 -4
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +42 -22
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +13 -24
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +11 -5
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.js +15 -9
- package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamConversation.js +8 -1
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts +21 -0
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.js +71 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +8 -24
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +9 -2
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMessage.js +13 -6
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +8 -0
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.js +21 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +106 -32
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +50 -7
- package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.js +25 -9
- package/packages/client-agent-team/lib/types/client/locales.d.ts +18 -0
- package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/locales.js +18 -0
- package/packages/client-agent-team/lib/types/client/navigation.d.ts +10 -0
- package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/navigation.js +18 -7
- package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts +41 -0
- package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/scope-coverage.js +64 -0
- package/packages/client-agent-team/lib/types/client/slots.d.ts +8 -2
- package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-changes.d.ts +26 -1
- package/packages/client-agent-team/lib/types/client/team-changes.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-changes.js +66 -15
- package/packages/client-agent-team/lib/types/client/team-dialog-save.d.ts +20 -0
- package/packages/client-agent-team/lib/types/client/team-dialog-save.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/team-dialog-save.js +36 -0
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +9 -0
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-formatters.js +34 -6
- package/packages/tool-agent-team/README.md +8 -6
- package/packages/tool-agent-team/README.zh.md +8 -6
- package/packages/tool-agent-team/lib/context-tools.js +18 -14
- package/packages/tool-agent-team/lib/host-access.js +20 -0
- package/packages/tool-agent-team/lib/index.js +314 -123
- package/packages/tool-agent-team/lib/types/context-tools.d.ts.map +1 -1
- package/packages/tool-agent-team/lib/types/host-access.d.ts +14 -0
- package/packages/tool-agent-team/lib/types/host-access.d.ts.map +1 -0
- package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect,
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Button, IconChevronDownOutline14, Input, Menu, Modal } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
4
|
import { mintRequestId } from "./requests.js";
|
|
5
|
+
import { useEditDialogSave } from "./team-dialog-save.js";
|
|
5
6
|
import createCss from './create.module.css';
|
|
6
7
|
import css from './sidebar.module.css';
|
|
7
8
|
/** Model option key inside one editor; opaque and resolved against the loaded groups. */
|
|
@@ -77,9 +78,11 @@ export function AgentEditorDialog({ status, updateMember, loadModels, onCommitte
|
|
|
77
78
|
const [handle, setHandle] = useState(status.member.handle);
|
|
78
79
|
const [description, setDescription] = useState(status.member.description);
|
|
79
80
|
const [model, setModel] = useState(status.member.model);
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
const { saving, error, pendingRequest, save } = useEditDialogSave({
|
|
82
|
+
save: updateMember,
|
|
83
|
+
onCommitted,
|
|
84
|
+
onClose,
|
|
85
|
+
});
|
|
83
86
|
const dirty = handle.trim() !== status.member.handle || description.trim() !== status.member.description
|
|
84
87
|
|| !sameModel(model, status.member.model);
|
|
85
88
|
const submit = async (event) => {
|
|
@@ -104,26 +107,7 @@ export function AgentEditorDialog({ status, updateMember, loadModels, onCommitte
|
|
|
104
107
|
requestId: mintRequestId(),
|
|
105
108
|
...payload,
|
|
106
109
|
};
|
|
107
|
-
|
|
108
|
-
setSaving(true);
|
|
109
|
-
setError(undefined);
|
|
110
|
-
try {
|
|
111
|
-
const result = await updateMember(request);
|
|
112
|
-
if (result.ok) {
|
|
113
|
-
pendingRequest.current = undefined;
|
|
114
|
-
await onCommitted();
|
|
115
|
-
onClose();
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
setError(result.error.message);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
catch (cause) {
|
|
122
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
123
|
-
}
|
|
124
|
-
finally {
|
|
125
|
-
setSaving(false);
|
|
126
|
-
}
|
|
110
|
+
await save(request);
|
|
127
111
|
};
|
|
128
112
|
return (_jsx(Modal, { open: true, onClose: onClose, title: t('editAgent'), description: `@${status.member.handle}`, closeLabel: t('close'), contentClassName: createCss.dialogContent, footer: _jsxs(_Fragment, { children: [_jsx(Button, { variant: "outline", disabled: saving, onClick: onClose, children: t('cancel') }), _jsx(Button, { type: "submit", form: "team-agent-edit-form", variant: "primary", disabled: saving || !dirty || handle.trim().length === 0, children: saving ? t('editSaving') : t('editSave') })] }), children: _jsxs("form", { id: "team-agent-edit-form", className: createCss.form, onSubmit: event => { void submit(event); }, children: [_jsxs("label", { className: createCss.field, children: [_jsx("span", { children: t('agentName') }), _jsx(Input, { className: createCss.input, value: handle, onChange: event => { setHandle(event.target.value); pendingRequest.current = undefined; }, disabled: saving, autoFocus: true })] }), _jsxs("label", { className: createCss.field, children: [_jsxs("span", { children: [t('agentDescription'), t('optionalSuffix')] }), _jsx(Input, { className: createCss.input, value: description, placeholder: t('agentDescriptionPlaceholder'), onChange: event => { setDescription(event.target.value); pendingRequest.current = undefined; }, disabled: saving })] }), _jsx(ModelPickerField, { model: model, onModelChange: choice => { pendingRequest.current = undefined; setModel(choice); }, loadModels: loadModels, disabled: saving, t: t }), error !== undefined && _jsx("p", { className: createCss.error, role: "alert", children: error })] }) }));
|
|
129
113
|
}
|
|
@@ -27,6 +27,13 @@ export interface TeamMessageProps {
|
|
|
27
27
|
readonly onResolveTaskRefs?: ((taskRefs: readonly AgentTeamTaskRef[]) => Promise<readonly ResolvedTaskRef[]>) | undefined;
|
|
28
28
|
readonly children?: ReactNode;
|
|
29
29
|
}
|
|
30
|
-
/**
|
|
31
|
-
|
|
30
|
+
/**
|
|
31
|
+
* One chat message row with identity chrome and sender-appropriate rendering.
|
|
32
|
+
*
|
|
33
|
+
* Memoized because a timeline row is rendered by the page that owns the whole
|
|
34
|
+
* Thread: the Task-ref subscription below lives inside this component, so
|
|
35
|
+
* skipping a render here never detaches it. Callers must therefore keep the
|
|
36
|
+
* props they derive per render (mention names, ref callbacks) identity-stable.
|
|
37
|
+
*/
|
|
38
|
+
export declare const TeamMessage: import("react").NamedExoticComponent<TeamMessageProps>;
|
|
32
39
|
//# sourceMappingURL=TeamMessage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamMessage.d.ts","sourceRoot":"","sources":["../../../src/client/TeamMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"TeamMessage.d.ts","sourceRoot":"","sources":["../../../src/client/TeamMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0G,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG9I,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACrH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,OAAO,EAA4E,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAI/H,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,uFAAuF;IACvF,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B;2DACuD;IACvD,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,0BAA0B,EAAE,GAAG,SAAS,CAAA;IACxE,6EAA6E;IAC7E,QAAQ,CAAC,cAAc,CAAC,EAAE,qBAAqB,CAAC,eAAe,CAAC,GAAG,SAAS,CAAA;IAC5E,QAAQ,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC,GAAG,CAAC,GAAG,SAAS,CAAA;IACnD,0FAA0F;IAC1F,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACxD,sFAAsF;IACtF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,KAAK,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;IACzH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAC9B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,wDAqHtB,CAAA"}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { MarkdownText,
|
|
2
|
+
import { Fragment, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { MarkdownText, Modal } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
4
|
import { cachedAttachmentDataUrl, formatByteSize, loadAttachmentDataUrl } from "./attachment-preview.js";
|
|
5
5
|
import { cachedResolvedTaskRef, resolveUnknownTaskRefs, useResolvedTaskRefVersion } from "./task-refs.js";
|
|
6
6
|
import { formatMessageTime, isSingleBrandedRef, memberHue, planMessageBody, shouldClampMessage, splitBrandedRefs, splitMentionNames } from "./team-formatters.js";
|
|
7
7
|
import css from './conversation.module.css';
|
|
8
|
-
/**
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* One chat message row with identity chrome and sender-appropriate rendering.
|
|
10
|
+
*
|
|
11
|
+
* Memoized because a timeline row is rendered by the page that owns the whole
|
|
12
|
+
* Thread: the Task-ref subscription below lives inside this component, so
|
|
13
|
+
* skipping a render here never detaches it. Callers must therefore keep the
|
|
14
|
+
* props they derive per render (mention names, ref callbacks) identity-stable.
|
|
15
|
+
*/
|
|
16
|
+
export const TeamMessage = memo(function TeamMessage({ senderName, memberId, human, body, occurredAt, mentionNames, senderTitle, grouped, showGroupedTime, attachments, loadAttachment, t, onOpenRef, onResolveTaskRefs, children }) {
|
|
10
17
|
const avatarStyle = human ? undefined : { '--team-avatar-hue': memberHue(memberId) };
|
|
11
18
|
// Literal bodies carry mention chips inline — Human input always, and
|
|
12
19
|
// plain-prose Agent bodies where literal rendering loses nothing. Rich
|
|
@@ -90,14 +97,14 @@ export function TeamMessage({ senderName, memberId, human, body, occurredAt, men
|
|
|
90
97
|
? _jsx("span", { className: css.mention, children: segment.text }, index)
|
|
91
98
|
: _jsx(Fragment, { children: renderRefs(segment.text, onOpenRef, taskLabel, refLabel) }, index)) })
|
|
92
99
|
: plan.render === 'literal'
|
|
93
|
-
? _jsx("div", { className: css.messageText, children: onOpenRef === undefined ?
|
|
100
|
+
? _jsx("div", { className: css.messageText, children: onOpenRef === undefined ? displayBody : renderRefs(displayBody, onOpenRef, taskLabel, refLabel) })
|
|
94
101
|
: _jsx("div", { ref: markdownRef, className: css.messageMarkdown, children: _jsx(MarkdownText, { text: displayBody, labels: markdownLabels }, `${displayBody}:${onOpenRef === undefined ? 'literal' : 'refs'}`) });
|
|
95
102
|
return (_jsxs("article", { className: css.messageRow, "data-human": human || undefined, "data-grouped": grouped || undefined, children: [_jsx("div", { className: css.messageIdentity, style: avatarStyle, "aria-hidden": "true", children: senderName.replace('@', '').slice(0, 1).toUpperCase() }), _jsxs("div", { className: css.messageBody, children: [(!grouped || showGroupedTime === true) && (_jsxs("div", { className: css.nameRow, children: [!grouped && _jsx("strong", { ...(senderTitle === undefined ? {} : { title: senderTitle }), children: senderName }), occurredAt !== undefined && _jsx("span", { className: css.messageTime, children: formatMessageTime(occurredAt) })] })), clampable ? _jsx("div", { className: clamped ? css.messageClamp : undefined, children: bodyNode }) : bodyNode, clampable && (_jsx("button", { type: "button", className: css.messageExpand, "data-message-expand": "true", "aria-expanded": expanded, onClick: () => { setExpanded(value => !value); }, children: expanded ? (t?.('collapseMessage') ?? 'Show less') : (t?.('expandMessage') ?? 'Show more') })), (plan.fallbackNames.length > 0 || plan.fallbackRefs.length > 0) && (_jsxs("div", { className: css.mentionsRow, children: [plan.fallbackNames.map(name => _jsxs("span", { className: css.mention, children: ["@", name] }, name)), plan.fallbackRefs.map(ref => {
|
|
96
103
|
const resolved = cachedResolvedTaskRef(ref);
|
|
97
104
|
const label = resolved !== undefined && ref.startsWith('task:') ? taskLabel(resolved.taskNumber) : ref;
|
|
98
105
|
return _jsx("button", { type: "button", className: css.refLink, title: ref, onClick: () => { onOpenRef(ref); }, children: label }, ref);
|
|
99
106
|
})] })), attachments !== undefined && attachments.length > 0 && _jsx(TeamAttachmentStrip, { attachments: attachments, ...(loadAttachment === undefined ? {} : { loadAttachment }), ...(t === undefined ? {} : { t }) }), children] })] }));
|
|
100
|
-
}
|
|
107
|
+
});
|
|
101
108
|
/** Text nodes that Markdown rendered as prose rather than code or a link. */
|
|
102
109
|
function markdownProseTextNodes(root) {
|
|
103
110
|
const nodes = [];
|
|
@@ -2,6 +2,14 @@ import type { AgentTeamClientMemberStatus } from '@wowyuarm/dsh-agent-team/types
|
|
|
2
2
|
import type { TeamSidebarProps } from './slots.ts';
|
|
3
3
|
import type { TeamStateDotState } from './TeamStateDot.tsx';
|
|
4
4
|
export declare function presenceLabel(status: AgentTeamClientMemberStatus, t: TeamSidebarProps['t']): string;
|
|
5
|
+
/** One line of human-readable diagnostic text: the reason, plus the refused artifact path when one was reported. */
|
|
6
|
+
export declare function diagnosticText(status: AgentTeamClientMemberStatus): string;
|
|
7
|
+
/**
|
|
8
|
+
* Whether the restart action can help an unavailable Member: it heals
|
|
9
|
+
* transient and repairable failures, but not a transient rollover window
|
|
10
|
+
* (which resolves on its own) or a refusal already proven non-remediable.
|
|
11
|
+
*/
|
|
12
|
+
export declare function restartOffered(status: AgentTeamClientMemberStatus): boolean;
|
|
5
13
|
/** Shared presence → indicator mapping for dots and avatar badges. */
|
|
6
14
|
export declare function presenceDotState(presence: AgentTeamClientMemberStatus['presence']): TeamStateDotState;
|
|
7
15
|
export declare function TeamPresenceDot({ status, t }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamPresenceDot.d.ts","sourceRoot":"","sources":["../../../src/client/TeamPresenceDot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,wBAAgB,aAAa,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,MAAM,CAKnG;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,GAAG,iBAAiB,CAErG;AAED,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;IAC7C,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAA;IAC5C,QAAQ,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAA;CAClC,+BASA"}
|
|
1
|
+
{"version":3,"file":"TeamPresenceDot.d.ts","sourceRoot":"","sources":["../../../src/client/TeamPresenceDot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,wBAAgB,aAAa,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,MAAM,CAKnG;AAED,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,MAAM,EAAE,2BAA2B,GAAG,MAAM,CAI1E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,CAK3E;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,GAAG,iBAAiB,CAErG;AAED,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;IAC7C,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAA;IAC5C,QAAQ,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAA;CAClC,+BASA"}
|
|
@@ -6,7 +6,27 @@ export function presenceLabel(status, t) {
|
|
|
6
6
|
const label = status.presence === 'available' ? t('statusAvailable')
|
|
7
7
|
: status.presence === 'working' ? t('statusWorking')
|
|
8
8
|
: status.presence === 'error' ? t('statusError') : t('statusUnavailable');
|
|
9
|
-
return status.diagnostic === undefined ? label : `${label}: ${status
|
|
9
|
+
return status.diagnostic === undefined ? label : `${label}: ${diagnosticText(status)}`;
|
|
10
|
+
}
|
|
11
|
+
/** One line of human-readable diagnostic text: the reason, plus the refused artifact path when one was reported. */
|
|
12
|
+
export function diagnosticText(status) {
|
|
13
|
+
const diagnostic = status.diagnostic;
|
|
14
|
+
if (diagnostic === undefined)
|
|
15
|
+
return '';
|
|
16
|
+
return diagnostic.location === undefined ? diagnostic.detail : `${diagnostic.detail} (${diagnostic.location.path})`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Whether the restart action can help an unavailable Member: it heals
|
|
20
|
+
* transient and repairable failures, but not a transient rollover window
|
|
21
|
+
* (which resolves on its own) or a refusal already proven non-remediable.
|
|
22
|
+
*/
|
|
23
|
+
export function restartOffered(status) {
|
|
24
|
+
const diagnostic = status.diagnostic;
|
|
25
|
+
if (diagnostic === undefined)
|
|
26
|
+
return true;
|
|
27
|
+
if (diagnostic.class === 'rollover')
|
|
28
|
+
return false;
|
|
29
|
+
return !(diagnostic.class === 'session-refused' && diagnostic.remediable === false);
|
|
10
30
|
}
|
|
11
31
|
/** Shared presence → indicator mapping for dots and avatar badges. */
|
|
12
32
|
export function presenceDotState(presence) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamThreadPage.d.ts","sourceRoot":"","sources":["../../../src/client/TeamThreadPage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"TeamThreadPage.d.ts","sourceRoot":"","sources":["../../../src/client/TeamThreadPage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,mBAAmB,EAInB,gBAAgB,EAGhB,kBAAkB,EAEnB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kDAAkD,CAAA;AAEnF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,aAAa,CAAA;AAe/D,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAA;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAA;IACnC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,CAAA;IAClE,QAAQ,CAAC,YAAY,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IAC5D,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACxD,QAAQ,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAA;IACtE,QAAQ,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,oBAAoB,CAAC,CAAA;IACxE,QAAQ,CAAC,gBAAgB,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,CAAA;IACpE,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC,aAAa,CAAC,CAAA;IAC1D,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAC9D,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAA;IAC9C,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACxD,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAC9D,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAC9D,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAA;IAC9D,QAAQ,CAAC,YAAY,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IAC5D,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,CAAA;IAClE,QAAQ,CAAC,CAAC,EAAE,qBAAqB,CAAC,GAAG,CAAC,CAAA;CACvC;AA+CD,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,+BAmvBxD"}
|
|
@@ -1,24 +1,40 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment, useEffect, useMemo, useRef, useState
|
|
2
|
+
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { Button, DisclosureRow, IconChevronLeftOutline14, IconChecklistOutline14, Modal, Pill } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
4
|
import { TeamComposer } from "./TeamComposer.js";
|
|
5
|
-
import { TeamPresenceDot } from "./TeamPresenceDot.js";
|
|
5
|
+
import { diagnosticText, TeamPresenceDot } from "./TeamPresenceDot.js";
|
|
6
6
|
import { TeamMessage } from "./TeamMessage.js";
|
|
7
7
|
import { TeamRunDivider } from "./TeamRunDivider.js";
|
|
8
8
|
import { formatActivity, formatClaimState, formatTaskStatus, formatTaskTitle, mentionNamesOf, taskStatusDot } from "./team-formatters.js";
|
|
9
9
|
import { TeamStateDot } from "./TeamStateDot.js";
|
|
10
|
-
import { mintRequestId } from "./requests.js";
|
|
10
|
+
import { mintRequestId, uploadComposerFiles } from "./requests.js";
|
|
11
|
+
import { ScopeCoverage } from "./scope-coverage.js";
|
|
11
12
|
import { daySeparatorLabel, isRunGap, timelineDayKey } from "./team-separators.js";
|
|
12
13
|
import { useTimelineScroll } from "./timeline-scroll.js";
|
|
13
14
|
import { hostTaskRefLookup, jumpToTaskThread } from "./task-refs.js";
|
|
14
|
-
import { bytesToBase64 } from "./attachment-preview.js";
|
|
15
15
|
import css from './conversation.module.css';
|
|
16
16
|
import threadCss from './thread.module.css';
|
|
17
17
|
function factKey(fact) {
|
|
18
18
|
return fact.kind === 'message' ? `message:${fact.message.messageRef}` : `activity:${fact.activity.activityRef}`;
|
|
19
19
|
}
|
|
20
20
|
function messageFact(message, mentions = []) {
|
|
21
|
-
return { kind: 'message', sequence: message.sequence, message, mentions };
|
|
21
|
+
return { kind: 'message', sequence: message.sequence, message, mentions, occurredAt: message.occurredAt };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A fact owns its mention array, so the rendered name list is cached against
|
|
25
|
+
* that array. Every roster refresh replaces the handles map with a fresh Map of
|
|
26
|
+
* identical content, so the cache compares the resolved names rather than the
|
|
27
|
+
* map identity: identity stays stable while the names are unchanged, which is
|
|
28
|
+
* what keeps a memoized row from re-rendering on every refresh.
|
|
29
|
+
*/
|
|
30
|
+
const mentionNamesCache = new WeakMap();
|
|
31
|
+
function stableMentionNames(mentions, handles) {
|
|
32
|
+
const names = mentionNamesOf(mentions, handles);
|
|
33
|
+
const cached = mentionNamesCache.get(mentions);
|
|
34
|
+
if (cached !== undefined && cached.length === names.length && cached.every((name, index) => name === names[index]))
|
|
35
|
+
return cached;
|
|
36
|
+
mentionNamesCache.set(mentions, names);
|
|
37
|
+
return names;
|
|
22
38
|
}
|
|
23
39
|
function mergeFacts(...groups) {
|
|
24
40
|
const byKey = new Map();
|
|
@@ -57,8 +73,9 @@ export function TeamThreadPage(props) {
|
|
|
57
73
|
const [newFactsCount, setNewFactsCount] = useState(0);
|
|
58
74
|
// The reply draft lives in the keyed draft cache: view switches unmount
|
|
59
75
|
// this page, and a refresh must not cost the half-written message either.
|
|
76
|
+
// The composer owns the subscription — this page only reads a snapshot when
|
|
77
|
+
// it sends, so typing never re-renders the timeline.
|
|
60
78
|
const draftKey = `thread:${threadRef}`;
|
|
61
|
-
const { draft, recipients } = useSyncExternalStore(drafts.subscribe, () => drafts.getSnapshot(draftKey));
|
|
62
79
|
const [claimsOpen, setClaimsOpen] = useState(false);
|
|
63
80
|
// Early acceptance: the Human may accept while Claims are still open; the
|
|
64
81
|
// confirm dialog lists exactly what will be completed with the Task.
|
|
@@ -148,14 +165,15 @@ export function TeamThreadPage(props) {
|
|
|
148
165
|
setLoading(false);
|
|
149
166
|
}
|
|
150
167
|
};
|
|
151
|
-
|
|
168
|
+
/** One roster + view read. Answers false once the page is gone. */
|
|
169
|
+
const applySupplemental = async () => {
|
|
152
170
|
try {
|
|
153
171
|
const [loadedMembers, loadedView] = await Promise.all([
|
|
154
172
|
loadMembers({ workspaceId }),
|
|
155
173
|
loadChannels({ workspaceId, ...(channelRef === undefined ? {} : { channelRef }), threadRef, includeActivities: false, limit: 1 }),
|
|
156
174
|
]);
|
|
157
175
|
if (!mountedRef.current)
|
|
158
|
-
return;
|
|
176
|
+
return false;
|
|
159
177
|
if (loadedMembers.ok)
|
|
160
178
|
setMembers(loadedMembers.value);
|
|
161
179
|
if (loadedView.ok)
|
|
@@ -163,12 +181,49 @@ export function TeamThreadPage(props) {
|
|
|
163
181
|
const failure = [loadedMembers, loadedView].find(result => !result.ok);
|
|
164
182
|
if (failure !== undefined && !failure.ok)
|
|
165
183
|
setError(failure.error.message);
|
|
184
|
+
return true;
|
|
166
185
|
}
|
|
167
186
|
catch (cause) {
|
|
168
187
|
if (mountedRef.current)
|
|
169
188
|
setError(cause instanceof Error ? cause.message : String(cause));
|
|
189
|
+
return mountedRef.current;
|
|
170
190
|
}
|
|
171
191
|
};
|
|
192
|
+
// One Host change event wakes every scope it matches: here a workspace commit
|
|
193
|
+
// and a presence transition, whose separate polls both deliver that event's
|
|
194
|
+
// version. Both asks are the same roster and view read, so each round answers
|
|
195
|
+
// one version per scope, and a newer version arriving mid-round runs one
|
|
196
|
+
// trailing round instead of being dropped. The two scopes count different
|
|
197
|
+
// domains, so coverage and pending versions are tracked per scope.
|
|
198
|
+
const supplementalRef = useRef();
|
|
199
|
+
const supplementalCoverageRef = useRef(new ScopeCoverage());
|
|
200
|
+
const refreshSupplemental = (wake) => {
|
|
201
|
+
const inFlight = supplementalRef.current;
|
|
202
|
+
if (wake === undefined) {
|
|
203
|
+
if (inFlight !== undefined)
|
|
204
|
+
return inFlight;
|
|
205
|
+
}
|
|
206
|
+
else if (!supplementalCoverageRef.current.wake(wake.scope, wake.version)) {
|
|
207
|
+
return inFlight ?? Promise.resolve();
|
|
208
|
+
}
|
|
209
|
+
const coverage = supplementalCoverageRef.current;
|
|
210
|
+
const round = (async () => {
|
|
211
|
+
for (;;) {
|
|
212
|
+
coverage.beginRound();
|
|
213
|
+
const applied = await applySupplemental();
|
|
214
|
+
// A newer change landed while this round fetched: cover it too, and
|
|
215
|
+
// keep going only while the page is still the one asking.
|
|
216
|
+
if (!applied || !coverage.finishRound())
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
})().finally(() => {
|
|
220
|
+
// A remount may already own a newer round; only this one clears itself.
|
|
221
|
+
if (supplementalRef.current === round)
|
|
222
|
+
supplementalRef.current = undefined;
|
|
223
|
+
});
|
|
224
|
+
supplementalRef.current = round;
|
|
225
|
+
return round;
|
|
226
|
+
};
|
|
172
227
|
const refreshPassiveFacts = async () => {
|
|
173
228
|
try {
|
|
174
229
|
const result = await loadThreadHistory({ workspaceId, ...threadRequest, limit: 100 });
|
|
@@ -226,6 +281,9 @@ export function TeamThreadPage(props) {
|
|
|
226
281
|
};
|
|
227
282
|
useEffect(() => {
|
|
228
283
|
mountedRef.current = true;
|
|
284
|
+
// The previous mount's supplemental round must not answer for this one.
|
|
285
|
+
supplementalRef.current = undefined;
|
|
286
|
+
supplementalCoverageRef.current.reset();
|
|
229
287
|
projectionRef.current = undefined;
|
|
230
288
|
setProjection(undefined);
|
|
231
289
|
setChannelView(undefined);
|
|
@@ -298,7 +356,19 @@ export function TeamThreadPage(props) {
|
|
|
298
356
|
setError(update.message);
|
|
299
357
|
return;
|
|
300
358
|
}
|
|
301
|
-
void refreshSupplemental();
|
|
359
|
+
void refreshSupplemental({ scope: 'workspace', version: update.version });
|
|
360
|
+
}),
|
|
361
|
+
// Presence transitions commit nothing: only the member rows move, so
|
|
362
|
+
// the roster refresh rides the same supplemental fetch as workspace
|
|
363
|
+
// membership changes, leaving the timeline untouched.
|
|
364
|
+
subscribeChanges({ kind: 'presence', workspaceId }, update => {
|
|
365
|
+
if (!mountedRef.current)
|
|
366
|
+
return;
|
|
367
|
+
if (update.type === 'failed') {
|
|
368
|
+
setError(update.message);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
void refreshSupplemental({ scope: 'presence', version: update.version });
|
|
302
372
|
}),
|
|
303
373
|
];
|
|
304
374
|
return () => {
|
|
@@ -378,7 +448,8 @@ export function TeamThreadPage(props) {
|
|
|
378
448
|
// Branded-ref navigation for message bodies: channel refs hop to the
|
|
379
449
|
// Channel; the open Task's own refs are already on screen, and other Tasks
|
|
380
450
|
// are not resolvable from this surface, so they degrade to a no-op.
|
|
381
|
-
|
|
451
|
+
// Identity-stable: a fresh closure per render would defeat TeamMessage's memo.
|
|
452
|
+
const openRef = useCallback((ref) => {
|
|
382
453
|
if (ref.startsWith('channel:') && ref !== channelRef) {
|
|
383
454
|
selectChannel(ref);
|
|
384
455
|
return;
|
|
@@ -402,13 +473,13 @@ export function TeamThreadPage(props) {
|
|
|
402
473
|
// Another Task cited here: resolve its home Channel and jump.
|
|
403
474
|
jumpToTaskThread(resolveTaskRefs, workspaceId, ref, selectThread);
|
|
404
475
|
}
|
|
405
|
-
};
|
|
406
|
-
const lookupTaskRefs = hostTaskRefLookup(resolveTaskRefs, workspaceId);
|
|
476
|
+
}, [channelRef, threadRef, taskRef, workspaceId, selectChannel, selectThread, loadChannels, resolveTaskRefs]);
|
|
477
|
+
const lookupTaskRefs = useMemo(() => hostTaskRefLookup(resolveTaskRefs, workspaceId), [resolveTaskRefs, workspaceId]);
|
|
407
478
|
const renderFact = (fact, grouped = false) => {
|
|
408
479
|
if (fact.kind === 'message') {
|
|
409
480
|
const sender = memberName(fact.message.sender);
|
|
410
481
|
const senderStatus = members.find(candidate => candidate.member.memberId === fact.message.sender);
|
|
411
|
-
return _jsx(TeamMessage, { senderName: sender, memberId: fact.message.sender, human: fact.message.sender === channelView?.humanMemberId, body: fact.message.body, attachments: fact.message.attachments, loadAttachment: getAttachment, t: t, occurredAt: fact.message.occurredAt, mentionNames:
|
|
482
|
+
return _jsx(TeamMessage, { senderName: sender, memberId: fact.message.sender, human: fact.message.sender === channelView?.humanMemberId, body: fact.message.body, attachments: fact.message.attachments, loadAttachment: getAttachment, t: t, occurredAt: fact.message.occurredAt, mentionNames: stableMentionNames(fact.mentions, mentionHandlesMap), onOpenRef: openRef, onResolveTaskRefs: lookupTaskRefs, grouped: grouped, ...(senderStatus === undefined ? {} : { senderTitle: senderStatus.member.description }) }, factKey(fact));
|
|
412
483
|
}
|
|
413
484
|
return _jsxs("p", { className: threadCss.activityRow, children: [_jsx("span", { className: threadCss.activityMark, "aria-hidden": "true" }), _jsx("span", { className: threadCss.activityText, children: formatActivity(fact.activity, { t, actorName: memberName, claims: taskClaims }) })] }, factKey(fact));
|
|
414
485
|
};
|
|
@@ -480,7 +551,7 @@ export function TeamThreadPage(props) {
|
|
|
480
551
|
setProjection(current => current === undefined ? current
|
|
481
552
|
: { ...current, task: committed.task, thread: committed.thread });
|
|
482
553
|
setCurrentFacts(current => {
|
|
483
|
-
const merged = mergeFacts(current, [{ kind: 'activity', sequence: committed.activity.sequence, activity: committed.activity }]);
|
|
554
|
+
const merged = mergeFacts(current, [{ kind: 'activity', sequence: committed.activity.sequence, activity: committed.activity, occurredAt: committed.receipt.occurredAt }]);
|
|
484
555
|
currentFactsRef.current = merged;
|
|
485
556
|
return merged;
|
|
486
557
|
});
|
|
@@ -527,7 +598,7 @@ export function TeamThreadPage(props) {
|
|
|
527
598
|
const committed = result.value;
|
|
528
599
|
setProjection(current => current === undefined ? current : { ...current, task: committed.task, thread: committed.thread, claims: committed.claims });
|
|
529
600
|
setCurrentFacts(current => {
|
|
530
|
-
const merged = mergeFacts(current, [{ kind: 'activity', sequence: committed.activity.sequence, activity: committed.activity }]);
|
|
601
|
+
const merged = mergeFacts(current, [{ kind: 'activity', sequence: committed.activity.sequence, activity: committed.activity, occurredAt: committed.receipt.occurredAt }]);
|
|
531
602
|
currentFactsRef.current = merged;
|
|
532
603
|
return merged;
|
|
533
604
|
});
|
|
@@ -553,7 +624,19 @@ export function TeamThreadPage(props) {
|
|
|
553
624
|
setMutating(undefined);
|
|
554
625
|
}
|
|
555
626
|
};
|
|
627
|
+
// Editing the draft invalidates one-shot send state: a confirmation token,
|
|
628
|
+
// the retained requestId, and the status line. Every setter returns the same
|
|
629
|
+
// state when there is nothing to clear, so a keystroke does not re-render the
|
|
630
|
+
// timeline now that the composer owns the draft.
|
|
631
|
+
const clearSendState = useCallback(() => {
|
|
632
|
+
setConfirmation(current => current === undefined ? current : undefined);
|
|
633
|
+
setReplyRequestId(current => current === undefined ? current : undefined);
|
|
634
|
+
setStatusMessage(current => current === undefined ? current : undefined);
|
|
635
|
+
}, []);
|
|
556
636
|
const sendReply = async () => {
|
|
637
|
+
// Read the draft at send time: this page no longer subscribes to it, so a
|
|
638
|
+
// captured render value would be stale after the composer's own edits.
|
|
639
|
+
const { draft, recipients } = drafts.getSnapshot(draftKey);
|
|
557
640
|
if (pending || thread === undefined || draft.trim() === '')
|
|
558
641
|
return;
|
|
559
642
|
const id = replyRequestId ?? mintRequestId();
|
|
@@ -563,21 +646,12 @@ export function TeamThreadPage(props) {
|
|
|
563
646
|
try {
|
|
564
647
|
// Upload chosen files first; any failure aborts the reply with the
|
|
565
648
|
// existing error surface and keeps the chips for a retry.
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
workspaceId,
|
|
571
|
-
name: file.name,
|
|
572
|
-
mediaType: file.type === '' ? undefined : file.type,
|
|
573
|
-
bytesBase64: bytesToBase64(new Uint8Array(await file.arrayBuffer())),
|
|
574
|
-
});
|
|
575
|
-
if (!uploaded.ok) {
|
|
576
|
-
setError(uploaded.error.message);
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
attachmentIds.push(uploaded.value.attachmentId);
|
|
649
|
+
const upload = await uploadComposerFiles(putAttachment, workspaceId, pendingFiles);
|
|
650
|
+
if (!upload.ok) {
|
|
651
|
+
setError(upload.error);
|
|
652
|
+
return;
|
|
580
653
|
}
|
|
654
|
+
const attachmentIds = upload.attachmentIds;
|
|
581
655
|
const result = await reply({ requestId: id, workspaceId, threadRef, ...(task === undefined ? {} : { taskRef: task.taskRef }), body: draft.trim(), baseRevision: thread.revision, recipients: [...recipients].sort(), ...(attachmentIds.length === 0 ? {} : { attachments: attachmentIds }), ...(confirmation === undefined ? {} : { confirmationToken: confirmation }) });
|
|
582
656
|
if (!result.ok) {
|
|
583
657
|
setError(result.error.message);
|
|
@@ -586,7 +660,7 @@ export function TeamThreadPage(props) {
|
|
|
586
660
|
if (result.value.kind === 'committed') {
|
|
587
661
|
const committed = result.value;
|
|
588
662
|
setCurrentFacts(current => {
|
|
589
|
-
const merged = mergeFacts(current, [{ kind: 'message', sequence: committed.message.sequence, message: committed.message, mentions: [...recipients].sort() }]);
|
|
663
|
+
const merged = mergeFacts(current, [{ kind: 'message', sequence: committed.message.sequence, message: committed.message, mentions: [...recipients].sort(), occurredAt: committed.receipt.occurredAt }]);
|
|
590
664
|
currentFactsRef.current = merged;
|
|
591
665
|
return merged;
|
|
592
666
|
});
|
|
@@ -654,7 +728,7 @@ export function TeamThreadPage(props) {
|
|
|
654
728
|
} }, children: t('acceptTask') });
|
|
655
729
|
})(), task.resolution === 'open'
|
|
656
730
|
? _jsx(Button, { size: "sm", variant: "outline", disabled: pending, onClick: () => { void mutateTask('close'); }, children: t('closeTask') })
|
|
657
|
-
: _jsx(Button, { size: "sm", variant: "primary", disabled: pending, onClick: () => { void mutateTask('reopen'); }, children: t('reopenTask') })] })] }), risks.length > 0 && _jsxs("section", { className: threadCss.riskSection, "aria-label": t('runtimeRisk'), children: [_jsx("h2", { children: t('runtimeRisk') }), risks.map(({ claim, status }) => _jsxs("p", { className: threadCss.riskRow, children: [_jsx(TeamPresenceDot, { status: status, t: t }), _jsxs("span", { children: [t('runtimeRiskDetail', { member: status.member.handle, diagnostic: status
|
|
731
|
+
: _jsx(Button, { size: "sm", variant: "primary", disabled: pending, onClick: () => { void mutateTask('reopen'); }, children: t('reopenTask') })] })] }), risks.length > 0 && _jsxs("section", { className: threadCss.riskSection, "aria-label": t('runtimeRisk'), children: [_jsx("h2", { children: t('runtimeRisk') }), risks.map(({ claim, status }) => _jsxs("p", { className: threadCss.riskRow, children: [_jsx(TeamPresenceDot, { status: status, t: t }), _jsxs("span", { children: [t('runtimeRiskDetail', { member: status.member.handle, diagnostic: diagnosticText(status) || t('statusError') }), " \u00B7 ", claim.direction] })] }, claim.claimRef))] }), task !== undefined && thread !== undefined && (() => {
|
|
658
732
|
// Recomputed here so the confirm list never shows stale rows.
|
|
659
733
|
const activeClaims = projection?.claims.filter(claim => claim.taskRef === task.taskRef && claim.state === 'active') ?? [];
|
|
660
734
|
return _jsxs(Modal, { open: confirmingAccept, onClose: () => { if (!pending)
|
|
@@ -664,5 +738,5 @@ export function TeamThreadPage(props) {
|
|
|
664
738
|
return _jsxs("article", { className: threadCss.claimRow, children: [ownerStatus === undefined ? _jsx("span", {}) : _jsx(TeamPresenceDot, { status: ownerStatus, t: t }), _jsx("strong", { className: threadCss.claimOwner, children: memberName(claim.owner) }), _jsx("span", { className: threadCss.claimDirection, children: claim.direction }), _jsx("small", { className: threadCss.claimState, children: formatClaimState(claim.state, t) })] }, claim.claimRef);
|
|
665
739
|
})] }) }) })] }), _jsx("section", { ref: timeline.ref, onScroll: handleTimelineScroll, className: css.timeline, "aria-label": t('timelineLabel'), children: _jsxs("div", { className: css.timelineContent, children: [loading && projection === undefined && error === undefined && _jsx("div", { className: css.emptySurface, children: _jsxs("p", { className: css.loadingState, children: [_jsx("span", { className: css.loadingMark, "aria-hidden": "true" }), t('loadingThread')] }) }), projection === undefined && error !== undefined && _jsxs("div", { className: css.errorState, role: "alert", children: [_jsx("span", { children: error }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => { void readCurrent(); }, children: t('retry') })] }), olderFacts.length > 0 && _jsxs("section", { className: threadCss.historySection, "aria-label": t('olderHistory'), children: [_jsx("h2", { children: t('olderHistory') }), renderFactBlocks(olderFacts, undefined)] }), historyHasMore && _jsx("div", { className: css.timelineAction, children: _jsx(Button, { size: "sm", onClick: () => { void loadOlder(); }, children: t('loadOlder') }) }), currentFactsWithAnchor.length > 0 && _jsx("section", { className: threadCss.publicSection, children: renderFactBlocks(currentFactsWithAnchor, unreadBoundary) }), autoReadExhausted && _jsxs("div", { className: css.timelineAction, role: "alert", children: [_jsx("span", { children: t('autoReadIncomplete') }), _jsx(Button, { size: "sm", onClick: () => { setAutoReadExhausted(false); void drainUnread(); }, disabled: loading, children: t('retry') })] }), newFactsCount > 0 && _jsx("div", { className: threadCss.newUpdates, role: "status", children: _jsx("button", { type: "button", className: threadCss.newUpdatesJump, onClick: () => { setNewFactsCount(0); timeline.scrollToBottom(); }, children: t('newUpdatesJump', { count: newFactsCount }) }) })] }) }), projection !== undefined && thread !== undefined ? (task?.resolution === 'closed'
|
|
666
740
|
? _jsxs("div", { className: threadCss.closedBar, "data-team-closed": true, children: [error !== undefined && _jsx("p", { className: css.error, role: "alert", children: error }), _jsxs("div", { className: threadCss.closedNotice, children: [_jsx("span", { children: t('taskClosedNotice') }), _jsx(Button, { size: "sm", variant: "outline", disabled: pending, onClick: () => { void mutateTask('reopen'); }, children: t('reopenTask') })] })] })
|
|
667
|
-
: _jsx(TeamComposer, { members: channelMembers, followerMemberIds: followerIds,
|
|
741
|
+
: _jsx(TeamComposer, { members: channelMembers, followerMemberIds: followerIds, drafts: drafts, draftKey: draftKey, pending: pending, ...(statusMessage === undefined ? {} : { confirmation: statusMessage }), ...(error === undefined ? {} : { error }), onEdit: clearSendState, onSubmit: () => { void sendReply(); }, placeholder: t('replyPlaceholder'), pendingFiles: pendingFiles, onFilesChange: setPendingFiles, t: t }, draftKey)) : _jsx("div", {})] });
|
|
668
742
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { TeamSidebarProps } from './slots.ts';
|
|
2
|
-
export declare function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, t, useWorkspaces, loadMembers, subscribeChanges, addMember, loadChannels, createChannel, updateChannel, archiveChannel, updateMember, recoverMember, archiveMember, joinChannel, removeChannelMember, loadModels, openMemberSession }: TeamSidebarProps): import("react").JSX.Element;
|
|
2
|
+
export declare function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, selectInbox, t, useWorkspaces, loadMembers, loadInbox, subscribeChanges, subscribeReads, addMember, loadChannels, createChannel, updateChannel, archiveChannel, updateMember, recoverMember, archiveMember, joinChannel, removeChannelMember, loadModels, openMemberSession }: TeamSidebarProps): import("react").JSX.Element;
|
|
3
3
|
//# sourceMappingURL=TeamWorkspaceBrowser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamWorkspaceBrowser.d.ts","sourceRoot":"","sources":["../../../src/client/TeamWorkspaceBrowser.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAUlD,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,+
|
|
1
|
+
{"version":3,"file":"TeamWorkspaceBrowser.d.ts","sourceRoot":"","sources":["../../../src/client/TeamWorkspaceBrowser.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAUlD,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,+BA+GtY"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
3
|
-
import { IconAgentPresetOutline16, IconListPenOutline16, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
|
+
import { IconAgentPresetOutline16, IconListPenOutline16, IconQueueOutline14, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
4
|
import { TeamWorkspaceRow } from "./TeamWorkspaceRow.js";
|
|
5
5
|
import { TeamSidebarSection } from "./TeamSidebarSection.js";
|
|
6
6
|
import { useSidebarSectionOpen, setSidebarSectionOpen } from "./sidebar-sections.js";
|
|
7
7
|
import { TeamAgentsPanel } from "./TeamAgentsPanel.js";
|
|
8
8
|
import { TeamChannelsPanel } from "./TeamChannelsPanel.js";
|
|
9
9
|
import css from './sidebar.module.css';
|
|
10
|
-
export function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, t, useWorkspaces, loadMembers, subscribeChanges, addMember, loadChannels, createChannel, updateChannel, archiveChannel, updateMember, recoverMember, archiveMember, joinChannel, removeChannelMember, loadModels, openMemberSession }) {
|
|
10
|
+
export function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWorkspace, selectChannel, selectInbox, t, useWorkspaces, loadMembers, loadInbox, subscribeChanges, subscribeReads, addMember, loadChannels, createChannel, updateChannel, archiveChannel, updateMember, recoverMember, archiveMember, joinChannel, removeChannelMember, loadModels, openMemberSession }) {
|
|
11
11
|
const navigationState = useSyncExternalStore(navigation.subscribe, navigation.getSnapshot, navigation.getSnapshot);
|
|
12
12
|
const workspaces = useWorkspaces(state => state.items);
|
|
13
13
|
const selected = navigationState.workspaceId;
|
|
@@ -16,19 +16,62 @@ export function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWo
|
|
|
16
16
|
// Exactly one sidebar row carries aria-current='page': the open Channel while
|
|
17
17
|
// one is set, the selected Agent card while a Member Session view is open,
|
|
18
18
|
// otherwise the browsed Workspace's overview. The selected row keeps its
|
|
19
|
-
// quiet folder tint (data-selected) in every case.
|
|
20
|
-
|
|
19
|
+
// quiet folder tint (data-selected) in every case. The mention-Inbox card
|
|
20
|
+
// takes the marker while the Inbox page stands.
|
|
21
|
+
const overviewIsCurrent = navigationState.channelRef === undefined && navigationState.memberSessionId === undefined && navigationState.inbox !== true;
|
|
22
|
+
const inboxIsCurrent = navigationState.inbox === true;
|
|
21
23
|
const [creatingAgents, setCreatingAgents] = useState([]);
|
|
22
24
|
// Rail icons request expansion and name the section to reveal once wide.
|
|
23
25
|
const [pendingSection, setPendingSection] = useState();
|
|
24
26
|
const channelsRef = useRef(null);
|
|
25
27
|
const agentsRef = useRef(null);
|
|
26
28
|
const workspacesOpen = useSidebarSectionOpen(undefined, 'workspaces');
|
|
29
|
+
// The cross-Workspace mention badge: one scope-less subscription while the
|
|
30
|
+
// Team sidebar stands; every wake re-pulls each Workspace's direct-only
|
|
31
|
+
// total (limit 1 — totals cover every row, never the list). Same-burst
|
|
32
|
+
// wakes coalesce behind a short debounce; the total is still whatever the
|
|
33
|
+
// Host's direct-only projection returns.
|
|
34
|
+
const [inboxTotal, setInboxTotal] = useState(0);
|
|
27
35
|
useEffect(() => {
|
|
36
|
+
let disposed = false;
|
|
37
|
+
let scheduled;
|
|
38
|
+
const refresh = async () => {
|
|
39
|
+
const results = await Promise.all(workspaces.map(workspace => loadInbox({ workspaceId: workspace.workspaceId, directOnly: true, limit: 1 })));
|
|
40
|
+
if (disposed)
|
|
41
|
+
return;
|
|
42
|
+
setInboxTotal(results.reduce((sum, result) => result.ok ? sum + result.value.totalUnreadCount : sum, 0));
|
|
43
|
+
};
|
|
44
|
+
const schedule = () => {
|
|
45
|
+
if (scheduled !== undefined)
|
|
46
|
+
return;
|
|
47
|
+
scheduled = setTimeout(() => { scheduled = undefined; void refresh(); }, 200);
|
|
48
|
+
};
|
|
49
|
+
void refresh();
|
|
50
|
+
const unsubscribe = subscribeChanges(undefined, update => {
|
|
51
|
+
if (update.type === 'changed')
|
|
52
|
+
schedule();
|
|
53
|
+
});
|
|
54
|
+
// A durable Thread read consumes this reader's mention markers without a
|
|
55
|
+
// changes wake (reads change no shared projection), so the badge also
|
|
56
|
+
// refreshes from every completed read.
|
|
57
|
+
const unsubscribeReads = subscribeReads(schedule);
|
|
58
|
+
return () => {
|
|
59
|
+
disposed = true;
|
|
60
|
+
if (scheduled !== undefined)
|
|
61
|
+
clearTimeout(scheduled);
|
|
62
|
+
unsubscribe();
|
|
63
|
+
unsubscribeReads();
|
|
64
|
+
};
|
|
65
|
+
}, [loadInbox, subscribeChanges, subscribeReads, workspaces]);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
// The Inbox page is global and needs no selected Workspace, so the
|
|
68
|
+
// auto-select must not yank the seat back to a Workspace overview.
|
|
69
|
+
if (navigationState.inbox === true)
|
|
70
|
+
return;
|
|
28
71
|
if (navigationState.mode === 'team' && selectedId !== undefined && selectedId !== selected) {
|
|
29
72
|
selectWorkspace(selectedId);
|
|
30
73
|
}
|
|
31
|
-
}, [navigationState.mode, selected, selectedId, selectWorkspace]);
|
|
74
|
+
}, [navigationState.inbox, navigationState.mode, selected, selectedId, selectWorkspace]);
|
|
32
75
|
useEffect(() => {
|
|
33
76
|
if (!wide || pendingSection === undefined)
|
|
34
77
|
return;
|
|
@@ -37,7 +80,7 @@ export function TeamWorkspaceBrowser({ wide, expandSidebar, navigation, selectWo
|
|
|
37
80
|
queueMicrotask(() => { node?.querySelector('button')?.focus(); });
|
|
38
81
|
}, [wide, pendingSection]);
|
|
39
82
|
if (!wide) {
|
|
40
|
-
return _jsxs("nav", { className: css.railWorkspace, "aria-label": t('workspaceSections'), children: [_jsx(Tooltip, { label: t('channels'), side: "right", children: _jsx("button", { type: "button", className: css.railButton, "aria-label": t('channels'), onClick: () => { setPendingSection('channels'); expandSidebar(); }, children: _jsx(IconListPenOutline16, { size: 16 }) }) }), _jsx(Tooltip, { label: t('agents'), side: "right", children: _jsx("button", { type: "button", className: css.railButton, "aria-label": t('agents'), onClick: () => { setPendingSection('agents'); expandSidebar(); }, children: _jsx(IconAgentPresetOutline16, { size: 16 }) }) })] });
|
|
83
|
+
return _jsxs("nav", { className: css.railWorkspace, "aria-label": t('workspaceSections'), children: [_jsx(Tooltip, { label: t('mentionsOfMe'), side: "right", children: _jsxs("button", { type: "button", className: css.railButton, "aria-label": inboxTotal > 0 ? t('mentionsOfMeWithCount', { count: inboxTotal }) : t('mentionsOfMe'), "aria-current": inboxIsCurrent ? 'page' : undefined, onClick: () => { selectInbox(); expandSidebar(); }, children: [_jsx(IconQueueOutline14, { size: 16 }), inboxTotal > 0 && _jsx("span", { className: css.inboxBadge, "aria-hidden": "true", children: inboxTotal > 99 ? '99+' : inboxTotal })] }) }), _jsx(Tooltip, { label: t('channels'), side: "right", children: _jsx("button", { type: "button", className: css.railButton, "aria-label": t('channels'), onClick: () => { setPendingSection('channels'); expandSidebar(); }, children: _jsx(IconListPenOutline16, { size: 16 }) }) }), _jsx(Tooltip, { label: t('agents'), side: "right", children: _jsx("button", { type: "button", className: css.railButton, "aria-label": t('agents'), onClick: () => { setPendingSection('agents'); expandSidebar(); }, children: _jsx(IconAgentPresetOutline16, { size: 16 }) }) })] });
|
|
41
84
|
}
|
|
42
|
-
return _jsxs("section", { className: css.workspaceBrowser, "aria-label": t('workspaces'), children: [_jsx(TeamSidebarSection, { title: t('workspaces'), open: workspacesOpen, onToggle: open => { setSidebarSectionOpen(undefined, 'workspaces', open); }, children: _jsxs("div", { className: css.workspaceList, children: [workspaces.map(workspace => _jsx(TeamWorkspaceRow, { workspaceId: workspace.workspaceId, title: workspace.title, path: workspace.path, selected: workspace.workspaceId === selectedId, current: workspace.workspaceId === selectedId && overviewIsCurrent, onSelect: selectWorkspace }, workspace.workspaceId)), workspaces.length === 0 && _jsx("p", { className: css.emptyState, children: t('empty') })] }) }), selectedId !== undefined && _jsxs("div", { className: css.workspaceSection, children: [_jsx("div", { ref: channelsRef, children: _jsx(TeamChannelsPanel, { workspaceId: selectedId, loadMembers: loadMembers, loadChannels: loadChannels, subscribeChanges: subscribeChanges, createChannel: createChannel, updateChannel: updateChannel, archiveChannel: archiveChannel, joinChannel: joinChannel, removeChannelMember: removeChannelMember, creatingAgents: creatingAgents.filter(request => request.workspaceId === selectedId), ...(navigationState.memberSessionId !== undefined || navigationState.channelRef === undefined ? {} : { selectedChannelRef: navigationState.channelRef }), selectChannel: selectChannel, t: t }, selectedId) }), _jsx("div", { ref: agentsRef, children: _jsx(TeamAgentsPanel, { workspaceId: selectedId, loadMembers: loadMembers, subscribeChanges: subscribeChanges, addMember: addMember, updateMember: updateMember, recoverMember: recoverMember, archiveMember: archiveMember, loadModels: loadModels, ...(navigationState.memberSessionId === undefined ? {} : { memberSessionId: navigationState.memberSessionId }), openMemberSession: openMemberSession, onCreatingChange: (request, creating) => { setCreatingAgents(current => creating ? [...current.filter(item => item.requestId !== request.requestId), request] : current.filter(item => item.requestId !== request.requestId)); }, t: t }, selectedId) })] })] });
|
|
85
|
+
return _jsxs("section", { className: css.workspaceBrowser, "aria-label": t('workspaces'), children: [_jsxs("button", { type: "button", className: css.inboxCard, "aria-label": inboxTotal > 0 ? t('mentionsOfMeWithCount', { count: inboxTotal }) : t('mentionsOfMe'), "aria-current": inboxIsCurrent ? 'page' : undefined, onClick: selectInbox, children: [_jsx(IconQueueOutline14, { size: 16 }), _jsx("span", { className: css.inboxCardLabel, children: t('mentionsOfMe') }), inboxTotal > 0 && _jsx("span", { className: css.inboxBadge, "aria-hidden": "true", children: inboxTotal > 99 ? '99+' : inboxTotal })] }), _jsx(TeamSidebarSection, { title: t('workspaces'), open: workspacesOpen, onToggle: open => { setSidebarSectionOpen(undefined, 'workspaces', open); }, children: _jsxs("div", { className: css.workspaceList, children: [workspaces.map(workspace => _jsx(TeamWorkspaceRow, { workspaceId: workspace.workspaceId, title: workspace.title, path: workspace.path, selected: workspace.workspaceId === selectedId, current: workspace.workspaceId === selectedId && overviewIsCurrent, onSelect: selectWorkspace }, workspace.workspaceId)), workspaces.length === 0 && _jsx("p", { className: css.emptyState, children: t('empty') })] }) }), selectedId !== undefined && _jsxs("div", { className: css.workspaceSection, children: [_jsx("div", { ref: channelsRef, children: _jsx(TeamChannelsPanel, { workspaceId: selectedId, loadMembers: loadMembers, loadChannels: loadChannels, subscribeChanges: subscribeChanges, createChannel: createChannel, updateChannel: updateChannel, archiveChannel: archiveChannel, joinChannel: joinChannel, removeChannelMember: removeChannelMember, creatingAgents: creatingAgents.filter(request => request.workspaceId === selectedId), ...(navigationState.memberSessionId !== undefined || navigationState.channelRef === undefined ? {} : { selectedChannelRef: navigationState.channelRef }), selectChannel: selectChannel, t: t }, selectedId) }), _jsx("div", { ref: agentsRef, children: _jsx(TeamAgentsPanel, { workspaceId: selectedId, loadMembers: loadMembers, subscribeChanges: subscribeChanges, addMember: addMember, updateMember: updateMember, recoverMember: recoverMember, archiveMember: archiveMember, loadModels: loadModels, ...(navigationState.memberSessionId === undefined ? {} : { memberSessionId: navigationState.memberSessionId }), openMemberSession: openMemberSession, onCreatingChange: (request, creating) => { setCreatingAgents(current => creating ? [...current.filter(item => item.requestId !== request.requestId), request] : current.filter(item => item.requestId !== request.requestId)); }, t: t }, selectedId) })] })] });
|
|
43
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAqCnE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAK5C,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAEnD,YAAY,EAAE,QAAQ,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAC9F,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAIhD,eAAO,MAAM,MAAM,UAElB,CAAA;AAED,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,IAAI,EAAE,OAAO,CAAA;KACd;CACF;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,cAAc,EAAE,cAAc,CAAA;QAC9B,UAAU,EAAE,cAAc,CAAA;KAC3B;CACF;AA8LD,wBAAsB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D"}
|