@wowyuarm/dsh-agent-team 0.1.2 → 0.1.4
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 +8 -1
- package/README.zh.md +9 -1
- package/package.json +12 -3
- package/packages/agent-team/README.md +3 -3
- package/packages/agent-team/README.zh.md +3 -3
- package/packages/agent-team/lib/attachments.js +11 -12
- package/packages/agent-team/lib/auto-compaction.js +163 -0
- package/packages/agent-team/lib/index.js +252 -139
- package/packages/agent-team/lib/ledger.js +344 -170
- package/packages/agent-team/lib/recovery.js +30 -35
- package/packages/agent-team/lib/spec.js +27 -11
- package/packages/agent-team/lib/typert.host.js +197 -88
- package/packages/agent-team/lib/typert.remote-client.d.ts +3 -1
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +139 -59
- package/packages/agent-team/lib/types/attachments.d.ts +2 -2
- package/packages/agent-team/lib/types/attachments.d.ts.map +1 -1
- package/packages/agent-team/lib/types/auto-compaction.d.ts +38 -0
- package/packages/agent-team/lib/types/auto-compaction.d.ts.map +1 -0
- package/packages/agent-team/lib/types/index.d.ts +52 -19
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/ledger.d.ts +29 -2
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/recovery.d.ts +15 -16
- package/packages/agent-team/lib/types/recovery.d.ts.map +1 -1
- package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types.d.ts +69 -30
- package/packages/agent-team/lib/types/types.d.ts.map +1 -1
- package/packages/agent-team/preset/team-member/agent.cordis.yml +7 -2
- package/packages/client-agent-team/README.md +2 -1
- package/packages/client-agent-team/README.zh.md +2 -1
- package/packages/client-agent-team/lib/client.js +1577 -863
- 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 +35 -174
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +20 -30
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +3 -2
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +6 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.js +4 -5
- 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 +3 -3
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts +34 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +169 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts +17 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.js +120 -0
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +4 -1
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMessage.js +94 -47
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +2 -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 +81 -39
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +2 -1
- package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.js +72 -1
- package/packages/client-agent-team/lib/types/client/locales.d.ts +24 -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 +24 -0
- package/packages/client-agent-team/lib/types/client/member-session-input.d.ts +22 -0
- package/packages/client-agent-team/lib/types/client/member-session-input.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/member-session-input.js +98 -0
- package/packages/client-agent-team/lib/types/client/navigation.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/navigation.js +12 -6
- package/packages/client-agent-team/lib/types/client/requests.d.ts +16 -0
- package/packages/client-agent-team/lib/types/client/requests.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/requests.js +22 -0
- package/packages/client-agent-team/lib/types/client/slots.d.ts +2 -1
- package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/task-refs.d.ts +6 -1
- package/packages/client-agent-team/lib/types/client/task-refs.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/task-refs.js +19 -0
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +52 -3
- 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 +74 -4
- package/packages/client-agent-team/lib/types/client/team-membership.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-membership.js +2 -1
- package/packages/tool-agent-team/README.md +7 -7
- package/packages/tool-agent-team/README.zh.md +7 -7
- package/packages/tool-agent-team/lib/index.js +38 -28
- package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.d.ts +0 -13
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.js +0 -90
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AgentTeamClientMemberStatus } from '@wowyuarm/dsh-agent-team/types';
|
|
2
|
+
import type { ISession } from '@deepseek-ai/dsh-client-runtime/client';
|
|
3
|
+
import type { ClientSessionContext, InputTriggerSource, SubmitOutcome } from '@deepseek-ai/dsh-client-ui-input-trigger/client';
|
|
4
|
+
export declare const TEAM_COMMAND_SOURCE = "agent-team-command";
|
|
5
|
+
export declare const TEAM_MEMBER_SOURCE = "agent-team-member";
|
|
6
|
+
export interface TeamMemberSessionInputOptions {
|
|
7
|
+
readonly isEmbeddedMemberSession: (sessionId: ClientSessionContext['sessionId']) => boolean;
|
|
8
|
+
readonly members: () => Promise<readonly AgentTeamClientMemberStatus[]>;
|
|
9
|
+
readonly executeCompact: (sessionId: ClientSessionContext['sessionId']) => Promise<SubmitOutcome>;
|
|
10
|
+
}
|
|
11
|
+
/** Preserve the public Session command admission contract, not handler outcome. */
|
|
12
|
+
export declare function admitTeamCompact(session: Pick<ISession, 'command'>): Promise<SubmitOutcome>;
|
|
13
|
+
/**
|
|
14
|
+
* The two Team-only sources live in the shared public registry, but their
|
|
15
|
+
* candidate plane is inert for every ordinary Session. The member source owns
|
|
16
|
+
* its stable ref→label cache so serialization never falls back to guessing a
|
|
17
|
+
* handle from plain text.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createTeamMemberSessionSources(options: TeamMemberSessionInputOptions): readonly InputTriggerSource[];
|
|
20
|
+
/** Unknown leading slash must never fall into the shipped global palette. */
|
|
21
|
+
export declare function allowsMemberSessionSubmit(draft: string, claimToken: string | undefined): boolean;
|
|
22
|
+
//# sourceMappingURL=member-session-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"member-session-input.d.ts","sourceRoot":"","sources":["../../../src/client/member-session-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAqB,MAAM,gCAAgC,CAAA;AACpG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAA;AACtE,OAAO,KAAK,EACV,oBAAoB,EAAgB,kBAAkB,EAAmB,aAAa,EACvF,MAAM,iDAAiD,CAAA;AAExD,eAAO,MAAM,mBAAmB,uBAAuB,CAAA;AACvD,eAAO,MAAM,kBAAkB,sBAAsB,CAAA;AAErD,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,uBAAuB,EAAE,CAAC,SAAS,EAAE,oBAAoB,CAAC,WAAW,CAAC,KAAK,OAAO,CAAA;IAC3F,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,SAAS,2BAA2B,EAAE,CAAC,CAAA;IACvE,QAAQ,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,oBAAoB,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;CAClG;AAED,mFAAmF;AACnF,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAIjG;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,6BAA6B,GAAG,SAAS,kBAAkB,EAAE,CAiEpH;AAED,6EAA6E;AAC7E,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGhG"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export const TEAM_COMMAND_SOURCE = 'agent-team-command';
|
|
2
|
+
export const TEAM_MEMBER_SOURCE = 'agent-team-member';
|
|
3
|
+
/** Preserve the public Session command admission contract, not handler outcome. */
|
|
4
|
+
export async function admitTeamCompact(session) {
|
|
5
|
+
const result = await session.command('/compact');
|
|
6
|
+
if (!result.ok)
|
|
7
|
+
throw new Error(`session.command failed: ${result.error.message}`);
|
|
8
|
+
return result.value.matched ? { kind: 'success' } : { kind: 'error', text: 'unknown command: /compact' };
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The two Team-only sources live in the shared public registry, but their
|
|
12
|
+
* candidate plane is inert for every ordinary Session. The member source owns
|
|
13
|
+
* its stable ref→label cache so serialization never falls back to guessing a
|
|
14
|
+
* handle from plain text.
|
|
15
|
+
*/
|
|
16
|
+
export function createTeamMemberSessionSources(options) {
|
|
17
|
+
const labels = new Map();
|
|
18
|
+
const command = {
|
|
19
|
+
trigger: '/',
|
|
20
|
+
name: TEAM_COMMAND_SOURCE,
|
|
21
|
+
showGroupTitle: false,
|
|
22
|
+
async candidates(session, { query }) {
|
|
23
|
+
if (!options.isEmbeddedMemberSession(session.sessionId) || !'compact'.startsWith(query.toLocaleLowerCase()))
|
|
24
|
+
return [];
|
|
25
|
+
return [{ name: '/compact', description: '压缩当前 Session 上下文', value: 'compact' }];
|
|
26
|
+
},
|
|
27
|
+
onPick({ candidate, session }) {
|
|
28
|
+
if (candidate.value !== 'compact' || !options.isEmbeddedMemberSession(session.sessionId))
|
|
29
|
+
return undefined;
|
|
30
|
+
const claim = {
|
|
31
|
+
token: '/compact',
|
|
32
|
+
submit: async () => options.executeCompact(session.sessionId),
|
|
33
|
+
};
|
|
34
|
+
return { claim };
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
const member = {
|
|
38
|
+
trigger: '@',
|
|
39
|
+
name: TEAM_MEMBER_SOURCE,
|
|
40
|
+
showGroupTitle: false,
|
|
41
|
+
async candidates(session, { query, signal }) {
|
|
42
|
+
if (!options.isEmbeddedMemberSession(session.sessionId))
|
|
43
|
+
return [];
|
|
44
|
+
const normalized = query.toLocaleLowerCase();
|
|
45
|
+
const members = await options.members();
|
|
46
|
+
if (signal.aborted)
|
|
47
|
+
return [];
|
|
48
|
+
return members
|
|
49
|
+
.filter(status => status.member.sessionId !== session.sessionId && status.member.state !== 'inactive')
|
|
50
|
+
.filter(status => status.member.handle.toLocaleLowerCase().startsWith(normalized))
|
|
51
|
+
.map(status => {
|
|
52
|
+
labels.set(status.member.memberId, `@${status.member.handle}`);
|
|
53
|
+
return {
|
|
54
|
+
name: `@${status.member.handle}`,
|
|
55
|
+
description: '引用成员 · 不会通知',
|
|
56
|
+
value: String(status.member.memberId),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
onPick({ candidate, session }) {
|
|
61
|
+
if (!options.isEmbeddedMemberSession(session.sessionId) || candidate.value === undefined)
|
|
62
|
+
return undefined;
|
|
63
|
+
const ref = candidate.value;
|
|
64
|
+
const label = labels.get(ref);
|
|
65
|
+
if (label === undefined)
|
|
66
|
+
return undefined;
|
|
67
|
+
const insert = {
|
|
68
|
+
source: TEAM_MEMBER_SOURCE,
|
|
69
|
+
// The input machine retains the typed trigger; label must therefore
|
|
70
|
+
// omit `@` or the draft would become `@@handle` after insertion.
|
|
71
|
+
label: label.slice(1),
|
|
72
|
+
ref,
|
|
73
|
+
clipboardText: label,
|
|
74
|
+
};
|
|
75
|
+
return { insert };
|
|
76
|
+
},
|
|
77
|
+
codec: {
|
|
78
|
+
clipboardText: ref => labels.get(ref) ?? `@${String(ref)}`,
|
|
79
|
+
serialize: async (ref) => {
|
|
80
|
+
const stable = String(ref);
|
|
81
|
+
const label = labels.get(ref) ?? '';
|
|
82
|
+
return `<team-member ref="${escapeAttribute(stable)}">${escapeText(label)}</team-member>`;
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
return [command, member];
|
|
87
|
+
}
|
|
88
|
+
/** Unknown leading slash must never fall into the shipped global palette. */
|
|
89
|
+
export function allowsMemberSessionSubmit(draft, claimToken) {
|
|
90
|
+
const trimmed = draft.trimStart();
|
|
91
|
+
return !trimmed.startsWith('/') || claimToken === '/compact';
|
|
92
|
+
}
|
|
93
|
+
function escapeText(value) {
|
|
94
|
+
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');
|
|
95
|
+
}
|
|
96
|
+
function escapeAttribute(value) {
|
|
97
|
+
return escapeText(value).replaceAll('"', '"').replaceAll("'", ''');
|
|
98
|
+
}
|
|
@@ -19,7 +19,7 @@ export interface TeamNavigationActions {
|
|
|
19
19
|
leaveTeam: () => void;
|
|
20
20
|
selectWorkspace: (workspaceId: WorkspaceId) => void;
|
|
21
21
|
selectChannel: (channelRef: AgentTeamChannelRef) => void;
|
|
22
|
-
selectThread: (
|
|
22
|
+
selectThread: (threadRef: AgentTeamThreadRef, channelRef?: AgentTeamChannelRef, taskRef?: AgentTeamTaskRef, taskNumber?: number) => void;
|
|
23
23
|
backToWorkspace: () => void;
|
|
24
24
|
/** Leave the selected Channel for the workspace Channel list; keeps mode and Workspace. */
|
|
25
25
|
backToChannels: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../src/client/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AACpF,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AAE/G,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,MAAM,CAAA;AAE9C,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,QAAQ,CAAA;IACd,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,UAAU,CAAC,EAAE,mBAAmB,CAAA;IAChC,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,SAAS,CAAC,EAAE,kBAAkB,CAAA;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sFAAsF;IACtF,eAAe,CAAC,EAAE,SAAS,CAAA;IAC3B,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,SAAS,CAAA;CAC9B;AAED,QAAA,MAAM,WAAW,8BAA8B,CAAA;AAuC/C,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,eAAe,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IACnD,aAAa,EAAE,CAAC,UAAU,EAAE,mBAAmB,KAAK,IAAI,CAAA;IACxD,YAAY,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../src/client/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AACpF,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AAE/G,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,MAAM,CAAA;AAE9C,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,QAAQ,CAAA;IACd,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,UAAU,CAAC,EAAE,mBAAmB,CAAA;IAChC,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,SAAS,CAAC,EAAE,kBAAkB,CAAA;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sFAAsF;IACtF,eAAe,CAAC,EAAE,SAAS,CAAA;IAC3B,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,SAAS,CAAA;CAC9B;AAED,QAAA,MAAM,WAAW,8BAA8B,CAAA;AAuC/C,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,eAAe,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IACnD,aAAa,EAAE,CAAC,UAAU,EAAE,mBAAmB,KAAK,IAAI,CAAA;IACxD,YAAY,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,UAAU,CAAC,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,gBAAgB,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACxI,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,2FAA2F;IAC3F,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,iBAAiB,CAAC,EAAE,SAAS,KAAK,IAAI,CAAA;IACjF,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,IAAI,CAAA;CAC9B;AAED,4EAA4E;AAC5E,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAElD,QAAQ,CAAC,WAAW,QAAO,sBAAsB,CAAiB;IAElE,QAAQ,CAAC,SAAS,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAGxD;IAED,OAAO,IAAI,qBAAqB;IAchC,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,gBAAgB;IAaxB,6EAA6E;IAC7E,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,SAAS;IAkBjB,OAAO,CAAC,MAAM;CAKf;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -4,14 +4,14 @@ function readSnapshot() {
|
|
|
4
4
|
return { mode: 'conversation' };
|
|
5
5
|
try {
|
|
6
6
|
const parsed = JSON.parse(localStorage.getItem(STORAGE_KEY) ?? '');
|
|
7
|
-
const hasThread = typeof parsed.
|
|
7
|
+
const hasThread = typeof parsed.threadRef === 'string';
|
|
8
8
|
return {
|
|
9
9
|
mode: parsed.mode === 'team' ? 'team' : 'conversation',
|
|
10
10
|
...(typeof parsed.workspaceId === 'string' ? { workspaceId: parsed.workspaceId } : {}),
|
|
11
11
|
...(typeof parsed.channelRef === 'string' ? { channelRef: parsed.channelRef } : {}),
|
|
12
12
|
...(hasThread ? {
|
|
13
|
-
taskRef: parsed.taskRef,
|
|
14
13
|
threadRef: parsed.threadRef,
|
|
14
|
+
...(typeof parsed.taskRef === 'string' ? { taskRef: parsed.taskRef } : {}),
|
|
15
15
|
...(typeof parsed.taskNumber === 'number' && Number.isInteger(parsed.taskNumber) && parsed.taskNumber > 0 ? { taskNumber: parsed.taskNumber } : {}),
|
|
16
16
|
} : {}),
|
|
17
17
|
};
|
|
@@ -53,7 +53,7 @@ export class TeamNavigation {
|
|
|
53
53
|
leaveTeam: () => { this.setMode('conversation'); },
|
|
54
54
|
selectWorkspace: workspaceId => { this.clearMemberSession(); this.setWorkspace(workspaceId); },
|
|
55
55
|
selectChannel: channelRef => { this.clearMemberSession(); this.setChannel(channelRef); },
|
|
56
|
-
selectThread: (
|
|
56
|
+
selectThread: (threadRef, channelRef, taskRef, taskNumber) => { this.clearMemberSession(); this.setThread(threadRef, channelRef, taskRef, taskNumber); },
|
|
57
57
|
backToWorkspace: () => { this.clearMemberSession(); this.setThread(undefined); },
|
|
58
58
|
backToChannels: () => { this.clearMemberSession(); this.clearChannel(); },
|
|
59
59
|
enterMemberSession: (sessionId, returnToSessionId) => { this.setMemberSession(sessionId, returnToSessionId); },
|
|
@@ -111,16 +111,22 @@ export class TeamNavigation {
|
|
|
111
111
|
this.snapshot = base;
|
|
112
112
|
this.commit();
|
|
113
113
|
}
|
|
114
|
-
setThread(
|
|
114
|
+
setThread(threadRef, channelRef, taskRef, taskNumber) {
|
|
115
115
|
if (this.snapshot.threadRef === threadRef && this.snapshot.taskRef === taskRef && this.snapshot.channelRef === channelRef && this.snapshot.taskNumber === taskNumber)
|
|
116
116
|
return;
|
|
117
|
-
if (threadRef === undefined
|
|
117
|
+
if (threadRef === undefined) {
|
|
118
118
|
const { taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
|
|
119
119
|
this.snapshot = base;
|
|
120
120
|
}
|
|
121
121
|
else {
|
|
122
122
|
const { channelRef: _channelRef, taskRef: _taskRef, threadRef: _threadRef, taskNumber: _taskNumber, ...base } = this.snapshot;
|
|
123
|
-
this.snapshot = {
|
|
123
|
+
this.snapshot = {
|
|
124
|
+
...base,
|
|
125
|
+
threadRef,
|
|
126
|
+
...(channelRef === undefined ? {} : { channelRef }),
|
|
127
|
+
...(taskRef === undefined ? {} : { taskRef }),
|
|
128
|
+
...(taskNumber === undefined ? {} : { taskNumber }),
|
|
129
|
+
};
|
|
124
130
|
}
|
|
125
131
|
this.commit();
|
|
126
132
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
2
|
+
import type { AgentTeamAttachmentId, AgentTeamPutAttachmentRequest, AgentTeamPutAttachmentResult, AgentTeamRequestId } from '@wowyuarm/dsh-agent-team/types';
|
|
3
|
+
/** Fresh idempotency identity for one Client-initiated durable request. */
|
|
4
|
+
export declare const mintRequestId: () => AgentTeamRequestId;
|
|
5
|
+
/**
|
|
6
|
+
* Upload composer files in order. One failure stops with the error text; the
|
|
7
|
+
* caller keeps its chips so a retry uploads only the still-pending files.
|
|
8
|
+
*/
|
|
9
|
+
export declare const uploadComposerFiles: (putAttachment: (request: AgentTeamPutAttachmentRequest) => Promise<RemoteResult<AgentTeamPutAttachmentResult>>, workspaceId: AgentTeamPutAttachmentRequest["workspaceId"], files: readonly File[]) => Promise<{
|
|
10
|
+
ok: true;
|
|
11
|
+
attachmentIds: readonly AgentTeamAttachmentId[];
|
|
12
|
+
} | {
|
|
13
|
+
ok: false;
|
|
14
|
+
error: string;
|
|
15
|
+
}>;
|
|
16
|
+
//# sourceMappingURL=requests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../../src/client/requests.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EACV,qBAAqB,EAAE,6BAA6B,EAAE,4BAA4B,EAAE,kBAAkB,EACvG,MAAM,gCAAgC,CAAA;AAGvC,2EAA2E;AAC3E,eAAO,MAAM,aAAa,QAAO,kBAA+D,CAAA;AAEhG;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC9B,eAAe,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAC,EAC9G,aAAa,6BAA6B,CAAC,aAAa,CAAC,EACzD,OAAO,SAAS,IAAI,EAAE,KACrB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,aAAa,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAatG,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { bytesToBase64 } from "./attachment-preview.js";
|
|
2
|
+
/** Fresh idempotency identity for one Client-initiated durable request. */
|
|
3
|
+
export const mintRequestId = () => crypto.randomUUID();
|
|
4
|
+
/**
|
|
5
|
+
* Upload composer files in order. One failure stops with the error text; the
|
|
6
|
+
* caller keeps its chips so a retry uploads only the still-pending files.
|
|
7
|
+
*/
|
|
8
|
+
export const uploadComposerFiles = async (putAttachment, workspaceId, files) => {
|
|
9
|
+
const attachmentIds = [];
|
|
10
|
+
for (const file of files) {
|
|
11
|
+
const uploaded = await putAttachment({
|
|
12
|
+
requestId: mintRequestId(), workspaceId,
|
|
13
|
+
name: file.name,
|
|
14
|
+
mediaType: file.type === '' ? undefined : file.type,
|
|
15
|
+
bytesBase64: bytesToBase64(new Uint8Array(await file.arrayBuffer())),
|
|
16
|
+
});
|
|
17
|
+
if (!uploaded.ok)
|
|
18
|
+
return { ok: false, error: uploaded.error.message };
|
|
19
|
+
attachmentIds.push(uploaded.value.attachmentId);
|
|
20
|
+
}
|
|
21
|
+
return { ok: true, attachmentIds };
|
|
22
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
-
import type { AgentTeamAddMemberRequest, AgentTeamChannelRef, AgentTeamClientMemberStatus, AgentTeamCreateChannelRequest, AgentTeamCreateChannelResult, AgentTeamJoinChannelRequest, AgentTeamJoinChannelResult, AgentTeamGetAttachmentRequest, AgentTeamGetAttachmentResult, AgentTeamPutAttachmentRequest, AgentTeamPutAttachmentResult, AgentTeamMemberResult, AgentTeamRecoverMemberRequest, AgentTeamRecoverMemberResult, AgentTeamMembersRequest, AgentTeamRemoveChannelMemberRequest, AgentTeamRemoveChannelMemberResult, AgentTeamReplyRequest, AgentTeamResolveTaskRefsRequest, AgentTeamResolveTaskRefsResult, AgentTeamReplyResult, AgentTeamConfirmationRequired, AgentTeamThreadHistory, AgentTeamThreadHistoryRequest, AgentTeamThreadReadRequest, AgentTeamThreadReadResult, AgentTeamTaskRequest, AgentTeamTaskResult, AgentTeamSendMessageRequest, AgentTeamSendMessageResult, AgentTeamUpdateChannelRequest, AgentTeamUpdateChannelResult, AgentTeamUpdateMemberRequest, AgentTeamView, AgentTeamViewRequest } from '@wowyuarm/dsh-agent-team/types';
|
|
2
|
+
import type { AgentTeamAddMemberRequest, AgentTeamChannelRef, AgentTeamClientMemberStatus, AgentTeamCreateChannelRequest, AgentTeamCreateChannelResult, AgentTeamJoinChannelRequest, AgentTeamJoinChannelResult, AgentTeamGetAttachmentRequest, AgentTeamGetAttachmentResult, AgentTeamPutAttachmentRequest, AgentTeamPutAttachmentResult, AgentTeamMemberResult, AgentTeamRecoverMemberRequest, AgentTeamRecoverMemberResult, AgentTeamMembersRequest, AgentTeamRemoveChannelMemberRequest, AgentTeamRemoveChannelMemberResult, AgentTeamReplyRequest, AgentTeamResolveTaskRefsRequest, AgentTeamResolveTaskRefsResult, AgentTeamReplyResult, AgentTeamConfirmationRequired, AgentTeamThreadHistory, AgentTeamThreadHistoryRequest, AgentTeamThreadReadRequest, AgentTeamThreadReadResult, AgentTeamPromoteThreadRequest, AgentTeamPromoteThreadResult, AgentTeamTaskRequest, AgentTeamTaskResult, AgentTeamSendMessageRequest, AgentTeamSendMessageResult, AgentTeamUpdateChannelRequest, AgentTeamUpdateChannelResult, AgentTeamUpdateMemberRequest, AgentTeamView, AgentTeamViewRequest } from '@wowyuarm/dsh-agent-team/types';
|
|
3
3
|
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
4
4
|
import type { TeamNavigationActions, TeamNavigationSnapshot } from './navigation.ts';
|
|
5
5
|
import type { TeamChangeListener, TeamChangeScope } from './team-changes.ts';
|
|
@@ -72,6 +72,7 @@ export type TeamConversationProps = PropsRuntime<'conversation'> & PropsLocale<'
|
|
|
72
72
|
removeChannelMember: (request: AgentTeamRemoveChannelMemberRequest) => Promise<RemoteResult<AgentTeamRemoveChannelMemberResult>>;
|
|
73
73
|
reply: (request: AgentTeamReplyRequest) => Promise<RemoteResult<AgentTeamReplyResult | AgentTeamConfirmationRequired>>;
|
|
74
74
|
changeTask: (request: AgentTeamTaskRequest) => Promise<RemoteResult<AgentTeamTaskResult>>;
|
|
75
|
+
promoteThread: (request: AgentTeamPromoteThreadRequest) => Promise<RemoteResult<AgentTeamPromoteThreadResult>>;
|
|
75
76
|
resolveTaskRefs: (request: AgentTeamResolveTaskRefsRequest) => Promise<RemoteResult<AgentTeamResolveTaskRefsResult>>;
|
|
76
77
|
loadMembers: (request: AgentTeamMembersRequest) => Promise<RemoteResult<readonly AgentTeamClientMemberStatus[]>>;
|
|
77
78
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../../src/client/slots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,2BAA2B,EAC3B,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,mCAAmC,EACnC,kCAAkC,EAClC,qBAAqB,EACrB,+BAA+B,EAC/B,8BAA8B,
|
|
1
|
+
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../../src/client/slots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,2BAA2B,EAC3B,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,mCAAmC,EACnC,kCAAkC,EAClC,qBAAqB,EACrB,+BAA+B,EAC/B,8BAA8B,EAC9B,oBAAoB,EACpB,6BAA6B,EAC7B,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,4BAA4B,EAC5B,oBAAoB,EACpB,mBAAmB,EACnB,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,4BAA4B,EAC5B,aAAa,EACb,oBAAoB,EACrB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACpF,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,sBAAsB,CAAA;IACzC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;CAChD;AAED,gGAAgG;AAChG,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,kBAAkB,KAAK,MAAM,IAAI,CAAA;AAEvG,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE;QACnB,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAA;KACnD,CAAA;CACF;AAED,2EAA2E;AAC3E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;CAC5C;AAED,sFAAsF;AACtF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAClD,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CACvG;AAED,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,oBAAoB,CAAC,GAC7D,WAAW,CAAC,MAAM,CAAC,GACnB,qBAAqB,GACrB;IACA,UAAU,EAAE,oBAAoB,CAAA;IAChC,WAAW,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,YAAY,CAAC,SAAS,2BAA2B,EAAE,CAAC,CAAC,CAAA;IAChH,gBAAgB,EAAE,oBAAoB,CAAA;IACtC,SAAS,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAA;IAC/F,YAAY,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAA;IACrF,aAAa,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAC,CAAA;IAC9G,aAAa,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAC,CAAA;IAC9G,YAAY,EAAE,CAAC,OAAO,EAAE,4BAA4B,KAAK,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAA;IACrG,aAAa,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAC,CAAA;IAC9G,WAAW,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC,CAAA;IACxG,mBAAmB,EAAE,CAAC,OAAO,EAAE,mCAAmC,KAAK,OAAO,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAAC,CAAA;IAChI,mFAAmF;IACnF,UAAU,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAA;IACzD,6EAA6E;IAC7E,iBAAiB,EAAE,CAAC,SAAS,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;IAC1F,kBAAkB,CAAC,EAAE,mBAAmB,CAAA;CACzC,CAAA;AAEH,MAAM,MAAM,qBAAqB,GAAG,YAAY,CAAC,cAAc,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,qBAAqB,GAAG;IAC/G,UAAU,EAAE,oBAAoB,CAAA;IAChC,gEAAgE;IAChE,MAAM,EAAE,cAAc,CAAA;IACtB,YAAY,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAA;IACrF,UAAU,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,OAAO,CAAC,YAAY,CAAC,yBAAyB,CAAC,CAAC,CAAA;IACrG,iBAAiB,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAC5G,gBAAgB,EAAE,oBAAoB,CAAA;IACtC,aAAa,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAC,CAAA;IAC9G,aAAa,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAC,CAAA;IAC9G,WAAW,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC,CAAA;IACxG,WAAW,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC,CAAA;IACxG,mBAAmB,EAAE,CAAC,OAAO,EAAE,mCAAmC,KAAK,OAAO,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAAC,CAAA;IAChI,KAAK,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,YAAY,CAAC,oBAAoB,GAAG,6BAA6B,CAAC,CAAC,CAAA;IACtH,UAAU,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC,CAAA;IACzF,aAAa,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAC,CAAA;IAC9G,eAAe,EAAE,CAAC,OAAO,EAAE,+BAA+B,KAAK,OAAO,CAAC,YAAY,CAAC,8BAA8B,CAAC,CAAC,CAAA;IACpH,WAAW,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,YAAY,CAAC,SAAS,2BAA2B,EAAE,CAAC,CAAC,CAAA;CACjH,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG;IACvF,gBAAgB,EAAE,MAAM,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAAA;CAC5D,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,2BAA2B,EAAE,CAAA;CACzD;AAED,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,uBAAuB,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,qBAAqB,GAAG;IAClH,UAAU,EAAE,oBAAoB,CAAA;IAChC,gBAAgB,EAAE,MAAM,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAAA;CAC5D,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
2
|
+
import type { AgentTeamChannelRef, AgentTeamResolveTaskRefsRequest, AgentTeamResolveTaskRefsResult, AgentTeamTaskRef, AgentTeamThreadRef } from '@wowyuarm/dsh-agent-team/types';
|
|
2
3
|
/** Navigation facts for one branded Task ref, resolved once per session. */
|
|
3
4
|
export interface ResolvedTaskRef {
|
|
4
5
|
readonly taskRef: AgentTeamTaskRef;
|
|
@@ -11,6 +12,10 @@ export declare const useResolvedTaskRefVersion: () => number;
|
|
|
11
12
|
export declare const cachedResolvedTaskRef: (taskRef: AgentTeamTaskRef) => ResolvedTaskRef | undefined;
|
|
12
13
|
/** Store one resolution (click path) and wake every rendered link. */
|
|
13
14
|
export declare const rememberResolvedTaskRef: (entry: ResolvedTaskRef) => void;
|
|
15
|
+
/** Click-path Host lookup: remember every resolved entry and hand them back for immediate navigation. */
|
|
16
|
+
export declare const hostTaskRefLookup: (resolveTaskRefs: (request: AgentTeamResolveTaskRefsRequest) => Promise<RemoteResult<AgentTeamResolveTaskRefsResult>>, workspaceId: AgentTeamResolveTaskRefsRequest["workspaceId"]) => ((taskRefs: readonly AgentTeamTaskRef[]) => Promise<readonly ResolvedTaskRef[]>);
|
|
17
|
+
/** Resolve one Task ref through the Host and jump to its home Channel Thread. */
|
|
18
|
+
export declare const jumpToTaskThread: (resolveTaskRefs: (request: AgentTeamResolveTaskRefsRequest) => Promise<RemoteResult<AgentTeamResolveTaskRefsResult>>, workspaceId: AgentTeamResolveTaskRefsRequest["workspaceId"], taskRef: AgentTeamTaskRef, selectThread: (threadRef: AgentTeamThreadRef, channelRef?: AgentTeamChannelRef, taskRef?: AgentTeamTaskRef, taskNumber?: number) => void) => void;
|
|
14
19
|
/**
|
|
15
20
|
* Batch-resolve unknown refs through the Host lookup. Concurrent callers
|
|
16
21
|
* deduplicate through the pending set; failures just clear the pending mark
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-refs.d.ts","sourceRoot":"","sources":["../../../src/client/task-refs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"task-refs.d.ts","sourceRoot":"","sources":["../../../src/client/task-refs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EACV,mBAAmB,EAAE,+BAA+B,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,kBAAkB,EAC3H,MAAM,gCAAgC,CAAA;AAEvC,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAA;IACxC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAwBD,0EAA0E;AAC1E,eAAO,MAAM,yBAAyB,QAAO,MAAmE,CAAA;AAEhH,eAAO,MAAM,qBAAqB,GAAI,SAAS,gBAAgB,KAAG,eAAe,GAAG,SAAkC,CAAA;AAEtH,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,GAAI,OAAO,eAAe,KAAG,IAIhE,CAAA;AAED,yGAAyG;AACzG,eAAO,MAAM,iBAAiB,GAC5B,iBAAiB,CAAC,OAAO,EAAE,+BAA+B,KAAK,OAAO,CAAC,YAAY,CAAC,8BAA8B,CAAC,CAAC,EACpH,aAAa,+BAA+B,CAAC,aAAa,CAAC,KAC1D,CAAC,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,KAAK,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAM/E,CAAA;AAEH,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,CAAC,OAAO,EAAE,+BAA+B,KAAK,OAAO,CAAC,YAAY,CAAC,8BAA8B,CAAC,CAAC,EACpH,aAAa,+BAA+B,CAAC,aAAa,CAAC,EAC3D,SAAS,gBAAgB,EACzB,cAAc,CAAC,SAAS,EAAE,kBAAkB,EAAE,UAAU,CAAC,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,gBAAgB,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,KACvI,IAMF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,MAAM,SAAS,gBAAgB,EAAE,EACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,KAAK,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,KACrF,OAAO,CAAC,IAAI,CAmBd,CAAA"}
|
|
@@ -25,6 +25,25 @@ export const rememberResolvedTaskRef = (entry) => {
|
|
|
25
25
|
pending.delete(entry.taskRef);
|
|
26
26
|
emit();
|
|
27
27
|
};
|
|
28
|
+
/** Click-path Host lookup: remember every resolved entry and hand them back for immediate navigation. */
|
|
29
|
+
export const hostTaskRefLookup = (resolveTaskRefs, workspaceId) => async (taskRefs) => {
|
|
30
|
+
const result = await resolveTaskRefs({ workspaceId, taskRefs });
|
|
31
|
+
if (!result.ok)
|
|
32
|
+
return [];
|
|
33
|
+
for (const entry of result.value.resolved)
|
|
34
|
+
rememberResolvedTaskRef(entry);
|
|
35
|
+
return result.value.resolved;
|
|
36
|
+
};
|
|
37
|
+
/** Resolve one Task ref through the Host and jump to its home Channel Thread. */
|
|
38
|
+
export const jumpToTaskThread = (resolveTaskRefs, workspaceId, taskRef, selectThread) => {
|
|
39
|
+
void resolveTaskRefs({ workspaceId, taskRefs: [taskRef] }).then(result => {
|
|
40
|
+
if (!result.ok)
|
|
41
|
+
return;
|
|
42
|
+
const hit = result.value.resolved[0];
|
|
43
|
+
if (hit !== undefined)
|
|
44
|
+
selectThread(hit.threadRef, hit.channelRef, hit.taskRef, hit.taskNumber);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
28
47
|
/**
|
|
29
48
|
* Batch-resolve unknown refs through the Host lookup. Concurrent callers
|
|
30
49
|
* deduplicate through the pending set; failures just clear the pending mark
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentTeamActivity, AgentTeamClaim, AgentTeamMemberId, AgentTeamTask } from '@wowyuarm/dsh-agent-team/types';
|
|
1
|
+
import type { AgentTeamActivity, AgentTeamClaim, AgentTeamMemberId, AgentTeamTask, AgentTeamTaskRef } from '@wowyuarm/dsh-agent-team/types';
|
|
2
2
|
import type { TeamConversationProps } from './slots.ts';
|
|
3
3
|
export declare function formatTaskStatus(status: AgentTeamTask['status'], t: TeamConversationProps['t']): string;
|
|
4
4
|
export declare function formatClaimState(state: AgentTeamClaim['state'], t: TeamConversationProps['t']): string;
|
|
@@ -22,10 +22,18 @@ export interface RefSegment {
|
|
|
22
22
|
/**
|
|
23
23
|
* Split a literal text run into plain and branded-ref segments. The pattern
|
|
24
24
|
* anchors on the fixed ref prefixes plus the UUID shape, so ordinary prose
|
|
25
|
-
* containing a colon never linkifies
|
|
26
|
-
*
|
|
25
|
+
* containing a colon never linkifies; a doubled colon from model output is
|
|
26
|
+
* tolerated. Segment refs are always canonical, so resolution and navigation
|
|
27
|
+
* work regardless of how the ref was spelled; text without any ref comes
|
|
28
|
+
* back as one untouched segment.
|
|
27
29
|
*/
|
|
28
30
|
export declare function splitBrandedRefs(text: string): readonly RefSegment[];
|
|
31
|
+
/**
|
|
32
|
+
* Whether one string's whole content is exactly one branded ref. A code span
|
|
33
|
+
* like this is the model styling a ref as an identifier, not publishing code,
|
|
34
|
+
* so the Markdown pass may linkify it; anything larger stays literal.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isSingleBrandedRef(text: string): boolean;
|
|
29
37
|
export interface MentionSegment {
|
|
30
38
|
readonly text: string;
|
|
31
39
|
readonly mention: boolean;
|
|
@@ -65,4 +73,45 @@ export declare function formatActivity(activity: AgentTeamActivity, options: {
|
|
|
65
73
|
}): string;
|
|
66
74
|
/** Remove the machine-facing `[attachment] <path>` prompt lines from a body before display. */
|
|
67
75
|
export declare function stripAttachmentLines(body: string): string;
|
|
76
|
+
/**
|
|
77
|
+
* Displayed bodies past this character count render clamped behind an expand
|
|
78
|
+
* control. The rule is deterministic from the body alone, so every surface
|
|
79
|
+
* derives the same default for the same Message and no client has to remember
|
|
80
|
+
* a fold state.
|
|
81
|
+
*/
|
|
82
|
+
export declare const MESSAGE_COLLAPSE_CHARS = 600;
|
|
83
|
+
/** Whether one displayed Message body starts clamped behind the expand control. */
|
|
84
|
+
export declare function shouldClampMessage(displayBody: string): boolean;
|
|
85
|
+
/** How one Message body renders: mention-chip segments, literal text, or Markdown. */
|
|
86
|
+
export type MessageBodyRender = 'inline' | 'literal' | 'markdown';
|
|
87
|
+
/** Rendering decision for one Message body, resolved once from its stored form. */
|
|
88
|
+
export interface PlannedMessageBody {
|
|
89
|
+
/** Stored body without machine-facing attachment prompt lines; the raw body when stripping would empty it. */
|
|
90
|
+
readonly displayBody: string;
|
|
91
|
+
/** Rich Agent Markdown: only such bodies get the post-render chipify pass. */
|
|
92
|
+
readonly richAgentBody: boolean;
|
|
93
|
+
/** Which rendering branch the body takes. */
|
|
94
|
+
readonly render: MessageBodyRender;
|
|
95
|
+
/** Mention-chip segments for literal bodies; absent on the Markdown branch. */
|
|
96
|
+
readonly inline?: ReturnType<typeof splitMentionNames>;
|
|
97
|
+
/** Mention handles that did not render as chips; the trailing row shows them. */
|
|
98
|
+
readonly fallbackNames: readonly string[];
|
|
99
|
+
/** Non-Task branded refs for the trailing fallback row; rich Agent bodies keep the legacy row. */
|
|
100
|
+
readonly fallbackRefs: readonly string[];
|
|
101
|
+
/** Task refs authored in a literal body; resolved labels replace them in place. */
|
|
102
|
+
readonly taskRefs: readonly AgentTeamTaskRef[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Decide how one Message body renders. Human input and plain-prose Agent
|
|
106
|
+
* bodies stay literal, with structured mention chips inline where possible;
|
|
107
|
+
* rich Agent Markdown keeps unmatched mentions and non-Task refs in the
|
|
108
|
+
* trailing fallback row while the post-render pass handles Task refs at their
|
|
109
|
+
* authored position. Surfaces without ref navigation render everything
|
|
110
|
+
* literally and keep the full fallback row.
|
|
111
|
+
*/
|
|
112
|
+
export declare function planMessageBody(body: string, options: {
|
|
113
|
+
readonly human: boolean;
|
|
114
|
+
readonly mentionNames?: readonly string[];
|
|
115
|
+
readonly canOpenRefs: boolean;
|
|
116
|
+
}): PlannedMessageBody;
|
|
68
117
|
//# sourceMappingURL=team-formatters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-formatters.d.ts","sourceRoot":"","sources":["../../../src/client/team-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"team-formatters.d.ts","sourceRoot":"","sources":["../../../src/client/team-formatters.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,12 +35,22 @@ export function memberHue(memberId) {
|
|
|
35
35
|
hash = (hash * 31 + memberId.charCodeAt(index)) % 360;
|
|
36
36
|
return hash;
|
|
37
37
|
}
|
|
38
|
-
const BRANDED_REF_PATTERN = /\b(task|channel|thread):[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi;
|
|
38
|
+
const BRANDED_REF_PATTERN = /\b(task|channel|thread):{1,2}[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi;
|
|
39
|
+
/**
|
|
40
|
+
* Canonical form of one matched ref: models occasionally double the colon or
|
|
41
|
+
* uppercase the UUID when citing a ref in prose, while Host lookups and
|
|
42
|
+
* navigation only accept the lowercase single-colon ref the ledger mints.
|
|
43
|
+
*/
|
|
44
|
+
function canonicalBrandedRef(match) {
|
|
45
|
+
return match.replace('::', ':').toLowerCase();
|
|
46
|
+
}
|
|
39
47
|
/**
|
|
40
48
|
* Split a literal text run into plain and branded-ref segments. The pattern
|
|
41
49
|
* anchors on the fixed ref prefixes plus the UUID shape, so ordinary prose
|
|
42
|
-
* containing a colon never linkifies
|
|
43
|
-
*
|
|
50
|
+
* containing a colon never linkifies; a doubled colon from model output is
|
|
51
|
+
* tolerated. Segment refs are always canonical, so resolution and navigation
|
|
52
|
+
* work regardless of how the ref was spelled; text without any ref comes
|
|
53
|
+
* back as one untouched segment.
|
|
44
54
|
*/
|
|
45
55
|
export function splitBrandedRefs(text) {
|
|
46
56
|
const segments = [];
|
|
@@ -49,13 +59,25 @@ export function splitBrandedRefs(text) {
|
|
|
49
59
|
const start = match.index ?? 0;
|
|
50
60
|
if (start > cursor)
|
|
51
61
|
segments.push({ text: text.slice(cursor, start) });
|
|
52
|
-
segments.push({ text: match[0], ref: match[0] });
|
|
62
|
+
segments.push({ text: match[0], ref: canonicalBrandedRef(match[0]) });
|
|
53
63
|
cursor = start + match[0].length;
|
|
54
64
|
}
|
|
55
65
|
if (cursor < text.length)
|
|
56
66
|
segments.push({ text: text.slice(cursor) });
|
|
57
67
|
return segments;
|
|
58
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Whether one string's whole content is exactly one branded ref. A code span
|
|
71
|
+
* like this is the model styling a ref as an identifier, not publishing code,
|
|
72
|
+
* so the Markdown pass may linkify it; anything larger stays literal.
|
|
73
|
+
*/
|
|
74
|
+
export function isSingleBrandedRef(text) {
|
|
75
|
+
const trimmed = text.trim();
|
|
76
|
+
if (trimmed === '')
|
|
77
|
+
return false;
|
|
78
|
+
const matches = [...trimmed.matchAll(BRANDED_REF_PATTERN)];
|
|
79
|
+
return matches.length === 1 && matches[0][0] === trimmed;
|
|
80
|
+
}
|
|
59
81
|
function escapeRegExp(value) {
|
|
60
82
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
61
83
|
}
|
|
@@ -133,6 +155,8 @@ export function formatActivity(activity, options) {
|
|
|
133
155
|
? options.t('activityAcceptedWithClaims', { actor, count: activity.completedClaimRefs.length })
|
|
134
156
|
: options.t('activityAccepted', { actor });
|
|
135
157
|
}
|
|
158
|
+
if (activity.kind === 'promote')
|
|
159
|
+
return options.t('activityPromoted', { actor });
|
|
136
160
|
if (activity.kind === 'close')
|
|
137
161
|
return options.t('activityClosed', { actor });
|
|
138
162
|
if (activity.kind === 'reopen')
|
|
@@ -154,3 +178,49 @@ export function formatActivity(activity, options) {
|
|
|
154
178
|
export function stripAttachmentLines(body) {
|
|
155
179
|
return body.replaceAll(/^\[attachment\] .*$(\n)?/gm, '').replace(/\n+$/, '');
|
|
156
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Displayed bodies past this character count render clamped behind an expand
|
|
183
|
+
* control. The rule is deterministic from the body alone, so every surface
|
|
184
|
+
* derives the same default for the same Message and no client has to remember
|
|
185
|
+
* a fold state.
|
|
186
|
+
*/
|
|
187
|
+
export const MESSAGE_COLLAPSE_CHARS = 600;
|
|
188
|
+
/** Whether one displayed Message body starts clamped behind the expand control. */
|
|
189
|
+
export function shouldClampMessage(displayBody) {
|
|
190
|
+
return displayBody.length > MESSAGE_COLLAPSE_CHARS;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Decide how one Message body renders. Human input and plain-prose Agent
|
|
194
|
+
* bodies stay literal, with structured mention chips inline where possible;
|
|
195
|
+
* rich Agent Markdown keeps unmatched mentions and non-Task refs in the
|
|
196
|
+
* trailing fallback row while the post-render pass handles Task refs at their
|
|
197
|
+
* authored position. Surfaces without ref navigation render everything
|
|
198
|
+
* literally and keep the full fallback row.
|
|
199
|
+
*/
|
|
200
|
+
export function planMessageBody(body, options) {
|
|
201
|
+
const stripped = stripAttachmentLines(body);
|
|
202
|
+
const displayBody = stripped === '' ? body : stripped;
|
|
203
|
+
const richAgentBody = !options.human && !isPlainTextBody(displayBody);
|
|
204
|
+
const inline = (options.human || isPlainTextBody(displayBody)) && options.mentionNames !== undefined && options.mentionNames.length > 0
|
|
205
|
+
? splitMentionNames(displayBody, options.mentionNames)
|
|
206
|
+
: undefined;
|
|
207
|
+
const fallbackNames = inline !== undefined ? inline.unmatched
|
|
208
|
+
: richAgentBody && options.canOpenRefs && options.mentionNames !== undefined
|
|
209
|
+
? splitMentionNames(displayBody, options.mentionNames).unmatched
|
|
210
|
+
: options.mentionNames ?? [];
|
|
211
|
+
const refs = splitBrandedRefs(displayBody).flatMap(segment => segment.ref === undefined ? [] : [segment.ref]);
|
|
212
|
+
const render = inline !== undefined ? 'inline'
|
|
213
|
+
: options.human || (options.canOpenRefs && !richAgentBody && refs.length > 0) ? 'literal'
|
|
214
|
+
: 'markdown';
|
|
215
|
+
return {
|
|
216
|
+
displayBody,
|
|
217
|
+
richAgentBody,
|
|
218
|
+
render,
|
|
219
|
+
...(inline === undefined ? {} : { inline }),
|
|
220
|
+
fallbackNames,
|
|
221
|
+
fallbackRefs: richAgentBody && options.canOpenRefs ? refs.filter(ref => !ref.startsWith('task:')) : [],
|
|
222
|
+
taskRefs: options.canOpenRefs && !richAgentBody
|
|
223
|
+
? refs.filter(ref => ref.startsWith('task:')).map(ref => ref)
|
|
224
|
+
: [],
|
|
225
|
+
};
|
|
226
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-membership.d.ts","sourceRoot":"","sources":["../../../src/client/team-membership.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"team-membership.d.ts","sourceRoot":"","sources":["../../../src/client/team-membership.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,mBAAmB,EACnB,2BAA2B,EAC3B,0BAA0B,EAC1B,iBAAiB,EACjB,mCAAmC,EACnC,kCAAkC,EAEnC,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AAEzE,0EAA0E;AAC1E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAA;IACxC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC,CAAA;IACjH,QAAQ,CAAC,mBAAmB,EAAE,CAAC,OAAO,EAAE,mCAAmC,KAAK,OAAO,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAAC,CAAA;CAC1I;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,0BAA0B,EACrC,QAAQ,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,MAAM,EACrD,WAAW,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACrE;IACD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACrC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5C,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACpE,CA6BA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useRef, useState } from 'react';
|
|
2
|
+
import { mintRequestId } from "./requests.js";
|
|
2
3
|
/**
|
|
3
4
|
* Shared Channel membership mutation. One stable requestId per direction,
|
|
4
5
|
* Member, and Channel survives transport failures until the Host commits it;
|
|
@@ -15,7 +16,7 @@ export function useChannelMembership(transport, rowKeyOf, onCommitted) {
|
|
|
15
16
|
setPending(current => new Set(current).add(rowKey));
|
|
16
17
|
setErrors(current => { const next = new Map(current); next.delete(rowKey); return next; });
|
|
17
18
|
const key = `${membership.joined ? 'remove' : 'join'}:${membership.memberId}:${membership.channelRef}`;
|
|
18
|
-
const requestId = requestIds.current.get(key) ??
|
|
19
|
+
const requestId = requestIds.current.get(key) ?? mintRequestId();
|
|
19
20
|
requestIds.current.set(key, requestId);
|
|
20
21
|
const request = { requestId, workspaceId: membership.workspaceId, channelRef: membership.channelRef, memberId: membership.memberId };
|
|
21
22
|
try {
|
|
@@ -6,15 +6,15 @@ Model-facing tools for Agent Team Members. The package registers tools in the ca
|
|
|
6
6
|
|
|
7
7
|
## Tools
|
|
8
8
|
|
|
9
|
-
- `team_inbox` lists bounded unread Thread summaries for the calling Member, ordered by direct work and then recency.
|
|
10
|
-
- `team_thread` reads a Thread, pages history, follows, or unfollows. `read` atomically returns the
|
|
11
|
-
- `team_message` starts a top-level
|
|
12
|
-
- `team_claim` lists or mutates the calling Member's Direction Claims through `list`, `claim`, `done`, and `release
|
|
13
|
-
- `team_view` discovers bounded, membership-authorized Channel, Task, and Member summaries. It does not return Thread messages or activities.
|
|
9
|
+
- `team_inbox` lists bounded unread Thread summaries for the calling Member, ordered by direct work and then recency; Task status/number appear only where the Thread has a real Task overlay.
|
|
10
|
+
- `team_thread` reads a Thread, pages history, follows, or unfollows. `threadRef` is primary; a `taskRef` is a Host alias only for released task-only Clients. `read` atomically returns the Thread anchor, optional current Task and Claim snapshot, bounded orientation facts, and one contiguous unread batch while advancing the durable watermark; `history` never changes read state.
|
|
11
|
+
- `team_message` starts a top-level Thread or replies to an existing Thread. It defaults to a taskless Thread; pass `asTask: true` for atomic Task creation. Replies require the exact `baseRevision` and reject unread work before checking revision freshness.
|
|
12
|
+
- `team_claim` lists or mutates the calling Member's Direction Claims through `list`, `claim`, `done`, and `release`; it applies only to real Tasks. Direction exclusion uses Unicode NFKC normalization, trim, whitespace compression, and deterministic case folding.
|
|
13
|
+
- `team_view` discovers bounded, membership-authorized Channel, real Task, and Member summaries. It does not return Thread messages or activities.
|
|
14
14
|
|
|
15
|
-
An Agent cannot silently enroll an unfollowed Agent through a mention; the Host returns `member_not_following`. Human confirmation is a separate Host/Client flow. Closed Tasks reject replies, Claims, and new Attention until a Human reopens them.
|
|
15
|
+
An Agent cannot silently enroll an unfollowed Agent through a mention; the Host returns `member_not_following`. Human confirmation is a separate Host/Client flow. Closed Tasks reject replies, Claims, and new Attention until a Human reopens them; taskless Threads have no Claim or Task-resolution mutation path.
|
|
16
16
|
|
|
17
|
-
Canonical results expose stable refs,
|
|
17
|
+
Canonical results expose stable refs, optional Task status, Thread revision, Claim history, Attention, and unread facts. Typed `unread_required` and `stale_revision` results include the fields needed to reread and retry deliberately. Tool execution resolves the exact live `exec.agent`; arguments cannot select or impersonate the actor or Workspace. Write request identity derives from sessionId plus tool callId. Team tools return to the model loop and never conclude the turn.
|
|
18
18
|
|
|
19
19
|
The complete implemented protocol is documented in [`../../docs/team-collaboration.md`](../../docs/team-collaboration.md).
|
|
20
20
|
|