@wowyuarm/dsh-agent-team 0.1.14 → 0.1.15

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.
Files changed (71) hide show
  1. package/README.md +2 -2
  2. package/README.zh.md +2 -2
  3. package/cordis.patch.yml +187 -2
  4. package/package.json +49 -50
  5. package/packages/agent-team/README.md +1 -1
  6. package/packages/agent-team/README.zh.md +1 -1
  7. package/packages/agent-team/lib/context-continuity-host.js +2 -3
  8. package/packages/agent-team/lib/context-projection.js +3 -3
  9. package/packages/agent-team/lib/context-source.js +34 -13
  10. package/packages/agent-team/lib/human-profile.js +123 -12
  11. package/packages/agent-team/lib/index.js +165 -99
  12. package/packages/agent-team/lib/member-context.js +5 -3
  13. package/packages/agent-team/lib/member-time-context.js +5 -2
  14. package/packages/agent-team/lib/pressure-policy.js +5 -3
  15. package/packages/agent-team/lib/stored-session-reader.js +1 -2
  16. package/packages/agent-team/lib/typert.host.js +394 -252
  17. package/packages/agent-team/lib/typert.remote-client.d.ts +6 -3
  18. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  19. package/packages/agent-team/lib/typert.remote-client.js +322 -223
  20. package/packages/agent-team/lib/types/context-continuity-host.d.ts.map +1 -1
  21. package/packages/agent-team/lib/types/context-source.d.ts +46 -13
  22. package/packages/agent-team/lib/types/context-source.d.ts.map +1 -1
  23. package/packages/agent-team/lib/types/human-profile.d.ts +83 -11
  24. package/packages/agent-team/lib/types/human-profile.d.ts.map +1 -1
  25. package/packages/agent-team/lib/types/index.d.ts +64 -26
  26. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  27. package/packages/agent-team/lib/types/member-context.d.ts +14 -0
  28. package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
  29. package/packages/agent-team/lib/types/member-time-context.d.ts +15 -0
  30. package/packages/agent-team/lib/types/member-time-context.d.ts.map +1 -1
  31. package/packages/agent-team/lib/types/pressure-policy.d.ts.map +1 -1
  32. package/packages/agent-team/lib/types/stored-session-reader.d.ts +1 -2
  33. package/packages/agent-team/lib/types/stored-session-reader.d.ts.map +1 -1
  34. package/packages/agent-team/lib/types/types/entities.d.ts +3 -3
  35. package/packages/agent-team/lib/types/types/requests-results.d.ts +18 -0
  36. package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
  37. package/packages/client-agent-team/README.md +1 -1
  38. package/packages/client-agent-team/README.zh.md +1 -1
  39. package/packages/client-agent-team/lib/client.js +330 -239
  40. package/packages/client-agent-team/lib/client.js.map +1 -1
  41. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +6 -6
  42. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +3 -3
  43. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +4 -4
  44. package/packages/client-agent-team/lib/types/client/TeamComposer.js +3 -3
  45. package/packages/client-agent-team/lib/types/client/TeamFooterAction.js +2 -2
  46. package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +3 -3
  47. package/packages/client-agent-team/lib/types/client/TeamMembersAction.js +2 -2
  48. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
  49. package/packages/client-agent-team/lib/types/client/TeamMessage.js +1 -1
  50. package/packages/client-agent-team/lib/types/client/TeamRowMenu.d.ts.map +1 -1
  51. package/packages/client-agent-team/lib/types/client/TeamRowMenu.js +2 -2
  52. package/packages/client-agent-team/lib/types/client/TeamSidebarSection.js +2 -2
  53. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +3 -3
  54. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +3 -3
  55. package/packages/client-agent-team/lib/types/client/TeamWorkspaceSelector.js +2 -2
  56. package/packages/client-agent-team/lib/types/client/human-identity.d.ts +4 -8
  57. package/packages/client-agent-team/lib/types/client/human-identity.d.ts.map +1 -1
  58. package/packages/client-agent-team/lib/types/client/human-identity.js +0 -21
  59. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  60. package/packages/client-agent-team/lib/types/client/index.js +50 -49
  61. package/packages/client-agent-team/lib/types/client/multi-menu-field.js +2 -2
  62. package/packages/client-agent-team/lib/types/client/slots.d.ts +1 -1
  63. package/packages/tool-agent-team/README.md +1 -1
  64. package/packages/tool-agent-team/README.zh.md +1 -1
  65. package/packages/agent-team/lib/preset-roster.js +0 -15
  66. package/packages/agent-team/lib/session-remediation.js +0 -493
  67. package/packages/agent-team/lib/types/preset-roster.d.ts +0 -5
  68. package/packages/agent-team/lib/types/preset-roster.d.ts.map +0 -1
  69. package/packages/agent-team/lib/types/session-remediation.d.ts +0 -172
  70. package/packages/agent-team/lib/types/session-remediation.d.ts.map +0 -1
  71. package/packages/agent-team/preset/team-member/agent.cordis.yml +0 -166
