@xopcai/xopc 0.0.384 → 0.0.385

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 (150) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BSel9yf8.js → agent-avatar-dicebear-Cb9eaXxR.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-DgHMyhuY.js → agent-defaults-settings-panel-DEV-xtgm.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-plugin-dialog-BosuN4dO.js → agent-plugin-dialog-DXKc3Luj.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-B-pw5RKI.js → agents-DcNxwpJQ.js} +3 -3
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-DuOqKkfH.js → app-management-settings-panel-X5i0Tz7_.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-8JF9rXFr.js → appearance-settings-CmHHzquT.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-Cuclpk0A.js → apps-page-ChFA4Zp0.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automations-page-D7NwNy2I.js → automations-page-BFqsIqOI.js} +1 -1
  11. package/dist/gateway/static/root/assets/{automations-workspace-CSxW4wX0.js → automations-workspace-Blfak-fT.js} +1 -1
  12. package/dist/gateway/static/root/assets/{block-editor-Dnb7CH_l.js → block-editor-CpOLG3Co.js} +1 -1
  13. package/dist/gateway/static/root/assets/{browser-automations-page-GBgDe21o.js → browser-automations-page-BSbTJ9j2.js} +1 -1
  14. package/dist/gateway/static/root/assets/{browser-settings-page-B2FXaO3n.js → browser-settings-page-BUlILJrB.js} +1 -1
  15. package/dist/gateway/static/root/assets/{capabilities-page-f2-MquJn.js → capabilities-page-CeRdkwRf.js} +2 -2
  16. package/dist/gateway/static/root/assets/{capabilities-settings-panel-D9F0mw16.js → capabilities-settings-panel-S-cKsGja.js} +1 -1
  17. package/dist/gateway/static/root/assets/{capability-header-actions-DVRxJPQP.js → capability-header-actions-6w8pQhnn.js} +1 -1
  18. package/dist/gateway/static/root/assets/{channels-CnDm5T1t.js → channels-DfNTGBmp.js} +1 -1
  19. package/dist/gateway/static/root/assets/{chat-terminal-dock-BxSCDbK7.js → chat-terminal-dock-DnoQHpDc.js} +1 -1
  20. package/dist/gateway/static/root/assets/{computer-settings-page-DVAB-kQw.js → computer-settings-page-7yliE7sG.js} +1 -1
  21. package/dist/gateway/static/root/assets/{connector-service-page-D2EeLXei.js → connector-service-page-DOLAUFSW.js} +1 -1
  22. package/dist/gateway/static/root/assets/{connectors-page-DK9n4hgZ.js → connectors-page-DAsn97XG.js} +1 -1
  23. package/dist/gateway/static/root/assets/{date-picker-Cl9KfFj8.js → date-picker-DNDqr4Fk.js} +1 -1
  24. package/dist/gateway/static/root/assets/{dependency-picker-Ei6aX5WM.js → dependency-picker-B5oG7RgE.js} +1 -1
  25. package/dist/gateway/static/root/assets/{desktop-pet-4Evl4RKX.js → desktop-pet-K7kUCX1O.js} +1 -1
  26. package/dist/gateway/static/root/assets/{desktop-pet-settings-DAD_OWcX.js → desktop-pet-settings-KgOAuqSh.js} +1 -1
  27. package/dist/gateway/static/root/assets/{device-pairing-wizard-BA21epMn.js → device-pairing-wizard-DvqniZDm.js} +1 -1
  28. package/dist/gateway/static/root/assets/{directory-picker-path-field-B_Zb5nNR.js → directory-picker-path-field-BmOguLDl.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-page-8gWSThWP.js → extension-page-DSSuMQxp.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-settings-page-CunUbB09.js → extension-settings-page-DSd__mNd.js} +1 -1
  31. package/dist/gateway/static/root/assets/{fallback-models-BSAfzXby.js → fallback-models-D7bjbiwZ.js} +1 -1
  32. package/dist/gateway/static/root/assets/{gateway-settings-CN-2229W.js → gateway-settings-hSXGWumL.js} +1 -1
  33. package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-DktBCtHF.js → highlighted-body-KQOG7T2V-C7xJwE61.js} +1 -1
  34. package/dist/gateway/static/root/assets/{home-page-CUJcNW3H.js → home-page-DJNmlMfH.js} +1 -1
  35. package/dist/gateway/static/root/assets/{imports-page-DQm1MNNC.js → imports-page-BufZPzGE.js} +1 -1
  36. package/dist/gateway/static/root/assets/index-DBRwvWzm.css +1 -0
  37. package/dist/gateway/static/root/assets/{index-BPNL54bv.js → index-K8SXDtxr.js} +9 -9
  38. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DaC5YjuJ.js → keyboard-shortcuts-settings-B8pPP5RF.js} +1 -1
  39. package/dist/gateway/static/root/assets/{local-app-workbench-page-DwQyyo7a.js → local-app-workbench-page-zEtvE7pJ.js} +1 -1
  40. package/dist/gateway/static/root/assets/{local-apps-page-CpZhivpf.js → local-apps-page-Bli7e_eg.js} +1 -1
  41. package/dist/gateway/static/root/assets/{logs-page-Db43nh1M.js → logs-page-BimZk3R4.js} +1 -1
  42. package/dist/gateway/static/root/assets/{management-settings-DrKejBEZ.js → management-settings-5Y4COyU9.js} +1 -1
  43. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-DBRj4-1-.js +1 -0
  44. package/dist/gateway/static/root/assets/{note-detail-panel-a8NSwmmW.js → note-detail-panel-KLDPLVg7.js} +3 -3
  45. package/dist/gateway/static/root/assets/{notes-page-BKRke43F.js → notes-page-DST0oPXD.js} +1 -1
  46. package/dist/gateway/static/root/assets/{page-context-capture-button-DUaMkmxv.js → page-context-capture-button-Bmed83-6.js} +1 -1
  47. package/dist/gateway/static/root/assets/{personal-page-BqF-HHw1.js → personal-page-BG4Ystrm.js} +1 -1
  48. package/dist/gateway/static/root/assets/{product-open-page-GrhtTQIz.js → product-open-page-CXkYP9xE.js} +1 -1
  49. package/dist/gateway/static/root/assets/{product-preview-content-zdP7gN0y.js → product-preview-content-DjmupQSq.js} +1 -1
  50. package/dist/gateway/static/root/assets/{project-detail-page-9Vd_AqDW.js → project-detail-page-CzBmV0P6.js} +1 -1
  51. package/dist/gateway/static/root/assets/{projects-page-DGunhjoM.js → projects-page-DByqe5Em.js} +1 -1
  52. package/dist/gateway/static/root/assets/{remote-access-hub-BoRsF3Lx.js → remote-access-hub-DTjj-odF.js} +1 -1
  53. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-W0HDm--J.js → runtime-tools-settings-panel-B_ptn3T8.js} +1 -1
  54. package/dist/gateway/static/root/assets/{scenes-page-CYsFOfVJ.js → scenes-page-wkua4l5y.js} +1 -1
  55. package/dist/gateway/static/root/assets/{schema-form-CBxEbBQq.js → schema-form-VvOSM84Y.js} +1 -1
  56. package/dist/gateway/static/root/assets/{sessions-page-Dthfx_vc.js → sessions-page-D06XwYAT.js} +1 -1
  57. package/dist/gateway/static/root/assets/settings-advanced-gate-DoAHy1wj.js +1 -0
  58. package/dist/gateway/static/root/assets/{settings-page-CFs-WP_2.js → settings-page-C-6BJdb1.js} +1 -1
  59. package/dist/gateway/static/root/assets/{setup-status-panel-D2-9fXYL.js → setup-status-panel-L0JSG0K-.js} +1 -1
  60. package/dist/gateway/static/root/assets/{shares-settings-DTb88RHD.js → shares-settings-BbgAUM3v.js} +1 -1
  61. package/dist/gateway/static/root/assets/{skill-api-DJ8UBsxq.js → skill-api-BFU1tPyw.js} +1 -1
  62. package/dist/gateway/static/root/assets/{skills-page-DjbBOikT.js → skills-page-DZw6el4o.js} +1 -1
  63. package/dist/gateway/static/root/assets/{system-settings-panel-Dt5GkLhM.js → system-settings-panel-DshSGWNg.js} +1 -1
  64. package/dist/gateway/static/root/assets/{task-detail-page-88EShcbs.js → task-detail-page-CfZhq4XZ.js} +1 -1
  65. package/dist/gateway/static/root/assets/{tunnel-api-JHttXi63.js → tunnel-api-DFDXwWnU.js} +1 -1
  66. package/dist/gateway/static/root/assets/{usage-page-B3rUa0fW.js → usage-page-2RJLg54s.js} +1 -1
  67. package/dist/gateway/static/root/assets/{user-model-page-Cq1VSsZw.js → user-model-page-y1gjGYPI.js} +1 -1
  68. package/dist/gateway/static/root/assets/{work-discovery-overlay-BAtG_JHv.js → work-discovery-overlay-Ch-KfpCF.js} +1 -1
  69. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cw12NFgx.js → workflow-run-setup-panel-CTu297Hc.js} +1 -1
  70. package/dist/gateway/static/root/assets/{workflows-page-kR5ouOuM.js → workflows-page-CRZXG_rm.js} +1 -1
  71. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-BTBVKpSg.js → xopc-cloud-account-card-hEfjVjnc.js} +1 -1
  72. package/dist/gateway/static/root/index.html +2 -2
  73. package/dist/package.js +1 -1
  74. package/dist/src/agent/child-agent-factory.js +7 -1
  75. package/dist/src/agent/embedded/execution-tool-policy.d.ts +1 -1
  76. package/dist/src/agent/embedded/execution-tool-policy.js +3 -2
  77. package/dist/src/agent/embedded/run-for-session.js +32 -12
  78. package/dist/src/agent/embedded/run-turn.js +108 -24
  79. package/dist/src/agent/embedded/session-runner.js +9 -1
  80. package/dist/src/agent/embedded/types.d.ts +2 -1
  81. package/dist/src/agent/external-tools/cliProvider.d.ts +1 -0
  82. package/dist/src/agent/external-tools/cliProvider.js +1 -0
  83. package/dist/src/agent/external-tools/composio-provider.js +2 -0
  84. package/dist/src/agent/external-tools/gateway-tools.js +8 -2
  85. package/dist/src/agent/external-tools/service.d.ts +1 -0
  86. package/dist/src/agent/external-tools/service.js +3 -1
  87. package/dist/src/agent/external-tools/types.d.ts +4 -0
  88. package/dist/src/agent/orchestration/agent-turn-policy.d.ts +1 -0
  89. package/dist/src/agent/orchestration/delegation-budget.js +2 -1
  90. package/dist/src/agent/orchestration/llm-turn-retry.d.ts +5 -0
  91. package/dist/src/agent/orchestration/llm-turn-retry.js +15 -5
  92. package/dist/src/agent/orchestration/turn-recovery.d.ts +6 -0
  93. package/dist/src/agent/orchestration/turn-recovery.js +29 -0
  94. package/dist/src/agent/service/direct-turn-helpers.js +6 -5
  95. package/dist/src/agent/service/process-direct-streaming.js +7 -1
  96. package/dist/src/agent/tasks/task-judge-service.js +28 -10
  97. package/dist/src/agent/tools/factory.js +10 -1
  98. package/dist/src/agent/tools/index.d.ts +1 -0
  99. package/dist/src/agent/tools/index.js +2 -1
  100. package/dist/src/agent/tools/personal-request-result-tool.js +20 -3
  101. package/dist/src/agent/tools/personal-request-tool.js +162 -15
  102. package/dist/src/agent/tools/personal-task-tool.d.ts +5 -1
  103. package/dist/src/agent/tools/personal-task-tool.js +137 -15
  104. package/dist/src/agent/tools/task-collaboration-tool.d.ts +16 -0
  105. package/dist/src/agent/tools/task-collaboration-tool.js +153 -0
  106. package/dist/src/agent/tools/xopc-use-tool.js +1 -1
  107. package/dist/src/cli/commands/channels.js +1 -1
  108. package/dist/src/cli/commands/connectors.js +1 -1
  109. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  110. package/dist/src/cli/commands/models.js +1 -1
  111. package/dist/src/cli/commands/onboard.js +1 -1
  112. package/dist/src/connectors/connection-recovery-service.d.ts +6 -0
  113. package/dist/src/connectors/connection-recovery-service.js +151 -32
  114. package/dist/src/extensions/sdk/index.js +1 -1
  115. package/dist/src/gateway/hono/routes/connection-waits.js +3 -1
  116. package/dist/src/gateway/service/run-gateway-agent.js +9 -5
  117. package/dist/src/gateway/service/session-input-coordinator.js +4 -2
  118. package/dist/src/gateway/service.js +9 -9
  119. package/dist/src/personal-agent/prompts.js +6 -2
  120. package/dist/src/personal-agent/reply-composer.js +23 -9
  121. package/dist/src/personal-agent/request-access.d.ts +3 -0
  122. package/dist/src/personal-agent/request-access.js +31 -0
  123. package/dist/src/personal-agent/request-delivery.js +9 -4
  124. package/dist/src/personal-agent/request-repository.d.ts +1 -0
  125. package/dist/src/personal-agent/request-service.d.ts +2 -0
  126. package/dist/src/personal-agent/request-service.js +32 -7
  127. package/dist/src/providers/model-response.js +13 -2
  128. package/dist/src/session/store.js +19 -6
  129. package/dist/src/storage/sqlite/connection-wait-repository.d.ts +2 -0
  130. package/dist/src/storage/sqlite/connection-wait-repository.js +83 -4
  131. package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -0
  132. package/dist/src/storage/sqlite/transcript-repository.js +25 -1
  133. package/dist/src/tasks/task-application-service.js +1 -1
  134. package/dist/src/tasks/task-collaboration-delivery.js +4 -1
  135. package/dist/src/tasks/task-collaboration-repository.d.ts +3 -0
  136. package/dist/src/tasks/task-collaboration-repository.js +11 -1
  137. package/dist/src/tasks/task-context-assembler.js +13 -5
  138. package/dist/src/tasks/task-continuation.d.ts +5 -0
  139. package/dist/src/tasks/task-continuation.js +32 -0
  140. package/dist/src/tasks/task-main-update-delivery.js +13 -8
  141. package/dist/src/tasks/task-read-model-projector.js +1 -1
  142. package/dist/src/tasks/task-run-coordinator.d.ts +1 -0
  143. package/dist/src/tasks/task-run-coordinator.js +21 -6
  144. package/dist/src/tasks/task-run-dispatcher.js +11 -0
  145. package/dist/src/tasks/task-run-repository.d.ts +8 -0
  146. package/dist/src/tasks/task-run-repository.js +32 -1
  147. package/package.json +5 -5
  148. package/dist/gateway/static/root/assets/index-yseLAt9D.css +0 -1
  149. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-C4VzqE9z.js +0 -1
  150. package/dist/gateway/static/root/assets/settings-advanced-gate-O_0Lk38S.js +0 -1
