@wowyuarm/dsh-agent-team 0.1.14-alpha.2 → 0.1.14

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 (127) hide show
  1. package/README.md +5 -3
  2. package/README.zh.md +5 -3
  3. package/cordis.patch.yml +2 -185
  4. package/package.json +52 -46
  5. package/packages/agent-team/README.md +1 -1
  6. package/packages/agent-team/README.zh.md +1 -1
  7. package/packages/agent-team/core-skills/member-memory-manager/SKILL.md +30 -0
  8. package/packages/agent-team/lib/context-continuity-host.js +91 -0
  9. package/packages/agent-team/lib/context-projection.js +266 -489
  10. package/packages/agent-team/lib/context-source.js +17 -106
  11. package/packages/agent-team/lib/human-avatar.js +61 -0
  12. package/packages/agent-team/lib/human-profile.js +46 -0
  13. package/packages/agent-team/lib/human-update-check.js +119 -0
  14. package/packages/agent-team/lib/index.js +408 -264
  15. package/packages/agent-team/lib/ledger.js +120 -15
  16. package/packages/agent-team/lib/member-context.js +9 -8
  17. package/packages/agent-team/lib/member-runtime.js +1 -1
  18. package/packages/agent-team/lib/member-time-context.js +2 -5
  19. package/packages/agent-team/lib/preset-roster.js +15 -0
  20. package/packages/agent-team/lib/pressure-policy.js +9 -6
  21. package/packages/agent-team/lib/session-remediation.js +493 -0
  22. package/packages/agent-team/lib/stored-session-reader.js +2 -1
  23. package/packages/agent-team/lib/typert.host.js +605 -291
  24. package/packages/agent-team/lib/typert.remote-client.d.ts +15 -6
  25. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  26. package/packages/agent-team/lib/typert.remote-client.js +367 -244
  27. package/packages/agent-team/lib/types/context-continuity-host.d.ts +84 -0
  28. package/packages/agent-team/lib/types/context-continuity-host.d.ts.map +1 -0
  29. package/packages/agent-team/lib/types/context-projection.d.ts +130 -185
  30. package/packages/agent-team/lib/types/context-projection.d.ts.map +1 -1
  31. package/packages/agent-team/lib/types/context-source.d.ts +17 -81
  32. package/packages/agent-team/lib/types/context-source.d.ts.map +1 -1
  33. package/packages/agent-team/lib/types/human-avatar.d.ts +29 -0
  34. package/packages/agent-team/lib/types/human-avatar.d.ts.map +1 -0
  35. package/packages/agent-team/lib/types/human-profile.d.ts +44 -0
  36. package/packages/agent-team/lib/types/human-profile.d.ts.map +1 -0
  37. package/packages/agent-team/lib/types/human-update-check.d.ts +73 -0
  38. package/packages/agent-team/lib/types/human-update-check.d.ts.map +1 -0
  39. package/packages/agent-team/lib/types/index.d.ts +112 -38
  40. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  41. package/packages/agent-team/lib/types/ledger.d.ts +31 -2
  42. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  43. package/packages/agent-team/lib/types/member-context.d.ts +0 -14
  44. package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
  45. package/packages/agent-team/lib/types/member-time-context.d.ts +0 -15
  46. package/packages/agent-team/lib/types/member-time-context.d.ts.map +1 -1
  47. package/packages/agent-team/lib/types/preset-roster.d.ts +5 -0
  48. package/packages/agent-team/lib/types/preset-roster.d.ts.map +1 -0
  49. package/packages/agent-team/lib/types/pressure-policy.d.ts +6 -0
  50. package/packages/agent-team/lib/types/pressure-policy.d.ts.map +1 -1
  51. package/packages/agent-team/lib/types/session-remediation.d.ts +172 -0
  52. package/packages/agent-team/lib/types/session-remediation.d.ts.map +1 -0
  53. package/packages/agent-team/lib/types/stored-session-reader.d.ts +2 -1
  54. package/packages/agent-team/lib/types/stored-session-reader.d.ts.map +1 -1
  55. package/packages/agent-team/lib/types/types/entities.d.ts +20 -3
  56. package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
  57. package/packages/agent-team/lib/types/types/requests-results.d.ts +63 -0
  58. package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
  59. package/packages/agent-team/preset/team-member/agent.cordis.yml +166 -0
  60. package/packages/client-agent-team/lib/client.js +1667 -516
  61. package/packages/client-agent-team/lib/client.js.map +1 -1
  62. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.d.ts +15 -0
  63. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.d.ts.map +1 -0
  64. package/packages/client-agent-team/lib/types/client/HumanSettingsSection.js +115 -0
  65. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
  66. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +12 -8
  67. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts +22 -1
  68. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts.map +1 -1
  69. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.js +25 -2
  70. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts +6 -1
  71. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
  72. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +69 -31
  73. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +4 -4
  74. package/packages/client-agent-team/lib/types/client/TeamComposer.js +3 -3
  75. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
  76. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
  77. package/packages/client-agent-team/lib/types/client/TeamConversation.js +12 -5
  78. package/packages/client-agent-team/lib/types/client/TeamFooterAction.js +2 -2
  79. package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts +4 -1
  80. package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts.map +1 -1
  81. package/packages/client-agent-team/lib/types/client/TeamInboxPage.js +22 -7
  82. package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts +11 -1
  83. package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -1
  84. package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +69 -8
  85. package/packages/client-agent-team/lib/types/client/TeamMembersAction.js +2 -2
  86. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +18 -3
  87. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
  88. package/packages/client-agent-team/lib/types/client/TeamMessage.js +213 -67
  89. package/packages/client-agent-team/lib/types/client/TeamRowMenu.d.ts.map +1 -1
  90. package/packages/client-agent-team/lib/types/client/TeamRowMenu.js +2 -2
  91. package/packages/client-agent-team/lib/types/client/TeamSidebarSection.js +2 -2
  92. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +5 -0
  93. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
  94. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +55 -29
  95. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +3 -3
  96. package/packages/client-agent-team/lib/types/client/TeamWorkspaceSelector.js +2 -2
  97. package/packages/client-agent-team/lib/types/client/avatar-image.d.ts +21 -0
  98. package/packages/client-agent-team/lib/types/client/avatar-image.d.ts.map +1 -0
  99. package/packages/client-agent-team/lib/types/client/avatar-image.js +9 -0
  100. package/packages/client-agent-team/lib/types/client/human-identity.d.ts +94 -0
  101. package/packages/client-agent-team/lib/types/client/human-identity.d.ts.map +1 -0
  102. package/packages/client-agent-team/lib/types/client/human-identity.js +117 -0
  103. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  104. package/packages/client-agent-team/lib/types/client/index.js +112 -41
  105. package/packages/client-agent-team/lib/types/client/locales.d.ts +72 -2
  106. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  107. package/packages/client-agent-team/lib/types/client/locales.js +78 -2
  108. package/packages/client-agent-team/lib/types/client/multi-menu-field.js +2 -2
  109. package/packages/client-agent-team/lib/types/client/refs.d.ts +71 -0
  110. package/packages/client-agent-team/lib/types/client/refs.d.ts.map +1 -0
  111. package/packages/client-agent-team/lib/types/client/refs.js +181 -0
  112. package/packages/client-agent-team/lib/types/client/slots.d.ts +8 -2
  113. package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
  114. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +57 -9
  115. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
  116. package/packages/client-agent-team/lib/types/client/team-formatters.js +85 -17
  117. package/packages/tool-agent-team/README.md +1 -1
  118. package/packages/tool-agent-team/README.zh.md +1 -1
  119. package/packages/tool-agent-team/lib/context-tools.js +20 -6
  120. package/packages/tool-agent-team/lib/index.js +2 -2
  121. package/packages/tool-agent-team/lib/types/context-tools.d.ts.map +1 -1
  122. package/packages/agent-team/lib/context-management.js +0 -371
  123. package/packages/agent-team/lib/types/context-management.d.ts +0 -154
  124. package/packages/agent-team/lib/types/context-management.d.ts.map +0 -1
  125. package/packages/client-agent-team/lib/types/client/task-refs.d.ts +0 -31
  126. package/packages/client-agent-team/lib/types/client/task-refs.d.ts.map +0 -1
  127. package/packages/client-agent-team/lib/types/client/task-refs.js +0 -99
