@wowyuarm/dsh-agent-team 0.1.5 → 0.1.6
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 +15 -1
- package/README.zh.md +15 -1
- package/package.json +7 -2
- package/packages/agent-team/README.md +6 -0
- package/packages/agent-team/README.zh.md +6 -0
- package/packages/agent-team/core-skills/member-skill-manager/SKILL.md +41 -0
- package/packages/agent-team/core-skills/member-skill-manager/references/auth-and-config.md +30 -0
- package/packages/agent-team/core-skills/member-skill-manager/references/writing-great-skills.md +17 -0
- package/packages/agent-team/lib/index.js +255 -2
- package/packages/agent-team/lib/ledger.js +139 -5
- package/packages/agent-team/lib/member-context.js +2 -2
- package/packages/agent-team/lib/member-skills.js +94 -0
- package/packages/agent-team/lib/spec.js +26 -0
- package/packages/agent-team/lib/typert.host.js +131 -28
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +99 -23
- package/packages/agent-team/lib/types/index.d.ts +69 -1
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/ledger.d.ts +29 -1
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-skills.d.ts +45 -0
- package/packages/agent-team/lib/types/member-skills.d.ts.map +1 -0
- package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types.d.ts +87 -2
- package/packages/agent-team/lib/types/types.d.ts.map +1 -1
- package/packages/agent-team/preset/team-member/agent.cordis.yml +7 -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 +217 -299
- package/packages/client-agent-team/lib/client.js.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts +1 -4
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +11 -23
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts +4 -8
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +7 -40
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +61 -20
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +1 -1
- package/packages/client-agent-team/lib/types/client/locales.d.ts +4 -16
- package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/locales.js +4 -16
- package/packages/client-agent-team/lib/types/client/timeline-scroll.d.ts +5 -7
- package/packages/client-agent-team/lib/types/client/timeline-scroll.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/timeline-scroll.js +9 -22
- package/packages/tool-agent-team/lib/index.js +25 -5
- package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
|
@@ -3,16 +3,14 @@ export interface TimelineScroll {
|
|
|
3
3
|
onScroll: () => void;
|
|
4
4
|
/** Whether the reader currently sits within the follow margin of the bottom. */
|
|
5
5
|
isPinned: () => boolean;
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
/** Jump to the latest fact on the next content commit. */
|
|
9
|
-
jumpToLatest: () => void;
|
|
6
|
+
/** Scroll the timeline to the latest fact immediately. */
|
|
7
|
+
scrollToBottom: () => void;
|
|
10
8
|
}
|
|
11
9
|
/**
|
|
12
10
|
* Chat-timeline scroll policy shared by the Channel and Thread pages: follow
|
|
13
|
-
* new facts only while the reader stays pinned to the bottom, keep
|
|
14
|
-
* history visually stable
|
|
15
|
-
*
|
|
11
|
+
* new facts only while the reader stays pinned to the bottom, and keep
|
|
12
|
+
* prepended history visually stable. The content key must change whenever
|
|
13
|
+
* rendered facts change.
|
|
16
14
|
*/
|
|
17
15
|
export declare function useTimelineScroll(contentKey: string): TimelineScroll;
|
|
18
16
|
//# sourceMappingURL=timeline-scroll.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline-scroll.d.ts","sourceRoot":"","sources":["../../../src/client/timeline-scroll.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"timeline-scroll.d.ts","sourceRoot":"","sources":["../../../src/client/timeline-scroll.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;IAC1C,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,OAAO,CAAA;IACvB,0DAA0D;IAC1D,cAAc,EAAE,MAAM,IAAI,CAAA;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAiCpE"}
|
|
@@ -1,30 +1,26 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef } from 'react';
|
|
2
2
|
const BOTTOM_MARGIN_PX = 48;
|
|
3
|
-
const BOUNDARY_OFFSET_PX = 12;
|
|
4
3
|
/**
|
|
5
4
|
* Chat-timeline scroll policy shared by the Channel and Thread pages: follow
|
|
6
|
-
* new facts only while the reader stays pinned to the bottom, keep
|
|
7
|
-
* history visually stable
|
|
8
|
-
*
|
|
5
|
+
* new facts only while the reader stays pinned to the bottom, and keep
|
|
6
|
+
* prepended history visually stable. The content key must change whenever
|
|
7
|
+
* rendered facts change.
|
|
9
8
|
*/
|
|
10
9
|
export function useTimelineScroll(contentKey) {
|
|
11
10
|
const ref = useRef(null);
|
|
12
11
|
const pinnedRef = useRef(true);
|
|
13
12
|
const heightRef = useRef(0);
|
|
14
|
-
const jumpRef = useRef();
|
|
15
13
|
const onScroll = useCallback(() => {
|
|
16
14
|
const element = ref.current;
|
|
17
15
|
if (element === null)
|
|
18
16
|
return;
|
|
19
17
|
pinnedRef.current = element.scrollHeight - element.scrollTop - element.clientHeight < BOTTOM_MARGIN_PX;
|
|
20
18
|
}, []);
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
pinnedRef.current = false;
|
|
24
|
-
}, []);
|
|
25
|
-
const jumpToLatest = useCallback(() => {
|
|
26
|
-
jumpRef.current = 'latest';
|
|
19
|
+
const scrollToBottom = useCallback(() => {
|
|
20
|
+
const element = ref.current;
|
|
27
21
|
pinnedRef.current = true;
|
|
22
|
+
if (element !== null)
|
|
23
|
+
element.scrollTop = element.scrollHeight;
|
|
28
24
|
}, []);
|
|
29
25
|
useEffect(() => {
|
|
30
26
|
const element = ref.current;
|
|
@@ -32,16 +28,7 @@ export function useTimelineScroll(contentKey) {
|
|
|
32
28
|
return;
|
|
33
29
|
const previousHeight = heightRef.current;
|
|
34
30
|
heightRef.current = element.scrollHeight;
|
|
35
|
-
|
|
36
|
-
jumpRef.current = undefined;
|
|
37
|
-
if (jump === 'boundary') {
|
|
38
|
-
const marker = element.querySelector('[data-thread-boundary]');
|
|
39
|
-
if (marker !== null) {
|
|
40
|
-
element.scrollTop += marker.getBoundingClientRect().top - element.getBoundingClientRect().top - BOUNDARY_OFFSET_PX;
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (jump === 'latest' || pinnedRef.current) {
|
|
31
|
+
if (pinnedRef.current) {
|
|
45
32
|
element.scrollTop = element.scrollHeight;
|
|
46
33
|
return;
|
|
47
34
|
}
|
|
@@ -50,5 +37,5 @@ export function useTimelineScroll(contentKey) {
|
|
|
50
37
|
element.scrollTop += element.scrollHeight - previousHeight;
|
|
51
38
|
}
|
|
52
39
|
}, [contentKey]);
|
|
53
|
-
return { ref, onScroll, isPinned: () => pinnedRef.current,
|
|
40
|
+
return { ref, onScroll, isPinned: () => pinnedRef.current, scrollToBottom };
|
|
54
41
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { markAgentTeamPreset } from '@wowyuarm/dsh-agent-team/host';
|
|
1
|
+
import { AgentTeamDmDeliveryError, markAgentTeamPreset } from '@wowyuarm/dsh-agent-team/host';
|
|
2
2
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
3
3
|
export const name = 'wowyuarm-agent-team-tools';
|
|
4
4
|
export const inject = ['tools'];
|
|
@@ -136,12 +136,13 @@ function threadResult(kind, snapshot, attention, facts, extra = {}) {
|
|
|
136
136
|
}
|
|
137
137
|
const teamMessage = markAgentTeamPreset(defineTool({
|
|
138
138
|
name: 'team_message',
|
|
139
|
-
description: 'Start a top-level Thread
|
|
139
|
+
description: 'Start a top-level Thread, reply to an existing Thread, or send a direct message (DM). start defaults to a taskless Thread; pass asTask true to create a Task in the same send. Read the Thread first; replies require its current revision (an internal concurrency token carried by baseRevision, never quoted in bodies). A top-level start may mention related Agents directly; in replies, only a Human can invite an unfollowed Agent. Pass Member refs in mentions and spell their handles inside the body; only mentioned Members render as mention chips. dm sends a private direct message to one enabled Agent Member in your Workspace: use it for quick clarifications and status syncs — never for task work, decisions, or anything that needs team visibility or traceability (use a Thread); if a DM exchange with the same Member exceeds about 3 exchanges, move it to a Thread, because every DM costs the recipient a full agent turn.',
|
|
140
140
|
parameters: {
|
|
141
|
-
action: { type: 'string', required: true, enum: ['start', 'reply'] },
|
|
141
|
+
action: { type: 'string', required: true, enum: ['start', 'reply', 'dm'] },
|
|
142
142
|
channelRef: { type: 'string', description: "Full branded Channel ref exactly as returned by Team tools, including the 'channel:' prefix." },
|
|
143
143
|
threadRef: { type: 'string', description: "Full branded Thread ref exactly as returned by Team tools, including the 'thread:' prefix." },
|
|
144
144
|
taskRef: { type: 'string', description: "Optional Task ref alias for reply on a Taskful Thread. Prefer threadRef." },
|
|
145
|
+
memberRef: { type: 'string', description: "Full branded Member ref exactly as returned by Team tools, including the 'member:' prefix. Required for dm; the Member must be an enabled Agent in your Workspace (the Human cannot be DMed)." },
|
|
145
146
|
asTask: { type: 'boolean', description: 'When true, start creates a Task with the Thread. Default false creates a taskless Thread.' },
|
|
146
147
|
body: { type: 'string', required: true, description: "Markdown body. Cite Team refs exactly as returned, as bare text with one colon (e.g. task:0f0a…) — never a double colon, never inside backticks or quotes. Spell each mentioned Member's handle in the prose so the mention renders inline." }, baseRevision: { type: 'number', description: "Positive integer; use the current Thread revision as shown by the latest team_inbox or team_thread result for this Thread. The revision is an internal concurrency token, not a citable fact." },
|
|
147
148
|
mentions: { type: 'array', items: { type: 'string' }, description: 'Member refs to mention. Mentioned Agents receive the Message directly; write their handles in the body (any casing, optional @) so the mention renders inline.' },
|
|
@@ -151,9 +152,11 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
151
152
|
schema: { type: 'object', additionalProperties: false, properties: {
|
|
152
153
|
kind: { type: 'string', required: true }, taskRef: { type: 'string' }, threadRef: { type: 'string' }, revision: { type: 'number' },
|
|
153
154
|
expectedRevision: { type: 'number' }, messageRef: { type: 'string' }, memberIds: { type: 'array', items: { type: 'string' } }, unreadCount: { type: 'number' }, directCount: { type: 'number' },
|
|
155
|
+
recipientMemberId: { type: 'string' }, recipientHandle: { type: 'string' }, delivered: { type: 'boolean' }, deliveryNote: { type: 'string' },
|
|
154
156
|
} },
|
|
155
|
-
render: (_args, value) => [{ type: 'text', text: value.kind === '
|
|
156
|
-
:
|
|
157
|
+
render: (_args, value) => [{ type: 'text', text: value.kind === 'dm-sent' ? `DM ${value.delivered === false ? 'recorded but not delivered' : 'delivered'} to @${value.recipientHandle} (${value.recipientMemberId})${value.deliveryNote === undefined ? '' : `: ${value.deliveryNote}`}`
|
|
158
|
+
: value.kind === 'committed' ? `Message ${value.messageRef} committed at revision ${value.revision}.`
|
|
159
|
+
: `${value.kind}: ${value.memberIds?.join(', ') ?? `${value.threadRef ?? ''}${value.taskRef === undefined ? '' : ` · Task ${value.taskRef}`} revision ${value.revision ?? ''}`}` }],
|
|
157
160
|
},
|
|
158
161
|
async execute(args, exec) {
|
|
159
162
|
const agent = exec.agent;
|
|
@@ -172,6 +175,23 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
172
175
|
channelRef: args.channelRef, body: args.body, asTask: args.asTask === true, ...(mentions === undefined ? {} : { recipients: mentions }), ...paths });
|
|
173
176
|
return messageOutcome(result);
|
|
174
177
|
}
|
|
178
|
+
if (args.action === 'dm') {
|
|
179
|
+
if (args.memberRef === undefined || args.channelRef !== undefined || args.threadRef !== undefined || args.taskRef !== undefined
|
|
180
|
+
|| args.baseRevision !== undefined || args.asTask !== undefined || mentions !== undefined || attachmentPaths !== undefined) {
|
|
181
|
+
throw new Error('dm requires memberRef and body only; it does not accept channelRef, threadRef, taskRef, baseRevision, asTask, mentions, or attachments');
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
const result = await host.dmForAgent(agent, { requestId: requestId(agent.id, exec.callId), workspaceId: current.workspaceId,
|
|
185
|
+
recipientMemberId: args.memberRef, body: args.body });
|
|
186
|
+
return { kind: 'dm-sent', recipientMemberId: result.recipient.memberId, recipientHandle: result.recipient.handle, delivered: true };
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (error instanceof AgentTeamDmDeliveryError) {
|
|
190
|
+
return { kind: 'dm-sent', recipientMemberId: error.recipientMemberId, recipientHandle: error.recipientHandle, delivered: false, deliveryNote: error.message };
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
175
195
|
const baseRevision = args.baseRevision;
|
|
176
196
|
if ((args.threadRef === undefined && args.taskRef === undefined) || args.channelRef !== undefined || args.asTask !== undefined || typeof baseRevision !== 'number' || !Number.isSafeInteger(baseRevision) || baseRevision < 1) {
|
|
177
197
|
throw new Error("reply requires threadRef and a positive baseRevision, and does not accept channelRef; use the current Thread 'revision' returned by team_inbox or team_thread");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAWlD,eAAO,MAAM,IAAI,8BAA8B,CAAA;AAC/C,eAAO,MAAM,MAAM,UAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAWlD,eAAO,MAAM,IAAI,8BAA8B,CAAA;AAC/C,eAAO,MAAM,MAAM,UAAY,CAAA;AAwT/B,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAMxC"}
|