@wowyuarm/dsh-agent-team 0.1.15 → 0.2.1

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 (99) hide show
  1. package/README.md +8 -4
  2. package/README.zh.md +8 -4
  3. package/cordis.patch.yml +26 -12
  4. package/package.json +52 -47
  5. package/packages/agent-team/lib/attachments.js +63 -4
  6. package/packages/agent-team/lib/compaction-engine.js +18 -0
  7. package/packages/agent-team/lib/context-continuity-host.js +198 -4
  8. package/packages/agent-team/lib/context-judge.js +150 -0
  9. package/packages/agent-team/lib/context-source.js +11 -6
  10. package/packages/agent-team/lib/environment-check.js +102 -0
  11. package/packages/agent-team/lib/human-profile.js +23 -37
  12. package/packages/agent-team/lib/index.js +510 -99
  13. package/packages/agent-team/lib/installed-manifest.js +32 -0
  14. package/packages/agent-team/lib/invariant.js +36 -12
  15. package/packages/agent-team/lib/ledger.js +37 -1
  16. package/packages/agent-team/lib/member-context.js +2 -4
  17. package/packages/agent-team/lib/member-runtime.js +2 -1
  18. package/packages/agent-team/lib/member-time-context.js +2 -4
  19. package/packages/agent-team/lib/recovery.js +53 -4
  20. package/packages/agent-team/lib/typert.host.js +225 -54
  21. package/packages/agent-team/lib/typert.remote-client.d.ts +5 -1
  22. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  23. package/packages/agent-team/lib/typert.remote-client.js +127 -39
  24. package/packages/agent-team/lib/types/attachments.d.ts +32 -2
  25. package/packages/agent-team/lib/types/attachments.d.ts.map +1 -1
  26. package/packages/agent-team/lib/types/compaction-engine.d.ts +19 -0
  27. package/packages/agent-team/lib/types/compaction-engine.d.ts.map +1 -0
  28. package/packages/agent-team/lib/types/context-continuity-host.d.ts +131 -4
  29. package/packages/agent-team/lib/types/context-continuity-host.d.ts.map +1 -1
  30. package/packages/agent-team/lib/types/context-judge.d.ts +82 -0
  31. package/packages/agent-team/lib/types/context-judge.d.ts.map +1 -0
  32. package/packages/agent-team/lib/types/context-source.d.ts +7 -4
  33. package/packages/agent-team/lib/types/context-source.d.ts.map +1 -1
  34. package/packages/agent-team/lib/types/environment-check.d.ts +66 -0
  35. package/packages/agent-team/lib/types/environment-check.d.ts.map +1 -0
  36. package/packages/agent-team/lib/types/human-profile.d.ts +21 -27
  37. package/packages/agent-team/lib/types/human-profile.d.ts.map +1 -1
  38. package/packages/agent-team/lib/types/index.d.ts +281 -18
  39. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  40. package/packages/agent-team/lib/types/installed-manifest.d.ts +16 -0
  41. package/packages/agent-team/lib/types/installed-manifest.d.ts.map +1 -0
  42. package/packages/agent-team/lib/types/invariant.d.ts +27 -5
  43. package/packages/agent-team/lib/types/invariant.d.ts.map +1 -1
  44. package/packages/agent-team/lib/types/ledger.d.ts +12 -0
  45. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  46. package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
  47. package/packages/agent-team/lib/types/member-runtime.d.ts +1 -1
  48. package/packages/agent-team/lib/types/member-runtime.d.ts.map +1 -1
  49. package/packages/agent-team/lib/types/member-time-context.d.ts.map +1 -1
  50. package/packages/agent-team/lib/types/recovery.d.ts +19 -6
  51. package/packages/agent-team/lib/types/recovery.d.ts.map +1 -1
  52. package/packages/agent-team/lib/types/types/entities.d.ts +1 -8
  53. package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
  54. package/packages/agent-team/lib/types/types/requests-results.d.ts +94 -2
  55. package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
  56. package/packages/agent-team/lib/types/types.d.ts +9 -0
  57. package/packages/agent-team/lib/types/types.d.ts.map +1 -1
  58. package/packages/client-agent-team/lib/client.js +1264 -383
  59. package/packages/client-agent-team/lib/client.js.map +1 -1
  60. package/packages/client-agent-team/lib/types/client/EnvironmentCheck.d.ts +18 -0
  61. package/packages/client-agent-team/lib/types/client/EnvironmentCheck.d.ts.map +1 -0
  62. package/packages/client-agent-team/lib/types/client/EnvironmentCheck.js +58 -0
  63. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +0 -5
  64. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +1 -1
  65. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
  66. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.js +2 -7
  67. package/packages/client-agent-team/lib/types/client/TeamSettingsSection.d.ts +26 -0
  68. package/packages/client-agent-team/lib/types/client/TeamSettingsSection.d.ts.map +1 -0
  69. package/packages/client-agent-team/lib/types/client/TeamSettingsSection.js +195 -0
  70. package/packages/client-agent-team/lib/types/client/attachment-preview.d.ts +7 -11
  71. package/packages/client-agent-team/lib/types/client/attachment-preview.d.ts.map +1 -1
  72. package/packages/client-agent-team/lib/types/client/attachment-preview.js +13 -3
  73. package/packages/client-agent-team/lib/types/client/context-judge.d.ts +64 -0
  74. package/packages/client-agent-team/lib/types/client/context-judge.d.ts.map +1 -0
  75. package/packages/client-agent-team/lib/types/client/context-judge.js +78 -0
  76. package/packages/client-agent-team/lib/types/client/environment-check.d.ts +65 -0
  77. package/packages/client-agent-team/lib/types/client/environment-check.d.ts.map +1 -0
  78. package/packages/client-agent-team/lib/types/client/environment-check.js +78 -0
  79. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  80. package/packages/client-agent-team/lib/types/client/index.js +84 -11
  81. package/packages/client-agent-team/lib/types/client/judge-form.d.ts +99 -0
  82. package/packages/client-agent-team/lib/types/client/judge-form.d.ts.map +1 -0
  83. package/packages/client-agent-team/lib/types/client/judge-form.js +208 -0
  84. package/packages/client-agent-team/lib/types/client/locales.d.ts +70 -14
  85. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  86. package/packages/client-agent-team/lib/types/client/locales.js +76 -14
  87. package/packages/tool-agent-team/README.md +6 -3
  88. package/packages/tool-agent-team/README.zh.md +6 -3
  89. package/packages/tool-agent-team/lib/context-tools.js +148 -164
  90. package/packages/tool-agent-team/lib/index.js +17 -2
  91. package/packages/tool-agent-team/lib/types/context-tools.d.ts +32 -7
  92. package/packages/tool-agent-team/lib/types/context-tools.d.ts.map +1 -1
  93. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
  94. package/packages/agent-team/lib/pressure-policy.js +0 -230
  95. package/packages/agent-team/lib/types/pressure-policy.d.ts +0 -130
  96. package/packages/agent-team/lib/types/pressure-policy.d.ts.map +0 -1
  97. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.d.ts +0 -15
  98. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.d.ts.map +0 -1
  99. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.js +0 -115