@@ -8,10 +8,22 @@
8
8
  * order before the turn closes.
9
9
  * @module @wowyuarm/dsh-agent-team/context-tools
10
10
  */
11
+ import { createHash } from 'node:crypto';
11
12
  import { defineTool } from '@deepseek-ai/dsh-tools';
12
13
  import { member, service } from "./host-access.js";
13
14
  const MAX_HANDOFF_CHARS = 32 * 1024;
14
15
  const MAX_RELATED_FILES = 32;
16
+ /**
17
+ * Short stable identifier for one timeline row: a digest of the anchor's own
18
+ * ref. Rows routinely share a label (`Team message` is a constant) and a price
19
+ * (the same completed turn prices both), so without it two distinct anchors
20
+ * read as one duplicated row. Deliberately NOT the ref and deliberately not
21
+ * actionable: a ref only means something on a restorable row, which prints it
22
+ * in full for `context_rollover`.
23
+ */
24
+ function anchorId(checkpointRef) {
25
+ return createHash('sha256').update(checkpointRef).digest('hex').slice(0, 6);
26
+ }
15
27
  const contextRollover = defineTool({
16
28
  name: 'context_rollover',
17
29
  description: 'context_rollover: end this context generation and continue as the same Team Member in a new one. Without checkpointRef the context starts fresh and empty, seeded only by your handoff — this is the default, cheapest path at context pressure, and the right choice for ordinary generation changes and pressure-driven handoffs. Omit checkpointRef unless you are deliberately returning to a restorable anchor you just selected from a context_timeline result: supply a checkpointRef only when that timeline listed it as restorable and you are citing its exact ref — never synthesize, guess, or reconstruct one; a fabricated ref rejects as a model-visible error. Write the handoff as one prose string covering: current objective and every active Thread/Claim; verified facts and evidence; inferences and unresolved conflicts; current external side effects and their verification state (files, git, jobs, browser state, remote calls); one explicit next step. A context change never rolls back any external effect — describe current state so the next generation can re-verify. Record anything worth keeping in your private memory/notes first. Collect or stop your background jobs before calling: a rollover is refused while jobs this Member owns are still running.',
@@ -108,7 +120,7 @@ const contextCheckpoint = defineTool({
108
120
  });
109
121
  const contextTimeline = defineTool({
110
122
  name: 'context_timeline',
111
- description: 'Inspect the bounded structural timeline of this Member\'s context lineage: named checkpoints you recorded, Team boundaries (effect anchors: a committed team_message, a successful team_claim mutation, a follow/unfollow — rendered as `Team message`, `Team task claim change`, `Team attention change`; plus a Thread\'s first delivered notice, rendered as `First arrival: <refs>`), handoff and compaction boundaries, and the current head — across the current generation and its archived ancestors. Only the first delivery of a Thread\'s facts anchors; later re-deliveries and reminders produce no boundary. Returns approximate retained/discarded token estimates, current usage against the pressure budget, the Threads whose facts entered your context by each anchor, and which anchors are restorable. A Team boundary is a selectable default checkpoint exactly when it resolved at a completed turn and exactly one Thread is attributable to it; unattributable or multi-Thread boundaries state their reason. Structural only: no transcript content. A fresh context_rollover (no checkpointRef) never requires consulting this timeline first — call it directly. Use this tool only when you specifically intend a checkpointRef return: to pick the smallest sufficient ref, or to confirm that a fresh handoff is the better path when every anchor is marked non-restorable.',
123
+ description: 'Inspect the bounded structural timeline of this Member\'s context lineage: named checkpoints you recorded, Team boundaries (effect anchors: a committed team_message, a successful team_claim mutation, a follow/unfollow — rendered as `Team message`, `Team task claim change`, `Team attention change`; plus a Thread\'s first delivered notice, rendered as `First arrival: <refs>`), handoff and compaction boundaries, and the current head — across the current generation and its archived ancestors. Only the first delivery of a Thread\'s facts anchors; later re-deliveries and reminders produce no boundary. Returns approximate retained/discarded token estimates, current usage against the pressure budget, the Threads whose facts entered your context by each anchor, and which anchors are restorable. A Team boundary is a selectable default checkpoint exactly when the retained prefix through it stays inside one Thread and the return would shrink the working set below the handoff budget; a boundary spanning several Threads, or attributable to none, states its reason instead. Every row carries a short `anchor` id: it distinguishes rows that share a label and a price, and it is NOT a ref — only the `checkpointRef` printed on a restorable row may be cited to context_rollover. Structural only: no transcript content. A fresh context_rollover (no checkpointRef) never requires consulting this timeline first — call it directly. Use this tool only when you specifically intend a checkpointRef return: to pick the smallest sufficient ref, or to confirm that a fresh handoff is the better path when every anchor is marked non-restorable.',
112
124
  parameters: {
113
125
  limit: { type: 'number', description: 'Maximum number of items to return (default 12, at most 24).' },
114
126
  },
@@ -137,10 +149,12 @@ const contextTimeline = defineTool({
137
149
  // ref, label, source, size estimates, affected Threads, and
138
150
  // restorable/reason verdict, the model cannot pick a `checkpointRef` for
139
151
  // `context_rollover` — the summary line alone left the tool unusable for
140
- // seeded returns. The Host bounds items (default 12, at most 24), so this
141
- // list cannot grow unbounded. `incompleteFrom` states where and why the
142
- // lineage walk stopped early, so history read up to that ancestor is
143
- // known to be a truncation, not everything that exists.
152
+ // seeded returns. The short anchor id distinguishes rows that share a
153
+ // label and a price without ever printing a ref that is not usable. The
154
+ // Host bounds items (default 12, at most 24), so the list cannot grow
155
+ // unbounded. `incompleteFrom` states where and why the lineage walk
156
+ // stopped early, so history read up to that ancestor is known to be a
157
+ // truncation, not everything that exists.
144
158
  render: (_args, value) => {
145
159
  const lines = [`Context timeline: ${value.usageTokens} tokens used (handoff at ${value.handoffAt}, hard limit ${value.hardLimit}). ${value.items.length} item(s):`];
146
160
  for (const item of value.items) {
@@ -149,7 +163,7 @@ const contextTimeline = defineTool({
149
163
  const restorable = item.restorable
150
164
  ? `restorable — ref: ${item.checkpointRef}`
151
165
  : `not restorable — ${item.reason ?? 'no reason given'}`;
152
- lines.push(`- ${item.name} [source: ${item.source}] (${size}; ${threads}) — ${restorable}`);
166
+ lines.push(`- ${item.name} [source: ${item.source}; anchor ${anchorId(item.checkpointRef)}] (${size}; ${threads}) — ${restorable}`);
153
167
  }
154
168
  if (value.incompleteFrom !== undefined) {
155
169
  lines.push(`History incomplete: the lineage walk stopped at Session ${value.incompleteFrom.sessionId} (${value.incompleteFrom.reason}); ancestors before it could not be read and are not reflected above.`);
@@ -1,4 +1,4 @@
1
- import { AGENT_TEAM_HUMAN_HANDLE, AgentTeamDmDeliveryError, markAgentTeamPreset } from '@wowyuarm/dsh-agent-team/host';
1
+ import { AgentTeamDmDeliveryError, markAgentTeamPreset } from '@wowyuarm/dsh-agent-team/host';
2
2
  import { formatTeamTimestamp } from '@wowyuarm/dsh-agent-team/time-format';
3
3
  import { registerContextTools } from "./context-tools.js";
4
4
  import { service, workspaceOf, workspaceParam } from "./host-access.js";
@@ -626,7 +626,7 @@ const teamView = defineTool({
626
626
  ...(participation.title === undefined ? {} : { title: participation.title }), default: participation.default })),
627
627
  channels: view.channels.map(channel => ({ channelRef: channel.channelRef, name: channel.name })),
628
628
  members: [
629
- { memberId: view.humanMemberId, kind: 'human', handle: AGENT_TEAM_HUMAN_HANDLE, description: 'Human Team Member', presence: 'available' },
629
+ { memberId: view.humanMemberId, kind: 'human', handle: host.humanHandle(), description: 'Human Team Member', presence: 'available' },
630
630
  ...host.members().filter(status => visibleMemberIds.has(status.member.memberId)).map(status => ({ memberId: status.member.memberId,
631
631
  kind: 'agent', handle: status.member.handle, description: status.member.description, presence: status.presence })),
632
632
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"context-tools.d.ts","sourceRoot":"","sources":["../../src/context-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuKH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,CAIrG"}
1
+ {"version":3,"file":"context-tools.d.ts","sourceRoot":"","sources":["../../src/context-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsLH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,CAIrG"}
@@ -1,371 +0,0 @@
1
- /**
2
- * Context-management coordinator: the one deep module that turns a Member's
3
- * successful `context_rollover` tool result into its next private context
4
- * generation.
5
- *
6
- * Authority split (see docs/architecture.md):
7
- * - the Team ledger owns the Member→Session binding and rollover audit;
8
- * - the Session log projection owns intent, checkpoints, and delivery state;
9
- * - this coordinator owns only process locks and is always reconstructible.
10
- *
11
- * The coordinator reacts exclusively after the successful `tool/result` is
12
- * durably appended — never inside a tool body — so a render/finalize failure
13
- * can never outrun result durability. The actual swap waits for the
14
- * containing turn to end and the Agent to be idle, captures later input so no
15
- * old-generation model request opens, and then reuses the Member lifecycle:
16
- * commit rollover operation → dispose old Agent → archive old Session →
17
- * create/activate the new generation → deliver the handoff first.
18
- * @module @wowyuarm/dsh-agent-team/context-management
19
- */
20
- import { SessionId as SessionIdBrand } from '@deepseek-ai/dsh-session';
21
- import { createHash } from 'node:crypto';
22
- import { createCheckpointContinuationMessage, createHandoffMessage, isAgentTeamContextSource, isAgentTeamSource } from "./context-source.js";
23
- import { CONTEXT_CHECKPOINT_TOOL_NAME, CONTEXT_ROLLOVER_TOOL_NAME, continuationDelivered, foldContextProjection, } from "./context-projection.js";
24
- /** Stable summary of the one-shot rollover pressure notice (ticket 03 wires delivery). */
25
- export const CONTEXT_PRESSURE_NOTICE_SUMMARY = 'Context pressure: prepare a handoff';
26
- /**
27
- * Rebuild one Member's in-process intent from the projection's pending
28
- * rollover. Three call sites consume it — the live result, crash recovery
29
- * with the turn still open, and crash recovery past the turn end — and they
30
- * must agree field for field; this is the single definition of that list.
31
- */
32
- function intentFromPending(pending) {
33
- return {
34
- toolCallId: pending.toolCallId,
35
- resultSeq: pending.resultSeq,
36
- turn: pending.turn,
37
- handoff: pending.handoff,
38
- ...(pending.checkpointRef === undefined ? {} : { checkpointRef: pending.checkpointRef }),
39
- relatedFiles: pending.relatedFiles,
40
- };
41
- }
42
- export class ContextManagementCoordinator {
43
- options;
44
- members = new Map();
45
- capturedInput = new Map();
46
- /** Per-member latch for the in-process scheduling→delivery window. */
47
- scheduledContinuations = new Set();
48
- disposed = false;
49
- constructor(options) {
50
- this.options = options;
51
- }
52
- /** Whether one Member has a pending or in-flight rollover; tools use this to reject. */
53
- isTransitioning(memberId) {
54
- return this.members.has(memberId);
55
- }
56
- /**
57
- * Root `session/event` observer for Member Sessions. The store's dispatch
58
- * carrier is untagged, so the Host maps session ids to Members and calls
59
- * this for every Member event. All reactions are gated on the projection
60
- * state, which itself only records successful durable pairs.
61
- */
62
- onSessionEvent(memberId, agent, event) {
63
- if (this.disposed)
64
- return;
65
- if (event.type === 'tool/result') {
66
- this.onToolResult(memberId, agent, event);
67
- return;
68
- }
69
- if (event.type === 'user/message') {
70
- this.onUserMessage(memberId, agent, event);
71
- return;
72
- }
73
- if (event.type === 'turn/end') {
74
- this.onTurnEnd(memberId, agent);
75
- }
76
- }
77
- /** Build the first handoff message of one generation; the lifecycle delivers it. */
78
- handoffMessageFor(plan) {
79
- return createHandoffMessage({
80
- handoff: plan.handoff,
81
- previousSessionId: plan.previousSessionId,
82
- newSessionId: plan.newSessionId,
83
- trigger: plan.trigger,
84
- handoffEventSeq: plan.handoffEventSeq,
85
- ...(plan.checkpointRef === undefined ? {} : { checkpointRef: plan.checkpointRef }),
86
- ...(plan.relatedFiles.length === 0 ? {} : { relatedFiles: plan.relatedFiles }),
87
- });
88
- }
89
- /**
90
- * Whether one Agent's pending transition requires the admission gate: a
91
- * pending rollover must stop old-generation turns from admitting queued
92
- * input. The gate arms only for the old-generation Agent instance — the
93
- * new generation activates mid-swap and must be free to consume the
94
- * handoff and carried input immediately.
95
- */
96
- needsAdmissionGate(agent) {
97
- const memberId = this.options.memberForAgent(agent)?.memberId;
98
- if (memberId === undefined)
99
- return false;
100
- return this.members.get(memberId)?.agent === agent;
101
- }
102
- /**
103
- * Capture the inbox messages queued for an old generation at its turn-stop
104
- * boundary: non-Team input is preserved verbatim for delivery after the
105
- * handoff; stale Team notices are dropped because the new generation
106
- * rederives the Inbox from ledger facts. Removing them from the inbox lets
107
- * the turn close cleanly instead of admitting another old-generation step.
108
- */
109
- captureQueuedInput(agent) {
110
- const memberId = this.options.memberForAgent(agent)?.memberId;
111
- if (memberId === undefined)
112
- return [];
113
- if (this.members.get(memberId)?.agent !== agent)
114
- return [];
115
- const removed = [...agent.inbox.nextStep, ...agent.inbox.nextTurn];
116
- for (const message of removed)
117
- agent.inbox.remove(message.id);
118
- return this.captureInput(agent, removed);
119
- }
120
- /**
121
- * Capture messages a racing pre-step already claimed from the inbox before
122
- * rejecting that old-generation step. A rejected step's claimed message is
123
- * otherwise neither discarded nor re-emitted, so the gate preserves it here.
124
- */
125
- captureClaimedInput(agent, messages) {
126
- return this.captureInput(agent, messages);
127
- }
128
- captureInput(agent, messages) {
129
- const memberId = this.options.memberForAgent(agent)?.memberId;
130
- if (memberId === undefined)
131
- return [];
132
- if (this.members.get(memberId)?.agent !== agent)
133
- return [];
134
- const preserved = [];
135
- for (const message of messages) {
136
- if (this.isTeamNotice(message))
137
- continue;
138
- preserved.push(message);
139
- }
140
- if (preserved.length > 0)
141
- this.capturedInput.set(memberId, [...(this.capturedInput.get(memberId) ?? []), ...preserved]);
142
- return preserved;
143
- }
144
- /** Drain the captured input of one Member for delivery after the handoff. */
145
- drainCapturedInput(memberId) {
146
- const captured = this.capturedInput.get(memberId) ?? [];
147
- this.capturedInput.delete(memberId);
148
- return captured;
149
- }
150
- /**
151
- * Whether one queued message is a Team-owned notice the rederived Inbox
152
- * replaces. Handoff and continuation envelopes carry the same plugin
153
- * attribution but are ordinary delivered context the new generation keeps, so
154
- * they are excluded rather than dropped.
155
- */
156
- isTeamNotice(message) {
157
- return isAgentTeamSource(message.source) && !isAgentTeamContextSource(message);
158
- }
159
- /** Drop one Member's bookkeeping; the Host calls this on dispose/removal. */
160
- stopTracking(memberId) {
161
- this.members.delete(memberId);
162
- this.capturedInput.delete(memberId);
163
- }
164
- dispose() {
165
- this.disposed = true;
166
- this.members.clear();
167
- this.capturedInput.clear();
168
- }
169
- onToolResult(memberId, agent, event) {
170
- if (event.data.error !== undefined)
171
- return;
172
- const member = this.options.memberForAgent(agent);
173
- if (member === undefined)
174
- return;
175
- const state = this.options.projectionForMember(memberId, member.sessionId);
176
- if (state?.pending === null || state === undefined)
177
- return;
178
- const pending = state.pending;
179
- // React only to the intent's own result landing durably, and only once.
180
- if (pending.resultSeq !== event.seq)
181
- return;
182
- if (this.members.has(memberId))
183
- return;
184
- this.members.set(memberId, { agent, intent: intentFromPending(pending), turnEnded: false });
185
- }
186
- onUserMessage(memberId, _agent, event) {
187
- // Quiet-continuation delivery bookkeeping is projection-owned; the
188
- // coordinator only repairs a crash gap after restart, which the Host
189
- // performs through repairContinuations during activation.
190
- void memberId;
191
- void event;
192
- }
193
- onTurnEnd(memberId, agent) {
194
- // Checkpoint continuations first: a turn that resolved checkpoints owes
195
- // each of them exactly one quiet next-turn follow-up. The projection's
196
- // continuations state deduplicates across restarts; this in-memory latch
197
- // closes the same-process window between scheduling and the delivery
198
- // event landing in the log.
199
- this.scheduleCheckpointContinuations(memberId, agent);
200
- const transition = this.members.get(memberId);
201
- if (transition === undefined || transition.turnEnded)
202
- return;
203
- const member = this.options.memberForAgent(agent);
204
- if (member === undefined || transition.agent !== agent)
205
- return;
206
- transition.turnEnded = true;
207
- // Wait for true idle (the turn-end event fires before the driver fully
208
- // converges), then perform the swap off the session-event dispatch path.
209
- void agent.whenIdle().then(() => {
210
- if (this.disposed)
211
- return;
212
- const current = this.members.get(memberId);
213
- if (current === undefined || current !== transition)
214
- return;
215
- if (this.options.agentForMember(memberId) !== agent)
216
- return;
217
- void this.performTransition(memberId, member, transition);
218
- }, error => {
219
- this.options.log(`context rollover idle wait failed: ${error instanceof Error ? error.message : String(error)} (member ${memberId})`);
220
- this.members.delete(memberId);
221
- });
222
- }
223
- /**
224
- * Claim the in-process latch for one resolved checkpoint continuation.
225
- * Returns the latch key when this caller won it, or undefined when the
226
- * checkpoint never concluded a turn, was already delivered durably, or is
227
- * latched already. The caller releases the latch on its own failure path.
228
- */
229
- claimContinuationLatch(memberId, state, checkpoint) {
230
- if (checkpoint.turnEndSeq === -1)
231
- return undefined;
232
- if (continuationDelivered(state, checkpoint.checkpointRef))
233
- return undefined;
234
- const latch = `${memberId}:${checkpoint.checkpointRef}`;
235
- if (this.scheduledContinuations.has(latch))
236
- return undefined;
237
- this.scheduledContinuations.add(latch);
238
- return latch;
239
- }
240
- /**
241
- * Quiet follow-ups for checkpoints resolved by the turn that just ended.
242
- * A successful `context_checkpoint` result concludes its turn; the Host
243
- * continues work in the next turn with one host-generated notice. The
244
- * projection folds delivery (the continuation user/message event), so a
245
- * restart repairs a missing follow-up through repairContinuations without
246
- * duplicating a delivered one; this live path latches per checkpoint in
247
- * memory for the scheduling window.
248
- */
249
- scheduleCheckpointContinuations(memberId, agent) {
250
- const member = this.options.memberForAgent(agent);
251
- if (member === undefined)
252
- return;
253
- const state = this.options.projectionForMember(memberId, member.sessionId);
254
- if (state === undefined)
255
- return;
256
- for (const checkpoint of state.checkpoints) {
257
- const latch = this.claimContinuationLatch(memberId, state, checkpoint);
258
- if (latch === undefined)
259
- continue;
260
- // The turn/end observer fires inside the session append publication
261
- // (a synchronous followup would reenter the publishing append), and a
262
- // next-turn message queued while the driver is still converging never
263
- // latches a wake — the loop replays only maintenance/abort latches. So
264
- // the continuation waits for true idle, then queues its own turn: the
265
- // same discipline the rollover path uses.
266
- void agent.whenIdle().then(() => {
267
- if (this.disposed)
268
- return;
269
- try {
270
- agent.followup(createCheckpointContinuationMessage(checkpoint.checkpointRef));
271
- }
272
- catch (error) {
273
- this.scheduledContinuations.delete(latch);
274
- this.options.log(`context continuation scheduling failed: ${error instanceof Error ? error.message : String(error)} (member ${memberId})`);
275
- }
276
- }, () => {
277
- this.scheduledContinuations.delete(latch);
278
- });
279
- }
280
- }
281
- async performTransition(memberId, member, transition) {
282
- // Stable rollover identity derives from the previous Session and the
283
- // successful tool call: a result seq is session-local and would collide
284
- // across generations. Both inputs are unconstrained strings (provider
285
- // call ids carry arbitrary lengths and characters; Session ids are
286
- // caller-branded), so the pair is JSON-encoded — no delimiter can alias
287
- // across the two fields — and hashed to a fixed-length url-safe hex
288
- // digest instead of being embedded verbatim: the derived Session id and
289
- // request id stay bounded and collision-resistant.
290
- const stableKey = createHash('sha256').update(JSON.stringify([member.sessionId, transition.intent.toolCallId])).digest('hex');
291
- const newSessionId = SessionIdBrand(`agent-team-rollover-${stableKey}`);
292
- const plan = {
293
- previousSessionId: member.sessionId,
294
- newSessionId,
295
- handoff: transition.intent.handoff,
296
- handoffEventSeq: transition.intent.resultSeq,
297
- trigger: 'model',
298
- relatedFiles: transition.intent.relatedFiles,
299
- ...(transition.intent.checkpointRef === undefined ? {} : { checkpointRef: transition.intent.checkpointRef }),
300
- requestId: `agent-team:rollover:${stableKey}`,
301
- carriedInput: this.drainCapturedInput(memberId),
302
- };
303
- const swap = this.options.executeTransition(memberId, plan);
304
- transition.swapping = swap;
305
- try {
306
- await swap;
307
- this.members.delete(memberId);
308
- }
309
- catch (error) {
310
- this.options.log(`context rollover failed, leaving the previous generation recoverable: ${error instanceof Error ? error.message : String(error)} (member ${memberId})`);
311
- this.members.delete(memberId);
312
- }
313
- }
314
- /**
315
- * Crash-recovery hook the Host runs during Member activation: re-derive
316
- * pending intent from the projection and finish a transition that a restart
317
- * interrupted after the successful result was durable.
318
- */
319
- recoverPendingTransition(memberId, agent, sessionId) {
320
- if (this.disposed || this.members.has(memberId))
321
- return;
322
- const state = this.options.projectionForMember(memberId, sessionId);
323
- if (state?.pending === null || state === undefined)
324
- return;
325
- const pending = state.pending;
326
- if (pending.turnEndSeq === -1) {
327
- // The containing turn never ended durably; treat the intent as still
328
- // waiting and observe the live events from here.
329
- this.members.set(memberId, { agent, intent: intentFromPending(pending), turnEnded: false });
330
- return;
331
- }
332
- // The turn already ended before the crash; the Agent is idle at
333
- // activation, so the swap can proceed directly.
334
- const member = this.options.memberForAgent(agent);
335
- if (member === undefined)
336
- return;
337
- const transition = { agent, intent: intentFromPending(pending), turnEnded: true };
338
- this.members.set(memberId, transition);
339
- void this.performTransition(memberId, member, transition);
340
- }
341
- /**
342
- * Crash-recovery for quiet continuations: schedule the follow-up for one
343
- * resolved checkpoint exactly once when the result was durable but the
344
- * delivery never landed. The projection's continuations state is the
345
- * durable delivery record — a checkpoint whose delivery event exists in the
346
- * log is never re-scheduled.
347
- */
348
- repairContinuations(agent, state) {
349
- if (this.disposed)
350
- return;
351
- const memberId = this.options.memberForAgent(agent)?.memberId;
352
- if (memberId === undefined)
353
- return;
354
- for (const checkpoint of state.checkpoints) {
355
- const latch = this.claimContinuationLatch(memberId, state, checkpoint);
356
- if (latch === undefined)
357
- continue;
358
- try {
359
- agent.followup(createCheckpointContinuationMessage(checkpoint.checkpointRef));
360
- }
361
- catch (error) {
362
- this.scheduledContinuations.delete(latch);
363
- this.options.log(`context continuation repair failed: ${error instanceof Error ? error.message : String(error)}`);
364
- }
365
- }
366
- }
367
- }
368
- /** Tool names this module owns; the preset validation requires all of them. */
369
- export const CONTEXT_TOOL_NAMES = Object.freeze([CONTEXT_CHECKPOINT_TOOL_NAME, CONTEXT_ROLLOVER_TOOL_NAME, 'context_timeline']);
370
- /** Re-exported for Host wiring: cold-fold helper for archived ancestors. */
371
- export { foldContextProjection };
@@ -1,154 +0,0 @@
1
- /**
2
- * Context-management coordinator: the one deep module that turns a Member's
3
- * successful `context_rollover` tool result into its next private context
4
- * generation.
5
- *
6
- * Authority split (see docs/architecture.md):
7
- * - the Team ledger owns the Member→Session binding and rollover audit;
8
- * - the Session log projection owns intent, checkpoints, and delivery state;
9
- * - this coordinator owns only process locks and is always reconstructible.
10
- *
11
- * The coordinator reacts exclusively after the successful `tool/result` is
12
- * durably appended — never inside a tool body — so a render/finalize failure
13
- * can never outrun result durability. The actual swap waits for the
14
- * containing turn to end and the Agent to be idle, captures later input so no
15
- * old-generation model request opens, and then reuses the Member lifecycle:
16
- * commit rollover operation → dispose old Agent → archive old Session →
17
- * create/activate the new generation → deliver the handoff first.
18
- * @module @wowyuarm/dsh-agent-team/context-management
19
- */
20
- import type { Agent } from '@deepseek-ai/dsh-agent';
21
- import type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session';
22
- import type { UserMessage } from '@deepseek-ai/dsh-llm';
23
- import { foldContextProjection, type AgentTeamContextProjectionState } from './context-projection.ts';
24
- import type { AgentTeamAgentMember, AgentTeamMemberId, AgentTeamRolloverSessionRequest } from './types.ts';
25
- /** Stable summary of the one-shot rollover pressure notice (ticket 03 wires delivery). */
26
- export declare const CONTEXT_PRESSURE_NOTICE_SUMMARY = "Context pressure: prepare a handoff";
27
- export interface ContextManagementCoordinatorOptions {
28
- /** Resolve the live Agent of one Member; undefined leaves intent parked. */
29
- readonly agentForMember: (memberId: AgentTeamMemberId) => Agent | undefined;
30
- /** Resolve the durable Member of one live Agent. */
31
- readonly memberForAgent: (agent: Agent) => AgentTeamAgentMember | undefined;
32
- /** Fold one Member Session's projection state from its durable events. */
33
- readonly projectionForMember: (memberId: AgentTeamMemberId, sessionId: SessionId) => AgentTeamContextProjectionState | undefined;
34
- /**
35
- * Execute one prepared Member generation swap at a true idle boundary:
36
- * commit, dispose, archive, create/activate, deliver the handoff first,
37
- * then carried input and the rederived Inbox. Returns once the Member runs
38
- * its new generation.
39
- */
40
- readonly executeTransition: (memberId: AgentTeamMemberId, plan: TransitionPlan) => Promise<void>;
41
- /** Log one coordinator diagnostic. */
42
- readonly log: (message: string) => void;
43
- }
44
- /** Everything the lifecycle needs to perform one rollover. */
45
- export interface TransitionPlan {
46
- readonly previousSessionId: SessionId;
47
- readonly newSessionId: SessionId;
48
- readonly handoff: string;
49
- readonly handoffEventSeq: number;
50
- readonly trigger: 'model' | 'pressure';
51
- readonly relatedFiles: readonly {
52
- readonly path: string;
53
- readonly reason: string;
54
- }[];
55
- readonly checkpointRef?: string | undefined;
56
- readonly requestId: AgentTeamRolloverSessionRequest['requestId'];
57
- /** Non-Team input that arrived during the transition, delivered after the handoff. */
58
- readonly carriedInput: readonly UserMessage[];
59
- }
60
- export declare class ContextManagementCoordinator {
61
- private readonly options;
62
- private readonly members;
63
- private readonly capturedInput;
64
- /** Per-member latch for the in-process scheduling→delivery window. */
65
- private readonly scheduledContinuations;
66
- private disposed;
67
- constructor(options: ContextManagementCoordinatorOptions);
68
- /** Whether one Member has a pending or in-flight rollover; tools use this to reject. */
69
- isTransitioning(memberId: AgentTeamMemberId): boolean;
70
- /**
71
- * Root `session/event` observer for Member Sessions. The store's dispatch
72
- * carrier is untagged, so the Host maps session ids to Members and calls
73
- * this for every Member event. All reactions are gated on the projection
74
- * state, which itself only records successful durable pairs.
75
- */
76
- onSessionEvent(memberId: AgentTeamMemberId, agent: Agent, event: SessionEvent): void;
77
- /** Build the first handoff message of one generation; the lifecycle delivers it. */
78
- handoffMessageFor(plan: TransitionPlan): UserMessage;
79
- /**
80
- * Whether one Agent's pending transition requires the admission gate: a
81
- * pending rollover must stop old-generation turns from admitting queued
82
- * input. The gate arms only for the old-generation Agent instance — the
83
- * new generation activates mid-swap and must be free to consume the
84
- * handoff and carried input immediately.
85
- */
86
- needsAdmissionGate(agent: Agent): boolean;
87
- /**
88
- * Capture the inbox messages queued for an old generation at its turn-stop
89
- * boundary: non-Team input is preserved verbatim for delivery after the
90
- * handoff; stale Team notices are dropped because the new generation
91
- * rederives the Inbox from ledger facts. Removing them from the inbox lets
92
- * the turn close cleanly instead of admitting another old-generation step.
93
- */
94
- captureQueuedInput(agent: Agent): readonly UserMessage[];
95
- /**
96
- * Capture messages a racing pre-step already claimed from the inbox before
97
- * rejecting that old-generation step. A rejected step's claimed message is
98
- * otherwise neither discarded nor re-emitted, so the gate preserves it here.
99
- */
100
- captureClaimedInput(agent: Agent, messages: readonly UserMessage[]): readonly UserMessage[];
101
- private captureInput;
102
- /** Drain the captured input of one Member for delivery after the handoff. */
103
- drainCapturedInput(memberId: AgentTeamMemberId): readonly UserMessage[];
104
- /**
105
- * Whether one queued message is a Team-owned notice the rederived Inbox
106
- * replaces. Handoff and continuation envelopes carry the same plugin
107
- * attribution but are ordinary delivered context the new generation keeps, so
108
- * they are excluded rather than dropped.
109
- */
110
- private isTeamNotice;
111
- /** Drop one Member's bookkeeping; the Host calls this on dispose/removal. */
112
- stopTracking(memberId: AgentTeamMemberId): void;
113
- dispose(): void;
114
- private onToolResult;
115
- private onUserMessage;
116
- private onTurnEnd;
117
- /**
118
- * Claim the in-process latch for one resolved checkpoint continuation.
119
- * Returns the latch key when this caller won it, or undefined when the
120
- * checkpoint never concluded a turn, was already delivered durably, or is
121
- * latched already. The caller releases the latch on its own failure path.
122
- */
123
- private claimContinuationLatch;
124
- /**
125
- * Quiet follow-ups for checkpoints resolved by the turn that just ended.
126
- * A successful `context_checkpoint` result concludes its turn; the Host
127
- * continues work in the next turn with one host-generated notice. The
128
- * projection folds delivery (the continuation user/message event), so a
129
- * restart repairs a missing follow-up through repairContinuations without
130
- * duplicating a delivered one; this live path latches per checkpoint in
131
- * memory for the scheduling window.
132
- */
133
- private scheduleCheckpointContinuations;
134
- private performTransition;
135
- /**
136
- * Crash-recovery hook the Host runs during Member activation: re-derive
137
- * pending intent from the projection and finish a transition that a restart
138
- * interrupted after the successful result was durable.
139
- */
140
- recoverPendingTransition(memberId: AgentTeamMemberId, agent: Agent, sessionId: SessionId): void;
141
- /**
142
- * Crash-recovery for quiet continuations: schedule the follow-up for one
143
- * resolved checkpoint exactly once when the result was durable but the
144
- * delivery never landed. The projection's continuations state is the
145
- * durable delivery record — a checkpoint whose delivery event exists in the
146
- * log is never re-scheduled.
147
- */
148
- repairContinuations(agent: Agent, state: AgentTeamContextProjectionState): void;
149
- }
150
- /** Tool names this module owns; the preset validation requires all of them. */
151
- export declare const CONTEXT_TOOL_NAMES: readonly ["context_checkpoint", "context_rollover", "context_timeline"];
152
- /** Re-exported for Host wiring: cold-fold helper for archived ancestors. */
153
- export { foldContextProjection };
154
- //# sourceMappingURL=context-management.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context-management.d.ts","sourceRoot":"","sources":["../../src/context-management.ts"],"names":[],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
2
- import type { AgentTeamChannelRef, AgentTeamResolveTaskRefsRequest, AgentTeamResolveTaskRefsResult, AgentTeamTaskRef, AgentTeamThreadRef } from '@wowyuarm/dsh-agent-team/types';
3
- /** Navigation facts for one branded Task ref, resolved once per session. */
4
- export interface ResolvedTaskRef {
5
- readonly taskRef: AgentTeamTaskRef;
6
- readonly channelRef: AgentTeamChannelRef;
7
- readonly threadRef: AgentTeamThreadRef;
8
- readonly taskNumber: number;
9
- }
10
- /** React binding: re-renders the caller when any ref resolution lands. */
11
- export declare const useResolvedTaskRefVersion: () => number;
12
- export declare const cachedResolvedTaskRef: (taskRef: AgentTeamTaskRef) => ResolvedTaskRef | undefined;
13
- /** Store one resolution (click path) and wake every rendered link. */
14
- export declare const rememberResolvedTaskRef: (entry: ResolvedTaskRef) => void;
15
- /**
16
- * Click-path Host lookup: remember every resolved entry and hand them back
17
- * for immediate navigation. The Host keeps `resolved` in the same order as
18
- * the input `taskRefs` (one entry per resolvable input, unknowns omitted);
19
- * the pairing walk below relies on that contract, so it must be preserved
20
- * together with this implementation.
21
- */
22
- export declare const hostTaskRefLookup: (resolveTaskRefs: (request: AgentTeamResolveTaskRefsRequest) => Promise<RemoteResult<AgentTeamResolveTaskRefsResult>>, workspaceId: AgentTeamResolveTaskRefsRequest["workspaceId"]) => ((taskRefs: readonly AgentTeamTaskRef[]) => Promise<readonly ResolvedTaskRef[]>);
23
- /** Resolve one Task ref through the Host and jump to its home Channel Thread. */
24
- 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;
25
- /**
26
- * Batch-resolve unknown refs through the Host lookup. Concurrent callers
27
- * deduplicate through the pending set; failures just clear the pending mark
28
- * so a later interaction can retry.
29
- */
30
- export declare const resolveUnknownTaskRefs: (refs: readonly AgentTeamTaskRef[], lookup: (taskRefs: readonly AgentTeamTaskRef[]) => Promise<readonly ResolvedTaskRef[]>) => Promise<void>;
31
- //# sourceMappingURL=task-refs.d.ts.map
@@ -1 +0,0 @@
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;AAOD;;;;;;GAMG;AACH,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,CAiB/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"}