@@ -1,6 +1,6 @@
1
1
  import agentTeamRemote from '@wowyuarm/dsh-agent-team/remote';
2
2
  import { HumanSettingsSection } from "./HumanSettingsSection.js";
3
- import { HUMAN_PROFILE_NAMESPACE, TeamHumanIdentity } from "./human-identity.js";
3
+ import { TeamHumanIdentity } from "./human-identity.js";
4
4
  import { bytesToBase64 } from "./attachment-preview.js";
5
5
  import { TeamNavigation } from "./navigation.js";
6
6
  import { TeamChangeStream, TeamReadStream } from "./team-changes.js";
@@ -13,8 +13,27 @@ import { en, zh } from "./locales.js";
13
13
  export { TeamNavigation } from "./navigation.js";
14
14
  const NS = 'team';
15
15
  export const inject = [
16
- 'slots', 'workspaces', 'locale', 'remote', 'remote.session', 'sessions', 'connection', 'conversation',
16
+ 'slots', 'workspaces', 'locale', 'remote', 'remote.session', 'sessions', 'connection', 'conversation', 'uiWorkspace',
17
17
  ];
18
+ /**
19
+ * 0.1.7 moved the conversation selection into the workspace service: the
20
+ * rendered session is the one holding its `mainView` reference (the shipped
21
+ * consumers read the same projection), so the Team client reads the selection
22
+ * through retention instead of a service-owned `current`.
23
+ */
24
+ function currentMainSessionId(ctx) {
25
+ const sessions = ctx.sessions;
26
+ return Object.values(sessions.list.getSnapshot().byId)
27
+ .find(session => (session.retainedBy.mainView ?? 0) > 0)?.id;
28
+ }
29
+ /**
30
+ * Session ids this client opened as Member views, per client instance. The
31
+ * 0.1.7 workspace service exposes no clear, so a dead return target leaves
32
+ * the departed Member selection in place; excluding Member sessions from the
33
+ * next capture keeps that stale selection from becoming a false return
34
+ * target.
35
+ */
36
+ const openedMemberSessions = new WeakMap();
18
37
  function registerModeShadow(ctx, navigation, changes, reads, drafts, humanIdentity, name, component, extraInject,
19
38
  // Keyed seats (`main`) address one panel by key; the reserved 'conversation'
20
39
  // key is where the shipped Conversation registers, so the Team seat shadows
@@ -24,14 +43,16 @@ entryKey) {
24
43
  // views (see registerModeShadow), so the shipped conversation root renders
25
44
  // the selected Member Session inside the Team shell.
26
45
  const openMemberSessionImpl = (sessionId) => {
27
- const sessions = ctx.sessions;
28
46
  const snapshot = navigation.getSnapshot();
29
- const current = sessions.list.getSnapshot().current;
47
+ const current = currentMainSessionId(ctx);
30
48
  // The return target is captured on first entry only — switching between
31
49
  // Member Sessions must keep pointing at the Human's original session.
32
- const returnTo = snapshot.memberSessionId === undefined && current !== undefined && current !== sessionId ? current : undefined;
50
+ const memberSessions = openedMemberSessions.get(ctx) ?? new Set();
51
+ openedMemberSessions.set(ctx, memberSessions);
52
+ memberSessions.add(sessionId);
53
+ const returnTo = snapshot.memberSessionId === undefined && current !== undefined && current !== sessionId && !memberSessions.has(current) ? current : undefined;
33
54
  navigation.actions().enterMemberSession(sessionId, returnTo);
34
- sessions.open(sessionId);
55
+ ctx.uiWorkspace.openSession(sessionId);
35
56
  };
36
57
  // Remote bindings shared by every Team slot; surface-specific entries extend it below.
37
58
  const sharedRemotes = {
@@ -126,16 +147,8 @@ function applyUi(ctx) {
126
147
  // The Human's own identity: one projection every seat reads, refreshed once
127
148
  // after a profile write so a rename reaches the timeline and the member refs
128
149
  // without a reload. Reads are demand-driven — the first seat that subscribes
129
- // starts the read.
130
- // The profile page writes through the settings transport. It arrives from the
131
- // settings plugin, and Cordis refuses a `remote.<namespace>` read that was
132
- // never injected, so the binding is an optional injection rather than either
133
- // a hard activation dependency (a settings-less host would lose Team mode
134
- // entirely) or an undeclared read (which throws at the first write).
135
- let settingsTransport;
136
- ctx.inject(['remote.settings'], (scope) => {
137
- settingsTransport = scope.remote.settings;
138
- });
150
+ // starts the read. The profile page writes back through the Team Remote, so
151
+ // the Client never names the Host's own profile entry.
139
152
  const humanIdentity = new TeamHumanIdentity({
140
153
  loadProfile: () => ctx.remote.agentTeam.humanProfile({}),
141
154
  loadAvatarUrl: async (avatarRef) => {
@@ -155,12 +168,13 @@ function applyUi(ctx) {
155
168
  void disposeDrafts();
156
169
  }, 'agent-team: navigation service');
157
170
  // The one restore owner: leaving an embedded Member Session view must
158
- // rebind the underlying current session, or the stale Member current later
159
- // masks to undefined when the Host disposes that session (rollover) and
160
- // the conversation seat remounts. Takeover is conditional — only when the
161
- // current still IS the departed Member session — so a selection someone
162
- // else made in the meantime survives. A dead return target clears instead
163
- // of opening an unknown id.
171
+ // rebind the underlying selection, or the departed Member session stays the
172
+ // workspace service's `mainView` retention into the next Member entry's
173
+ // return-target capture. Takeover is conditional — only when the selection
174
+ // still IS the departed Member session — so a selection someone else made
175
+ // in the meantime survives. A dead return target keeps the departed
176
+ // selection: 0.1.7 exposes no public clear, and the retention is inert
177
+ // behind the Team seat until the next open.
164
178
  ctx.effect(() => {
165
179
  let previous = navigation.getSnapshot();
166
180
  const restore = () => {
@@ -170,13 +184,10 @@ function applyUi(ctx) {
170
184
  previous = snapshot;
171
185
  if (departed === undefined || snapshot.memberSessionId !== undefined)
172
186
  return;
173
- const sessions = ctx.sessions;
174
- if (sessions.list.getSnapshot().current !== departed)
187
+ if (currentMainSessionId(ctx) !== departed)
175
188
  return;
176
- if (returnTo !== undefined && sessions.list.getSnapshot().byId[returnTo] !== undefined)
177
- sessions.open(returnTo);
178
- else
179
- sessions.clear();
189
+ if (returnTo !== undefined && ctx.sessions.list.getSnapshot().byId[returnTo] !== undefined)
190
+ ctx.uiWorkspace.openSession(returnTo);
180
191
  };
181
192
  const unsubscribe = navigation.subscribe(restore);
182
193
  return () => {
@@ -213,7 +224,7 @@ function applyUi(ctx) {
213
224
  navigation,
214
225
  ...navigation.actions(),
215
226
  // The footer is the only surface that leaves Team mode; closing the
216
- // embedded Member Session view rebinds the underlying current through
227
+ // embedded Member Session view rebinds the underlying selection through
217
228
  // the same root-scope restore owner, so there is exactly one restore
218
229
  // path and no double open.
219
230
  leaveTeam: () => {
@@ -225,12 +236,12 @@ function applyUi(ctx) {
225
236
  registerModeShadow(ctx, navigation, changes, reads, drafts, humanIdentity, 'sidebar.workspaces', TeamWorkspaceBrowser);
226
237
  registerModeShadow(ctx, navigation, changes, reads, drafts, humanIdentity, 'main', TeamConversation, undefined, 'conversation');
227
238
  registerModeShadow(ctx, navigation, changes, reads, drafts, humanIdentity, 'sidebar.settings', TeamMembersAction, () => ({ loadMemberGroups }));
228
- // The Human profile page: one settings section over the `agent-team-human`
229
- // namespace, ordered between General (0) and Models (10) so identity sits
230
- // near the top. Writes go through the settings controller, which answers
231
- // with the Host's own rejection reason (a name collides, an empty one), and
232
- // the shared identity re-reads afterwards, so a rename lands in the timeline
233
- // and the member refs at the same moment the page shows it.
239
+ // The Human profile page: one settings section, ordered between General (0)
240
+ // and Models (10) so identity sits near the top. Writes go through the Team
241
+ // Remote, which answers with the Host's own rejection reason (a name
242
+ // collides, an empty one), and the shared identity re-reads afterwards, so a
243
+ // rename lands in the timeline and the member refs at the same moment the
244
+ // page shows it.
234
245
  ctx.slots.inject('settings.section', () => ctx.slots.register({
235
246
  name: 'settings.section',
236
247
  id: 'team-human',
@@ -240,10 +251,7 @@ function applyUi(ctx) {
240
251
  inject: () => ({
241
252
  identity: humanIdentity,
242
253
  saveName: async (name) => {
243
- const settings = settingsTransport;
244
- if (settings === undefined)
245
- return 'the settings service is unavailable';
246
- const saved = await settings.update(HUMAN_PROFILE_NAMESPACE, { name }, undefined);
254
+ const saved = await ctx.remote.agentTeam.setHumanProfile({ name });
247
255
  if (!saved.ok)
248
256
  return saved.error.message;
249
257
  await humanIdentity.refresh();
@@ -257,10 +265,7 @@ function applyUi(ctx) {
257
265
  });
258
266
  if (!put.ok)
259
267
  return put.error.message;
260
- const settings = settingsTransport;
261
- if (settings === undefined)
262
- return 'the settings service is unavailable';
263
- const saved = await settings.update(HUMAN_PROFILE_NAMESPACE, { avatarRef: put.value.avatarRef }, undefined);
268
+ const saved = await ctx.remote.agentTeam.setHumanProfile({ avatarRef: put.value.avatarRef });
264
269
  if (!saved.ok)
265
270
  return saved.error.message;
266
271
  await humanIdentity.refresh();
@@ -270,14 +275,10 @@ function applyUi(ctx) {
270
275
  const { avatarRef } = humanIdentity.getSnapshot();
271
276
  if (avatarRef === undefined)
272
277
  return undefined;
273
- const settings = settingsTransport;
274
- if (settings === undefined)
275
- return 'the settings service is unavailable';
276
278
  // Bytes first, then the reference: a failed clear leaves a readable
277
- // avatar instead of a reference to bytes nobody can load. Clearing one
278
- // field is a path op — a merge patch cannot express removal.
279
+ // avatar instead of a reference to bytes nobody can load.
279
280
  await ctx.remote.agentTeam.removeHumanAvatar({ avatarRef });
280
- const cleared = await settings.mutate(HUMAN_PROFILE_NAMESPACE, [{ op: 'unset', path: ['avatarRef'] }], undefined);
281
+ const cleared = await ctx.remote.agentTeam.setHumanProfile({ avatarRef: null });
281
282
  if (!cleared.ok)
282
283
  return cleared.error.message;
283
284
  await humanIdentity.refresh();
@@ -4,7 +4,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
4
4
  // without closing the list so several entries can be picked in one pass; the
5
5
  // capped card scrolls internally through long catalogs.
6
6
  import { useState } from 'react';
7
- import { IconChevronDownOutline14, Menu } from '@deepseek-ai/dsh-client-ui-primitives';
7
+ import { IconChevronDownOutlineRegular, Menu } from '@deepseek-ai/dsh-client-ui-primitives';
8
8
  import createCss from './create.module.css';
9
9
  import css from './sidebar.module.css';
10
10
  /**
@@ -26,5 +26,5 @@ export function MultiMenuField({ label, options, selected, onToggle, disabled =
26
26
  ...(option.disabled === true ? { disabled: true } : {}),
27
27
  ...(option.icon === undefined ? {} : { icon: option.icon }),
28
28
  }));
29
- return (_jsxs("div", { className: createCss.field, children: [_jsx("span", { children: label }), options.length === 0 && emptyText !== undefined ? _jsx("small", { className: css.editHint, children: emptyText }) : (_jsx(Menu, { open: open, portal: true, className: createCss.menuCap, items: items, selectedIds: selected, onSelect: id => { onToggle(id); }, onClose: () => { setOpen(false); }, anchor: _jsxs("button", { type: "button", className: createCss.selectTrigger, "aria-label": label, "aria-haspopup": "menu", "aria-expanded": open, disabled: disabled, onClick: () => { setOpen(value => !value); }, children: [_jsx("span", { className: createCss.selectValue, children: selected.length === 0 ? triggerEmptyLabel : formatCount(selected.length) }), _jsx("span", { className: `${createCss.chevron} ${open ? createCss.chevronOpen : ''}`, "aria-hidden": true, children: _jsx(IconChevronDownOutline14, {}) })] }) }))] }));
29
+ return (_jsxs("div", { className: createCss.field, children: [_jsx("span", { children: label }), options.length === 0 && emptyText !== undefined ? _jsx("small", { className: css.editHint, children: emptyText }) : (_jsx(Menu, { open: open, portal: true, className: createCss.menuCap, items: items, selectedIds: selected, onSelect: id => { onToggle(id); }, onClose: () => { setOpen(false); }, anchor: _jsxs("button", { type: "button", className: createCss.selectTrigger, "aria-label": label, "aria-haspopup": "menu", "aria-expanded": open, disabled: disabled, onClick: () => { setOpen(value => !value); }, children: [_jsx("span", { className: createCss.selectValue, children: selected.length === 0 ? triggerEmptyLabel : formatCount(selected.length) }), _jsx("span", { className: `${createCss.chevron} ${open ? createCss.chevronOpen : ''}`, "aria-hidden": true, children: _jsx(IconChevronDownOutlineRegular, {}) })] }) }))] }));
30
30
  }
@@ -58,7 +58,7 @@ export type TeamSidebarProps = PropsRuntime<'sidebar.workspaces'> & PropsLocale<
58
58
  /**
59
59
  * Host clear-context remote kept as a hidden migration escape hatch.
60
60
  * The visible row action is retired: Members manage their own context
61
- * through the context_rollover tool (see docs/architecture.md).
61
+ * through the context_rollover tool (see docs/architecture/README.md).
62
62
  */
63
63
  clearMemberContext: (request: AgentTeamClearMemberContextRequest) => Promise<RemoteResult<AgentTeamClearMemberContextResult>>;
64
64
  archiveMember: (request: AgentTeamArchiveMemberRequest) => Promise<RemoteResult<AgentTeamArchiveMemberResult>>;
@@ -21,7 +21,7 @@ Every agent-facing render carries absolute event instants in the fixed Team coor
21
21
 
22
22
  Canonical results expose stable refs, optional Task status, Thread revision, Claim history, Attention, and unread facts as structured fields. The model-visible renders follow the action decision surface: the write token appears only on a fully drained `team_thread read` and a committed public mutation; browsing results (`team_view`, `team_inbox`, status/follow/unfollow, `history`, `team_claim list`) and all typed rejections render no revision and no token. Typed `unread_required` and `stale_revision` results keep the structured fields needed to reread and retry deliberately. Tool execution resolves the exact live `exec.agent`; arguments cannot select or impersonate the actor, and the optional `workspace` selector can only pick among that actor's participated Workspaces. Write request identity derives from sessionId plus tool callId. `context_rollover` and `context_checkpoint` conclude the Agent turn (a rollover must not be followed by old-generation work, and a checkpoint resolves at its containing turn's end); every other Team tool returns to the model loop.
23
23
 
24
- The complete implemented protocol is documented in [`../../docs/team-collaboration.md`](../../docs/team-collaboration.md).
24
+ The complete implemented protocol is documented in [`../../docs/team-collaboration/README.md`](../../docs/team-collaboration/README.md).
25
25
 
26
26
  ## Composition
27
27
 
@@ -21,7 +21,7 @@ mention 在 Message 正文里撰写,形如 `@Handle`(`@` 必需、大小写
21
21
 
22
22
  Canonical result 以结构化字段暴露稳定 refs、可选 Task status、Thread revision、Claim history、Attention 和未读 facts。模型可见的渲染遵循 action decision surface:写令牌只出现在未读清零的 `team_thread read` 与一次已提交的 public mutation 上;浏览类结果(`team_view`、`team_inbox`、status/follow/unfollow、`history`、`team_claim list`)与所有类型化拒绝都不渲染 revision 与令牌。类型化的 `unread_required` 与 `stale_revision` 结果保留重新读取和审慎重试所需的结构化字段。工具执行通过准确的 live `exec.agent` 解析 actor;参数不能选择或冒充 actor,可选的 `workspace` 选择器只能在该 actor 已参与的 Workspace 中选择。写操作的 request identity 由 sessionId 与 tool callId 派生。`context_rollover` 与 `context_checkpoint` 结束 Agent turn;其余 Team tools 将结果返回模型循环,不主动结束 turn。
23
23
 
24
- 完整的已实现协议见 [`../../docs/team-collaboration.md`](../../docs/team-collaboration.md)。
24
+ 完整的已实现协议见 [`../../docs/team-collaboration/README.md`](../../docs/team-collaboration/README.md)。
25
25
 
26
26
  ## Composition
27
27
 
@@ -1,15 +0,0 @@
1
- import { dirname, resolve } from 'node:path';
2
- import { fileURLToPath } from 'node:url';
3
- import AgentPresets from '@deepseek-ai/dsh-agent-presets';
4
- export const inject = ['loader'];
5
- /** Bundle-private Agent preset roster. The composition must isolate `agentPresets` around this provider and AgentTeam. */
6
- export function apply(ctx) {
7
- const here = dirname(fileURLToPath(import.meta.url));
8
- const root = resolve(here, '../preset');
9
- ctx.plugin(AgentPresets, {
10
- default: 'team-member',
11
- roots: [{ path: root, trust: 'system' }],
12
- includeShippedRoot: false,
13
- includeUserRoot: false,
14
- });
15
- }