@@ -0,0 +1,32 @@
1
+ /** The installed bundle's own manifest, read once for both facts taken from it. */
2
+ import { readFileSync } from 'node:fs';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ /**
6
+ * Parsed manifest of the installed bundle, or `undefined` when it cannot be
7
+ * read.
8
+ *
9
+ * Three levels up: `packages/agent-team/{src,lib}` sits that deep in both a
10
+ * `link:` checkout and a registry tarball, so a development install and a
11
+ * published one each state their own truth. An unreadable or malformed manifest
12
+ * is a broken install, not a failure of whatever asked: every caller degrades to
13
+ * `'unknown'` or withholds the line it would have stated, so reading this can
14
+ * never fail the Host boot.
15
+ */
16
+ export function readInstalledManifest() {
17
+ try {
18
+ const manifestPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../../package.json');
19
+ const parsed = JSON.parse(readFileSync(manifestPath, 'utf8'));
20
+ return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
21
+ ? parsed
22
+ : undefined;
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ }
28
+ /** Version of the manifest this package installed from, or `'unknown'`. */
29
+ export function bundleVersionOf(manifest) {
30
+ const version = manifest?.version;
31
+ return typeof version === 'string' && version !== '' ? version : 'unknown';
32
+ }
@@ -2,9 +2,39 @@
2
2
  const PACKAGE_NAME = '@wowyuarm/dsh-agent-team';
3
3
  /** Cordis companion plugin name. */
4
4
  export const name = 'agent-team-invariant';
5
- /** Services required before the companion can validate Team state. */
6
- export const inject = ['invariants'];
7
- const install = Object.assign(async (ctx, fail) => {
5
+ /**
6
+ * Services required before the companion can validate Team state. The check
7
+ * is self-hosted in this plugin's own fiber — companions used to register
8
+ * into `@deepseek-ai/dsh-invariants`, which the Harness line after `rc.2`
9
+ * removes wholesale.
10
+ */
11
+ export const inject = ['agentTeam'];
12
+ /**
13
+ * A violated Team ledger invariant, raised on the frame that triggered the
14
+ * check: boot when the mount replay fails, the committing call while a
15
+ * divergence is latched. The Host's post-commit boundary recognizes this class
16
+ * and re-raises it instead of degrading it to a log line.
17
+ */
18
+ export class AgentTeamInvariantError extends Error {
19
+ /** Stable failure code, carried over from the removed upstream error class. */
20
+ code = 'INVARIANT';
21
+ /** Full npm package name that owns the violated invariant. */
22
+ packageName = PACKAGE_NAME;
23
+ /**
24
+ * Construct a Team invariant failure.
25
+ * @param message - violated contract, without the standard error prefix.
26
+ */
27
+ constructor(message) {
28
+ super(`invariant violated by "${PACKAGE_NAME}": ${message}`);
29
+ this.name = 'AgentTeamInvariantError';
30
+ }
31
+ }
32
+ /**
33
+ * Validate Team state at mount and keep validating it after every commit.
34
+ * @param ctx - Cordis context carrying the Agent Team service.
35
+ * @returns nothing; listeners and the pending check ride the plugin fiber.
36
+ */
37
+ export const apply = (ctx) => {
8
38
  const divergence = (error) => `durable ledger and Team projection diverged: ${String(error)}`;
9
39
  // Mounting stays synchronous: a durable ledger that cannot be re-derived
10
40
  // must fail startup instead of racing the first commit. The mount adopts
@@ -15,7 +45,7 @@ const install = Object.assign(async (ctx, fail) => {
15
45
  ctx.agentTeam.validateLedgerAtMount();
16
46
  }
17
47
  catch (error) {
18
- fail(divergence(error));
48
+ throw new AgentTeamInvariantError(divergence(error));
19
49
  }
20
50
  // The commit path cannot pay a full replay before its Remote response
21
51
  // returns, and opening a Thread commits. The replay stays the same full one
@@ -47,12 +77,6 @@ const install = Object.assign(async (ctx, fail) => {
47
77
  if (pending === undefined)
48
78
  pending = setImmediate(check);
49
79
  if (latched !== undefined)
50
- fail(latched);
80
+ throw new AgentTeamInvariantError(latched);
51
81
  });
52
- }, { inject: ['agentTeam'] });
53
- /**
54
- * Register the Agent Team ledger invariant.
55
- * @param ctx - Cordis context carrying the invariant registry.
56
- * @returns the installed registration disposer after setup succeeds.
57
- */
58
- export const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
82
+ };
@@ -1586,6 +1586,7 @@ export class AgentTeamLedger {
1586
1586
  })),