@@ -10,6 +10,7 @@ import { isPersonalConversation } from "../../personal-agent/repository.js";
10
10
  import { TaskAllocationRepository } from "../../tasks/task-allocation-repository.js";
11
11
  import { TaskOriginRepository } from "../../tasks/task-origin-repository.js";
12
12
  import { boundedPersonalResult } from "./personal-result-budget.js";
13
+ import { TaskCollaborationRepository } from "../../tasks/task-collaboration-repository.js";
13
14
  import { TaskApplicationService } from "../../tasks/task-application-service.js";
14
15
  import { createXopcUseTool } from "./xopc-use-tool.js";
15
16
  import { getAvailablePersonalAgentTools, personalAgentModelAvailability } from "../../personal-agent/specialist-capabilities.js";
@@ -36,6 +37,8 @@ const PersonalTaskSchema = Type.Object({
36
37
  Type.Literal("create"),
37
38
  Type.Literal("list"),
38
39
  Type.Literal("get"),
40
+ Type.Literal("collaboration"),
41
+ Type.Literal("entry"),
39
42
  Type.Literal("instruct"),
40
43
  Type.Literal("answer"),
41
44
  Type.Literal("cancel")
@@ -81,6 +84,25 @@ const PersonalTaskSchema = Type.Object({
81
84
  agentId: Type.Optional(Type.String({ description: "Specialist Agent ID. Never use your own ID." })),
82
85
  taskId: Type.Optional(Type.String()),
83
86
  instruction: Type.Optional(Type.String({ description: "The user’s new direction for this delegated Task." })),
87
+ entryId: Type.Optional(Type.String({ description: "Read one complete collaboration entry, including its question or instruction body." })),
88
+ afterSequence: Type.Optional(Type.Integer({ minimum: 0 })),
89
+ bodyOffset: Type.Optional(Type.Integer({
90
+ minimum: 0,
91
+ description: "Character offset for an entry body; follow nextBodyOffset until absent."
92
+ })),
93
+ section: Type.Optional(Type.Union([
94
+ "task",
95
+ "waits",
96
+ "runs",
97
+ "receipts",
98
+ "context",
99
+ "conversation",
100
+ "sessions",
101
+ "authorityGrants",
102
+ "dependencies",
103
+ "dependents",
104
+ "criterionReviews"
105
+ ].map((value) => Type.Literal(value)))),
84
106
  questionId: Type.Optional(Type.String({ description: "Collaboration question ID to answer." })),
85
107
  expectedOutputs: Type.Optional(Type.Array(Type.String())),
86
108
  acceptanceCriteria: Type.Optional(Type.Array(Type.String())),
@@ -107,6 +129,8 @@ const PersonalTaskModelSchema = Type.Object({
107
129
  "submit",
108
130
  "list",
109
131
  "get",
132
+ "collaboration",
133
+ "entry",
110
134
  "instruct",
111
135
  "answer",
112
136
  "retry_allocation",
@@ -124,11 +148,16 @@ const PersonalTaskModelSchema = Type.Object({
124
148
  {
125
149
  properties: { command: { enum: [
126
150
  "get",
151
+ "collaboration",
127
152
  "retry_allocation",
128
153
  "cancel"
129
154
  ] } },
130
155
  required: ["taskId"]
131
156
  },
157
+ {
158
+ properties: { command: { const: "entry" } },
159
+ required: ["taskId", "entryId"]
160
+ },
132
161
  {
133
162
  properties: { command: { const: "instruct" } },
134
163
  required: ["taskId", "instruction"]
@@ -164,7 +193,7 @@ function createPersonalTaskTool(deps) {
164
193
  return {
165
194
  name: "personal_task",
166
195
  label: "Personal Task",
167
- description: "Submit objective and a concise complete description, then return after local persistence. Preserve the user request and source references without inventing an execution plan or extra requirements. Omit optional structured fields when they merely repeat the description. Describe required capabilities in the brief; the background Task Router selects one executor and checks its tools. Do not read input files, select Agents or invent tool names before submit. Set requirements.requestedAgentId only for an executor explicitly named by the user, using their ID or display name; preserve explicitly requested requiredSkills. get/list inspect existing Tasks with limit/offset; cancel stops a Task on explicit user instruction and reports execution stop confirmation; instruct/answer send context; retry_allocation retries selection before execution; selection explains assignment. Status and results return automatically. Preserve idempotencyKey on uncertain retries. Report only confirmed states.",
196
+ description: "Submit objective and a concise complete description, then return after local persistence. Preserve the user request and source references without inventing an execution plan or extra requirements. Omit optional structured fields when they merely repeat the description. Describe required capabilities in the brief; the background Task Router selects one executor and checks its tools. Do not read input files, select Agents or invent tool names before submit. Set requirements.requestedAgentId only for an executor explicitly named by the user, using their ID or display name; preserve explicitly requested requiredSkills. get reads Task state, waits, runs, receipts and context; use section and limit/offset for complete paginated details. collaboration reads ordered message previews with afterSequence; entry reads exact message bodies using entryId and nextBodyOffset. Read full questions before answering. Delivery pending means saved, delivered means sent, confirmed means the executor acknowledged it; confirmation alone is not verified completion. get/list inspect existing Tasks with limit/offset; cancel stops a Task on explicit user instruction and reports execution stop confirmation; instruct/answer send context; retry_allocation retries selection before execution; selection explains assignment. Status and results return automatically. Preserve idempotencyKey on uncertain retries. Report only confirmed states.",
168
197
  parameters: PersonalTaskModelSchema,
169
198
  mutatesWorkspace: true,
170
199
  mutationScope: "external",
@@ -383,6 +412,54 @@ function createPersonalTaskTool(deps) {
383
412
  const taskId = input.taskId?.trim();
384
413
  if (!taskId) throw new Error("taskId is required");
385
414
  if (!new TaskOriginRepository().owns(taskId, conversationId)) throw new Error("Task does not belong to this personal conversation");
415
+ if (command === "collaboration" || command === "entry") {
416
+ const board = new TaskCollaborationRepository();
417
+ if (command === "entry") {
418
+ const entry = input.entryId ? board.get(input.entryId) : void 0;
419
+ if (!entry || entry.taskId !== taskId) throw new Error("Entry does not belong to this Task");
420
+ const offset = input.bodyOffset ?? 0;
421
+ const body = entry.body.slice(offset, offset + 4e3);
422
+ const payload = {
423
+ ok: true,
424
+ entry: {
425
+ ...entry,
426
+ body
427
+ },
428
+ bodyOffset: offset,
429
+ bodyLength: entry.body.length,
430
+ ...offset + body.length < entry.body.length ? { nextBodyOffset: offset + body.length } : {}
431
+ };
432
+ return {
433
+ content: [{
434
+ type: "text",
435
+ text: JSON.stringify(payload)
436
+ }],
437
+ details: {}
438
+ };
439
+ }
440
+ const limit = input.limit ?? 10;
441
+ const entries = board.list(taskId, input.afterSequence ?? 0, limit + 1);
442
+ const items = entries.slice(0, limit).map((entry) => ({
443
+ ...entry,
444
+ body: entry.body.slice(0, 600),
445
+ bodyLength: entry.body.length,
446
+ ...entry.body.length > 600 ? {
447
+ excerpt: true,
448
+ readEntryId: entry.id
449
+ } : {}
450
+ }));
451
+ return {
452
+ content: [{
453
+ type: "text",
454
+ text: JSON.stringify({
455
+ ok: true,
456
+ items,
457
+ ...entries.length > limit ? { nextAfterSequence: items.at(-1)?.sequence } : {}
458
+ })
459
+ }],
460
+ details: {}
461
+ };
462
+ }
386
463
  if (command === "cancel") {
387
464
  const result = await cancelPersonalTask(taskId, conversationId, input.idempotencyKey ?? toolCallId);
388
465
  deps.dispatchTaskRuns?.();
@@ -410,6 +487,13 @@ function createPersonalTaskTool(deps) {
410
487
  taskId,
411
488
  kind: input.command === "answer" ? "answer" : "instruction",
412
489
  body,
490
+ idempotencyKey: input.idempotencyKey?.trim() || `personal-collaboration:${selectionRequestHash({
491
+ inputId: getSessionInputState(conversationId).activeInputId ?? toolCallId,
492
+ taskId,
493
+ kind: input.command,
494
+ body,
495
+ questionId: input.questionId
496
+ })}`,
413
497
  ...input.command === "answer" ? { causationId: input.questionId.trim() } : {}
414
498
  };
415
499
  } else args = { taskId };
@@ -459,20 +543,58 @@ function createPersonalTaskTool(deps) {
459
543
  details: {}
460
544
  };
461
545
  }
462
- if (payload && input.command === "get") return {
463
- content: [{
464
- type: "text",
465
- text: JSON.stringify(boundedPersonalResult({
466
- ok: payload.ok,
467
- task: payload.task,
468
- allocation: new TaskAllocationRepository().summary(input.taskId),
469
- operationalState: payload.operationalState,
470
- attention: payload.attention,
471
- allowedCommands: payload.allowedCommands
472
- }))
473
- }],
474
- details: {}
475
- };
546
+ if (payload && input.command === "get") {
547
+ const offset = input.offset ?? 0;
548
+ const limit = input.limit ?? 10;
549
+ const read = input.section ? {
550
+ ok: payload.ok,
551
+ [input.section]: payload[input.section]
552
+ } : { ...payload };
553
+ const pagination = {};
554
+ for (const key of [
555
+ "waits",
556
+ "runs",
557
+ "receipts",
558
+ "context",
559
+ "sessions",
560
+ "authorityGrants",
561
+ "dependencies",
562
+ "dependents",
563
+ "criterionReviews"
564
+ ]) {
565
+ const value = read[key];
566
+ if (!Array.isArray(value)) continue;
567
+ read[key] = value.slice(offset, offset + limit);
568
+ pagination[key] = {
569
+ total: value.length,
570
+ offset,
571
+ ...offset + limit < value.length ? { nextOffset: offset + limit } : {}
572
+ };
573
+ }
574
+ if (!input.section) {
575
+ read.collaboration = new TaskCollaborationRepository().recent(input.taskId, void 0, 10).map((entry) => ({
576
+ ...entry,
577
+ body: entry.body.slice(0, 600),
578
+ bodyLength: entry.body.length,
579
+ ...entry.body.length > 600 ? {
580
+ excerpt: true,
581
+ readEntryId: entry.id
582
+ } : {}
583
+ }));
584
+ read.allocation = new TaskAllocationRepository().summary(input.taskId);
585
+ read.guidance = "Read entry for complete question/instruction bodies; collaboration with afterSequence pages the whole board. get(section, offset) pages state details. pending is saved, delivered is sent, confirmed is acknowledged; verification and Task acceptance are separate.";
586
+ }
587
+ return {
588
+ content: [{
589
+ type: "text",
590
+ text: JSON.stringify({
591
+ ...read,
592
+ pagination
593
+ })
594
+ }],
595
+ details: {}
596
+ };
597
+ }
476
598
  if (payload && input.command === "list") return {
477
599
  content: [{
478
600
  type: "text",
@@ -0,0 +1,16 @@
1
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ import { type XopcUseToolDeps } from './xopc-use-tool.js';
3
+ declare const Schema: import("@sinclair/typebox").TObject<{
4
+ command: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"get">, import("@sinclair/typebox").TLiteral<"post">]>;
5
+ section: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"collaboration">, import("@sinclair/typebox").TLiteral<"task">]>>;
6
+ kind: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"progress">, import("@sinclair/typebox").TLiteral<"question">, import("@sinclair/typebox").TLiteral<"ack">]>>;
7
+ body: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
8
+ causationId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
9
+ entryId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
10
+ afterSequence: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
11
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
12
+ idempotencyKey: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
13
+ }>;
14
+ /** Collaboration only: no product mutations, connection selection or external operations. */
15
+ export declare function createTaskCollaborationTool(deps: XopcUseToolDeps): AgentTool<typeof Schema>;
16
+ export {};
@@ -0,0 +1,153 @@
1
+ import { TaskRepository, init_task_repository } from "../../tasks/task-repository.js";
2
+ import { TaskRunRepository, init_task_run_repository } from "../../tasks/task-run-repository.js";
3
+ import { init_request_repository, personalRequestForExecution } from "../../personal-agent/request-repository.js";
4
+ import { getSessionMetadata } from "../../storage/sqlite/session-read-repository.js";
5
+ import { init_session_repository } from "../../storage/sqlite/session-repository.js";
6
+ import { TaskReadModelProjector } from "../../tasks/task-read-model-projector.js";
7
+ import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
8
+ import { getEmbeddedExecutionSession } from "../embedded/execution-context.js";
9
+ import { TaskCollaborationRepository } from "../../tasks/task-collaboration-repository.js";
10
+ import { createXopcUseTool } from "./xopc-use-tool.js";
11
+ import { Type } from "@sinclair/typebox";
12
+ //#region src/agent/tools/task-collaboration-tool.ts
13
+ init_request_repository();
14
+ init_session_repository();
15
+ init_task_repository();
16
+ init_task_run_repository();
17
+ const Schema = Type.Object({
18
+ command: Type.Union([Type.Literal("get"), Type.Literal("post")]),
19
+ section: Type.Optional(Type.Union([Type.Literal("collaboration"), Type.Literal("task")])),
20
+ kind: Type.Optional(Type.Union([
21
+ Type.Literal("progress"),
22
+ Type.Literal("question"),
23
+ Type.Literal("ack")
24
+ ])),
25
+ body: Type.Optional(Type.String({
26
+ minLength: 1,
27
+ maxLength: 8e3
28
+ })),
29
+ causationId: Type.Optional(Type.String({ minLength: 1 })),
30
+ entryId: Type.Optional(Type.String({ minLength: 1 })),
31
+ afterSequence: Type.Optional(Type.Integer({ minimum: 0 })),
32
+ limit: Type.Optional(Type.Integer({
33
+ minimum: 1,
34
+ maximum: 20
35
+ })),
36
+ idempotencyKey: Type.Optional(Type.String({
37
+ minLength: 1,
38
+ maxLength: 200
39
+ }))
40
+ }, {
41
+ additionalProperties: false,
42
+ anyOf: [
43
+ { properties: { command: { const: "get" } } },
44
+ {
45
+ properties: {
46
+ command: { const: "post" },
47
+ kind: { enum: ["progress", "question"] }
48
+ },
49
+ required: ["kind", "body"]
50
+ },
51
+ {
52
+ properties: {
53
+ command: { const: "post" },
54
+ kind: { const: "ack" }
55
+ },
56
+ required: [
57
+ "kind",
58
+ "body",
59
+ "causationId"
60
+ ]
61
+ }
62
+ ]
63
+ });
64
+ /** Collaboration only: no product mutations, connection selection or external operations. */
65
+ function createTaskCollaborationTool(deps) {
66
+ return {
67
+ name: "task_collaboration",
68
+ label: "Task collaboration",
69
+ parameters: Schema,
70
+ description: "Coordinate the current Task with its Personal owner. get with section task reads the complete brief, constraints and waits; default get reads complete ordered messages (afterSequence/limit) or one entryId. post progress for meaningful changes; post question then stop this turn until answered. Before continuing, post ack with causationId equal to each delivered answer/instruction ID and explain how the result will incorporate it. Confirmation is receipt and intent, not completed verification. Reuse the same Task and executor. Account authorization stays in the main connection UI; answers and instructions cannot change the selected connector/account or permit writes. Preserve idempotencyKey on retries.",
71
+ mutatesWorkspace: true,
72
+ mutationScope: "external",
73
+ requiresExclusiveWorkspaceLock: false,
74
+ async execute(toolCallId, input, signal) {
75
+ const conversationId = getEmbeddedExecutionSession() ?? deps.getCurrentConversationId?.();
76
+ const active = conversationId ? new TaskConversationRepository().resolveActiveExecutionSession(conversationId) : void 0;
77
+ if (!active || deps.getCurrentAgentId?.() && active.agentId !== deps.getCurrentAgentId()) throw new Error("No active Task execution");
78
+ const request = personalRequestForExecution(conversationId);
79
+ if (!request && getSessionMetadata(conversationId)?.customData?.personalReadRequestId || request && [
80
+ "cancelled",
81
+ "completed",
82
+ "failed"
83
+ ].includes(request.state)) throw new Error("Personal request is no longer active");
84
+ if (input.command === "get") {
85
+ if (input.section === "task") {
86
+ const model = new TaskReadModelProjector().project(new TaskRepository().require(active.taskId));
87
+ return {
88
+ content: [{
89
+ type: "text",
90
+ text: JSON.stringify({
91
+ ok: true,
92
+ ...model,
93
+ waits: new TaskRunRepository().listActiveWaits(active.taskId)
94
+ })
95
+ }],
96
+ details: {}
97
+ };
98
+ }
99
+ const board = new TaskCollaborationRepository();
100
+ if (input.entryId) {
101
+ const entry = board.get(input.entryId);
102
+ if (entry?.taskId !== active.taskId) throw new Error("Entry does not belong to this Task");
103
+ return {
104
+ content: [{
105
+ type: "text",
106
+ text: JSON.stringify({
107
+ ok: true,
108
+ entry
109
+ })
110
+ }],
111
+ details: {}
112
+ };
113
+ }
114
+ const limit = input.limit ?? 10;
115
+ const rows = board.list(active.taskId, input.afterSequence ?? 0, limit + 1);
116
+ const entries = rows.slice(0, limit);
117
+ return {
118
+ content: [{
119
+ type: "text",
120
+ text: JSON.stringify({
121
+ ok: true,
122
+ entries,
123
+ ...rows.length > limit ? { nextAfterSequence: entries.at(-1)?.sequence } : {}
124
+ })
125
+ }],
126
+ details: {}
127
+ };
128
+ }
129
+ const result = await createXopcUseTool({
130
+ ...deps,
131
+ getCurrentConversationId: () => conversationId,
132
+ getCurrentAgentId: () => active.agentId
133
+ }).execute(toolCallId, {
134
+ mode: "task",
135
+ command: "collaboration_post",
136
+ args: {
137
+ taskId: active.taskId,
138
+ kind: input.kind,
139
+ body: input.body,
140
+ causationId: input.causationId,
141
+ idempotencyKey: input.idempotencyKey ?? (input.kind === "ack" ? `ack:${active.agentId}:${input.causationId}` : toolCallId)
142
+ }
143
+ }, signal, void 0);
144
+ if (result.details.result?.ok === false) throw new Error(result.details.result.error ?? "Task collaboration failed");
145
+ return {
146
+ content: result.content,
147
+ details: {}
148
+ };
149
+ }
150
+ };
151
+ }
152
+ //#endregion
153
+ export { createTaskCollaborationTool };
@@ -1270,7 +1270,7 @@ async function handleTask(command, args, deps, dryRun, capabilities) {
1270
1270
  };
1271
1271
  if (causationId && (kind === "ack" || kind === "answer")) {
1272
1272
  const cited = collaboration.get(causationId);
1273
- if (cited?.taskId !== taskId || kind === "answer" && cited?.kind !== "question" || kind === "ack" && cited?.deliveryStatus !== "delivered") return {
1273
+ if (cited?.taskId !== taskId || kind === "answer" && cited?.kind !== "question" || kind === "ack" && (!active || !collaboration.canConfirm(causationId, conversationId, active.assignmentEpoch))) return {
1274
1274
  ok: false,
1275
1275
  error: "causationId must reference a relevant Task message"
1276
1276
  };
@@ -1,8 +1,8 @@
1
1
  import { buildChannelCatalogForConfig } from "../../channels/catalog/channel-catalog-service.js";
2
2
  import { loadConfig, saveConfig } from "../../config/loader.js";
3
- import { formatExamples, register } from "../registry.js";
4
3
  import { listChannelPairingState } from "../../channels/pairing/pairing-service.js";
5
4
  import { approveChannelPairingFromCli } from "../../channels/pairing/approve-cli.js";
5
+ import { formatExamples, register } from "../registry.js";
6
6
  import { colors } from "../utils/colors.js";
7
7
  import { Command } from "commander";
8
8
  //#region src/cli/commands/channels.ts
@@ -1,8 +1,8 @@
1
1
  import { getStoreConnectorInstallPlan, installStoreConnector, listStoreConnectors } from "../../capabilities/store-connector.js";
2
2
  import { loadConfig, saveConfig } from "../../config/loader.js";
3
3
  import { register } from "../registry.js";
4
- import { Command } from "commander";
5
4
  import { confirm } from "@inquirer/prompts";
5
+ import { Command } from "commander";
6
6
  //#region src/cli/commands/connectors.ts
7
7
  function parsePairs(values, option) {
8
8
  const output = {};
@@ -16,8 +16,8 @@ import { existsSync, readFileSync, statSync } from "node:fs";
16
16
  import { execSync } from "node:child_process";
17
17
  import { createHash } from "node:crypto";
18
18
  import semver from "semver";
19
- import { Command } from "commander";
20
19
  import { confirm } from "@inquirer/prompts";
20
+ import { Command } from "commander";
21
21
  //#region src/cli/commands/extension-marketplace.ts
22
22
  init_paths();
23
23
  const MANIFEST = "xopc.extension.json";
@@ -16,8 +16,8 @@ import { prepareUpdateGlobalDefaults } from "../../gateway/global-defaults-admin
16
16
  import { disconnectProvider } from "../../providers/provider-disconnect.js";
17
17
  import { colors } from "../utils/colors.js";
18
18
  import { runCliOAuthLogin } from "../utils/oauth-login.js";
19
- import { Command } from "commander";
20
19
  import { input } from "@inquirer/prompts";
20
+ import { Command } from "commander";
21
21
  //#region src/cli/commands/models.ts
22
22
  init_credentials();
23
23
  init_schema();
@@ -11,8 +11,8 @@ import { initWorkspace } from "../utils/init-workspace.js";
11
11
  import { setupModel } from "./onboard/model.js";
12
12
  import { getChannelConfigurators } from "./onboard/channels/registry.js";
13
13
  import { setupChannels } from "./onboard/channels/index.js";
14
- import { Command } from "commander";
15
14
  import { select } from "@inquirer/prompts";
15
+ import { Command } from "commander";
16
16
  //#region src/cli/commands/onboard.ts
17
17
  init_repository();
18
18
  init_schema();
@@ -7,6 +7,7 @@ export type ConnectionAction = {
7
7
  expectedTranscriptId: string;
8
8
  expectedVersion: number;
9
9
  idempotencyKey: string;
10
+ expectedObjectiveRevision?: number;
10
11
  action: 'install_complete' | 'connect' | 'check' | 'skip' | 'cancel' | 'select_account' | 'confirm_scope' | 'replace_source';
11
12
  needKey?: string;
12
13
  accountId?: string;
@@ -17,6 +18,7 @@ export type ConnectionAction = {
17
18
  export declare class ConnectionRecoveryService {
18
19
  private readonly deps;
19
20
  private readonly busy;
21
+ private readonly checks;
20
22
  private timer?;
21
23
  private deliveryTimer?;
22
24
  private polling;
@@ -32,8 +34,12 @@ export declare class ConnectionRecoveryService {
32
34
  drain: (conversationId: string) => void;
33
35
  onPersonalRequestDelivered?: (conversationId: string, requestId: string) => void;
34
36
  adapter?: ComposioSessionsAdapter;
37
+ checkTimeoutMs?: number;
35
38
  });
36
39
  private get adapter();
40
+ private markChecking;
41
+ /** Readiness checks never execute the objective; late results cannot advance a newer wait. */
42
+ private boundedCheck;
37
43
  snapshot(conversationId: string): ConnectionWaitSnapshot;
38
44
  private view;
39
45
  private ensureInstallation;