1587
1587
  taskNumbers: Object.freeze(visibleTasks.map(task => Object.freeze({ taskRef: task.taskRef, taskNumber: taskNumbers.get(task.taskRef) ?? 0 }))),
1588
1588
  items: Object.freeze(items),
1589
+ activeTaskThreads: this.activeTaskThreads(visibleTasks, taskNumbers),
1589
1590
  claims: this.claimsForVisibleTasks(visibleTasks),
1590
1591
  activities: Object.freeze(selected.filter((fact) => fact.kind === 'activity').map(fact => fact.activity)),
1591
1592
  cursor: nextCursor,
@@ -3172,6 +3173,40 @@ export class AgentTeamLedger {
3172
3173
  const refs = new Set(tasks.map(task => task.taskRef));
3173
3174
  return Object.freeze([...this.state.claims.values()].filter(claim => refs.has(claim.taskRef)));
3174
3175
  }
3176
+ /**
3177
+ * The team_view「活跃 task thread」radar for a Workspace: every visible Task
3178
+ * still in flight — in_progress or in_review, the two states a live Claim
3179
+ * keeps a Task in — newest activity first. Unlike `recentInboxItems`, this is
3180
+ * not a participation slice: admission is the Task being active in a Channel
3181
+ * the reader can see, whether or not the reader wrote in it, and a Thread
3182
+ * still holding the reader's unread is not excluded. Rows carry the same
3183
+ * `liveClaimOwners`口径 the Inbox and Channel feed already use, so 「谁在这个
3184
+ * Task 上」 never gains a second definition. Archived Channels are already
3185
+ * absent from `visibleTasks`, so their Tasks never reach here.
3186
+ */
3187
+ activeTaskThreads(visibleTasks, taskNumbers) {
3188
+ const rows = [];
3189
+ for (const task of visibleTasks) {
3190
+ if (task.status !== 'in_progress' && task.status !== 'in_review')
3191
+ continue;
3192
+ const thread = this.state.threads.get(task.threadRef);
3193
+ if (thread === undefined)
3194
+ continue;
3195
+ const newest = (this.state.factsByThread.get(thread.threadRef) ?? []).at(-1);
3196
+ if (newest === undefined)
3197
+ continue;
3198
+ const taskNumber = taskNumbers.get(task.taskRef);
3199
+ rows.push({
3200
+ row: Object.freeze({ taskRef: task.taskRef, threadRef: thread.threadRef, channelRef: task.channelRef,
3201
+ ...(taskNumber === undefined ? {} : { taskNumber }), status: task.status,
3202
+ subject: boundedInboxPreview(this.threadAnchor(thread.threadRef).body),
3203
+ members: this.liveClaimOwners(task), lastActivityAt: newest.occurredAt }),
3204
+ sequence: newest.sequence,
3205
+ });
3206
+ }
3207
+ rows.sort((left, right) => right.sequence - left.sequence || left.row.threadRef.localeCompare(right.row.threadRef));
3208
+ return Object.freeze(rows.map(entry => entry.row));
3209
+ }
3175
3210
  tasksForClaims(claims, projected) {
3176
3211
  return Object.freeze([...new Set(claims.map(claim => claim.taskRef))].map(taskRef => {
3177
3212
  const task = this.state.tasks.get(taskRef);
@@ -3745,7 +3780,7 @@ export class AgentTeamLedger {
3745
3780
  if (operation.kind !== 'team/message-sent' || !this.sameActor(operation.actor, request.actor)
3746
3781
  || operation.data.workspaceId !== request.workspaceId || operation.data.message.channelRef !== request.channelRef
3747
3782
  || operation.data.message.body !== request.body.trim() || !this.sameList(operation.data.mentions, recipients)
3748
- || !this.sameList(operation.data.message.attachments?.map(attachment => attachment.attachmentId) ?? [], request.attachments ?? [])
3783
+ || !this.sameList(operation.data.message.attachments?.map(attachment => attachment.attachmentId) ?? [], request.resolvedAttachments?.map(attachment => attachment.attachmentId) ?? [])
3749
3784
  || (request.asTask !== false) !== (operation.data.task !== undefined))
3750
3785
  this.throwRequestCollision(request.requestId);
3751
3786
  }
@@ -3756,6 +3791,7 @@ export class AgentTeamLedger {
3756
3791
  || (request.taskRef !== undefined && operation.data.task?.taskRef !== request.taskRef)
3757
3792
  || (request.threadRef === undefined && request.taskRef === undefined)
3758
3793
  || operation.data.message.body !== request.body.trim() || operation.data.baseRevision !== request.baseRevision
3794
+ || !this.sameList(operation.data.message.attachments?.map(attachment => attachment.attachmentId) ?? [], request.resolvedAttachments?.map(attachment => attachment.attachmentId) ?? [])
3759
3795
  || !this.sameList(operation.data.mentions, recipients))
3760
3796
  this.throwRequestCollision(request.requestId);
3761
3797
  }
@@ -2,7 +2,7 @@ import { readFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import { createUserMessage } from '@deepseek-ai/dsh-llm';
4
4
  import { SessionLogOffset } from '@deepseek-ai/dsh-session';
5
- import { v3RenamedSourceKind } from "./context-source.js";
5
+ import { matchesProducerKind } from "./context-source.js";
6
6
  import { memberMemoryDirectoryPath } from "./member-runtime.js";
7
7
  export const name = 'wowyuarm-agent-team-member-context';
8
8
  const MAX_MEMORY_BYTES = 16 * 1024;
@@ -43,9 +43,7 @@ export function apply(ctx) {
43
43
  // number domains explicit (the seq = log.length contiguity contract).
44
44
  const event = agent.session.snapshotEvents(SessionLogOffset(sequence), SessionLogOffset(sequence + 1))[0];
45
45
  return event?.type === 'user/message'
46
- // Both identities are this producer's own: the kind written now and
47
- // the read-time conversion's rename of this producer's V3 history.
48
- && (event.data.source.kind === name || event.data.source.kind === v3RenamedSourceKind(name))
46
+ && matchesProducerKind(event.data.source.kind, name)
49
47
  && event.data.content[0]?.type === 'text'
50
48
  ? [event.data.content[0].text]
51
49
  : [];
@@ -35,7 +35,8 @@ export const AGENT_TEAM_TOOL_NAMES = Object.freeze([
35
35
  'team_view',
36
36
  'context_rollover',
37
37
  'context_checkpoint',
38
- 'context_timeline',
38
+ 'context_status',
39
+ 'context_compact',
39
40
  ]);
40
41
  /** Copy a Remote-supplied capability overlay into owned frozen storage. */
41
42
  export function deepCopyCapabilities(capabilities) {
@@ -27,7 +27,7 @@
27
27
  * @module @wowyuarm/dsh-agent-team/member-time-context
28
28
  */
29
29
  import { createUserMessage } from '@deepseek-ai/dsh-llm';
30
- import { v3RenamedSourceKind } from "./context-source.js";
30
+ import { matchesProducerKind } from "./context-source.js";
31
31
  import { formatTeamDuration, formatTeamTimestamp } from "./time-format.js";
32
32
  import { advanceOwnedSessionEventCursor } from "./session-event-cursor.js";
33
33
  export const name = 'wowyuarm-agent-team-member-time-context';
@@ -50,9 +50,7 @@ export function applyClockEvent(state, event) {
50
50
  return state.openTurn === -1 ? state : { ...state, lastTurnInjectionTime: null, openTurn: -1 };
51
51
  case 'user/message': {
52
52
  const source = event.data.source;
53
- // Both identities are this producer's own: the kind written now and the
54
- // read-time conversion's rename of this producer's V3 history.
55
- const injected = source.kind === name || source.kind === v3RenamedSourceKind(name);
53
+ const injected = matchesProducerKind(source.kind, name);
56
54
  const withMessage = state.lastMessageTime === event.time ? state : { ...state, lastMessageTime: event.time };
57
55
  if (!injected)
58
56
  return withMessage;
@@ -1,6 +1,55 @@
1
1
  const TRANSIENT_NETWORK_PATTERNS = [/fetch failed/i, /econnreset/i, /etimedout/i, /socket hang up/i];
2
2
  const RATE_LIMIT_PATTERNS = [/\b429\b/, /rate limit/i, /\b503\b/, /overloaded/i];
3
- export function classifyRecoverableError(message) {
3
+ /**
4
+ * Read the stable code/status off any Harness-shaped failure without trusting
5
+ * class identity: a cross-package copy of `dsh-llm` preserves own data but
6
+ * not `instanceof`, so the own fields are the contract.
7
+ */
8
+ function structuredFailure(error) {
9
+ if (typeof error !== 'object' || error === null)
10
+ return {};
11
+ const root = error;
12
+ const failure = typeof root.failure === 'object' && root.failure !== null
13
+ ? root.failure
14
+ : undefined;
15
+ const code = typeof failure?.code === 'string' && failure.code.length > 0 ? failure.code
16
+ : typeof root.code === 'string' && root.code.length > 0 ? root.code : undefined;
17
+ if (code === undefined)
18
+ return {};
19
+ const status = typeof failure?.status === 'number' && Number.isInteger(failure.status) ? failure.status
20
+ : typeof root.status === 'number' && Number.isInteger(root.status) ? root.status : undefined;
21
+ return { code, ...status === undefined ? {} : { status } };
22
+ }
23
+ /** The readable message of an arbitrary thrown value. */
24
+ function failureMessage(error) {
25
+ if (error instanceof Error)
26
+ return error.message;
27
+ if (typeof error === 'object' && error !== null) {
28
+ const message = error.message;
29
+ if (typeof message === 'string' && message.length > 0)
30
+ return message;
31
+ }
32
+ return String(error);
33
+ }
34
+ /**
35
+ * Classify one `agent/error` occurrence. Structured data outranks wording: a
36
+ * Harness code decides alone (a message can never upgrade a terminal failure
37
+ * back to recoverable), and the narrow message signatures run only when no
38
+ * usable code exists at all — `UNKNOWN` means the Harness folded a foreign
39
+ * error whose own taxonomy Team must not trust.
40
+ */
41
+ export function classifyRecoverableError(error) {
42
+ const { code, status } = structuredFailure(error);
43
+ if (code !== undefined && code !== 'UNKNOWN') {
44
+ if (code === 'RATE_LIMIT')
45
+ return 'rate limiting';
46
+ if (code === 'TRANSPORT' || code === 'TIMEOUT')
47
+ return 'transient network';
48
+ if (status === 429 || status === 503)
49
+ return 'rate limiting';
50
+ return undefined;
51
+ }
52
+ const message = failureMessage(error);
4
53
  if (RATE_LIMIT_PATTERNS.some(pattern => pattern.test(message)))
5
54
  return 'rate limiting';
6
55
  if (TRANSIENT_NETWORK_PATTERNS.some(pattern => pattern.test(message)))
@@ -26,9 +75,9 @@ export class RecoveryCoordinator {
26
75
  this.delayMs = options.delayMs ?? RECOVERY_DELAY_MS;
27
76
  this.maxConsecutiveErrors = options.maxConsecutiveErrors ?? RECOVERY_MAX_CONSECUTIVE_ERRORS;
28
77
  }
29
- /** Observe one `agent/error` occurrence for a Member. */
30
- onError(memberId, errorMessage) {
31
- if (classifyRecoverableError(errorMessage) === undefined) {
78
+ /** Observe one `agent/error` occurrence for a Member; `error` is the raw event payload. */
79
+ onError(memberId, error) {
80
+ if (classifyRecoverableError(error) === undefined) {
32
81
  // A non-recoverable failure cancels anything pending: retrying cannot help.
33
82
  this.stopTracking(memberId);
34
83
  return;