@tt-a1i/openpi 0.3.1 → 0.5.0

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 (129) hide show
  1. package/README.md +184 -59
  2. package/SETUP.md +23 -7
  3. package/assets/openpi-launch-card-v1.webp +0 -0
  4. package/bin/openpi.js +145 -0
  5. package/extensions/ask-user/index.ts +30 -14
  6. package/extensions/background-terminals/index.ts +30 -2
  7. package/extensions/background-terminals/src/domain.ts +2 -0
  8. package/extensions/background-terminals/src/manager.ts +486 -106
  9. package/extensions/background-terminals/src/output.ts +33 -0
  10. package/extensions/background-terminals/src/prompt.ts +14 -6
  11. package/extensions/background-terminals/src/result-delivery.ts +4 -1
  12. package/extensions/background-terminals/src/ui/ps.ts +132 -129
  13. package/extensions/capabilities/index.ts +30 -42
  14. package/extensions/capabilities/src/ui.ts +93 -0
  15. package/extensions/clear-context/index.ts +83 -0
  16. package/extensions/context-pivot/index.ts +16 -6
  17. package/extensions/cron/schedule.ts +7 -1
  18. package/extensions/file-mutation-display/index.ts +34 -76
  19. package/extensions/file-mutation-display/render.ts +146 -87
  20. package/extensions/file-search/index.ts +8 -7
  21. package/extensions/file-search/src/binaries.ts +75 -59
  22. package/extensions/git-info/src/changed-files-view.ts +47 -14
  23. package/extensions/git-read/index.ts +328 -0
  24. package/extensions/git-read/src/args.ts +171 -0
  25. package/extensions/git-read/src/process.ts +81 -0
  26. package/extensions/git-read/src/prompt.ts +56 -0
  27. package/extensions/model-info/index.ts +21 -33
  28. package/extensions/model-info/session-metrics.ts +96 -0
  29. package/extensions/plan-mode/bash-policy.ts +54 -9
  30. package/extensions/plan-mode/index.ts +7 -2
  31. package/extensions/post-edit/index.ts +16 -6
  32. package/extensions/sessions/git-stats.ts +258 -72
  33. package/extensions/sessions/index.ts +222 -140
  34. package/extensions/sessions/preview-cache.ts +104 -0
  35. package/extensions/sessions/preview-loader.ts +856 -0
  36. package/extensions/sessions/sessions.ts +43 -4
  37. package/extensions/setup/index.ts +127 -131
  38. package/extensions/shared/activity-status.ts +36 -5
  39. package/extensions/shared/agent-session-page.ts +319 -0
  40. package/extensions/shared/agent-tool-renderer.ts +218 -0
  41. package/extensions/shared/agent-transcript.ts +524 -0
  42. package/extensions/shared/below-editor-navigation.ts +26 -0
  43. package/extensions/shared/capability-intent.ts +53 -0
  44. package/extensions/shared/child-session.ts +444 -22
  45. package/extensions/shared/result-budget.ts +134 -0
  46. package/extensions/shared/result-delivery.ts +34 -0
  47. package/extensions/shared/screen-chrome.ts +133 -0
  48. package/extensions/shared/setup-config.ts +97 -38
  49. package/extensions/shared/setup-episode-state.ts +1 -1
  50. package/extensions/shared/spinner.ts +28 -0
  51. package/extensions/shared/terminal-text.ts +110 -23
  52. package/extensions/shared/text-projection.ts +113 -0
  53. package/extensions/shared/tool-activity.ts +382 -0
  54. package/extensions/shared/tool-surface.ts +42 -8
  55. package/extensions/shared/transcript-viewport.ts +46 -0
  56. package/extensions/shared/web-observer-registry.ts +390 -0
  57. package/extensions/shared/worktree.ts +11 -0
  58. package/extensions/subagents/index.ts +461 -186
  59. package/extensions/subagents/navigation.ts +86 -28
  60. package/extensions/subagents/src/agent-types.ts +37 -15
  61. package/extensions/subagents/src/backend.ts +12 -1
  62. package/extensions/subagents/src/backends/pi.ts +375 -66
  63. package/extensions/subagents/src/domain.ts +5 -0
  64. package/extensions/subagents/src/id-sequence.ts +84 -0
  65. package/extensions/subagents/src/manager.ts +651 -536
  66. package/extensions/subagents/src/prompt.ts +185 -42
  67. package/extensions/subagents/src/result-artifact.ts +146 -0
  68. package/extensions/subagents/src/result-delivery.ts +7 -1
  69. package/extensions/subagents/src/runtime.ts +23 -6
  70. package/extensions/subagents/src/ui/takeover.ts +128 -337
  71. package/extensions/subagents/src/ui/transcript.ts +38 -501
  72. package/extensions/subagents/src/ui/wait-result.ts +103 -15
  73. package/extensions/suggestions/src/ui.ts +10 -4
  74. package/extensions/tasks/index.ts +0 -3
  75. package/extensions/tasks/ui.ts +79 -62
  76. package/extensions/ui-customization/footer.ts +7 -44
  77. package/extensions/ui-customization/index.ts +0 -4
  78. package/extensions/user-input-fold/index.ts +185 -0
  79. package/extensions/web/index.ts +234 -0
  80. package/extensions/workflows/artifacts.ts +147 -22
  81. package/extensions/workflows/completion-projection.ts +457 -0
  82. package/extensions/workflows/controller.ts +14 -2
  83. package/extensions/workflows/coordinator.ts +62 -0
  84. package/extensions/workflows/dashboard.ts +458 -339
  85. package/extensions/workflows/handoff.ts +121 -25
  86. package/extensions/workflows/index.ts +1042 -492
  87. package/extensions/workflows/journal.ts +148 -13
  88. package/extensions/workflows/model.ts +131 -19
  89. package/extensions/workflows/navigation.ts +61 -18
  90. package/extensions/workflows/progress-projection.ts +306 -0
  91. package/extensions/workflows/prompt.ts +166 -10
  92. package/extensions/workflows/replay-safety.ts +58 -27
  93. package/extensions/workflows/result-delivery.ts +253 -0
  94. package/extensions/workflows/retention.ts +593 -0
  95. package/extensions/workflows/runner.ts +388 -279
  96. package/extensions/workflows/sandbox-child.cjs +36 -3
  97. package/extensions/workflows/sandbox.ts +62 -8
  98. package/extensions/workflows/serialization.ts +325 -17
  99. package/extensions/workflows/tool-renderer.ts +22 -0
  100. package/extensions/workflows/transcript.ts +149 -0
  101. package/extensions/workspace-cleanup-guard/index.ts +54 -0
  102. package/extensions/workspace-cleanup-guard/workspace-provenance.ts +563 -0
  103. package/package.json +28 -8
  104. package/skills/subagents/REFERENCE.md +189 -0
  105. package/skills/subagents/SKILL.md +2 -2
  106. package/skills/workflows/REFERENCE.md +10 -5
  107. package/skills/workflows/SKILL.md +53 -10
  108. package/web/adapter/pi-adapter.ts +661 -0
  109. package/web/host/browser-launcher.ts +20 -0
  110. package/web/host/static-assets.ts +4 -0
  111. package/web/host/terminal-status.ts +38 -0
  112. package/web/host/web-host.ts +789 -0
  113. package/web/http-dispatcher.ts +125 -0
  114. package/web/protocol/types.ts +462 -0
  115. package/web/runtime/pi-runtime.ts +991 -0
  116. package/web/runtime/types.ts +71 -0
  117. package/web/runtime/web-host-lease.ts +497 -0
  118. package/web/trace.ts +18 -0
  119. package/web/ui/app.js +1398 -0
  120. package/web/ui/index.html +139 -0
  121. package/web/ui/styles.css +598 -0
  122. package/web/vite.config.mjs +34 -0
  123. package/extensions/execution-convergence/active-evidence.ts +0 -129
  124. package/extensions/execution-convergence/index.ts +0 -442
  125. package/extensions/execution-convergence/workspace-provenance.ts +0 -338
  126. package/extensions/setup/intercom-fs-helper.cjs +0 -130
  127. package/extensions/setup/intercom.ts +0 -603
  128. package/extensions/subagents/src/backends/stub.ts +0 -296
  129. package/extensions/subagents/src/format.ts +0 -48
@@ -0,0 +1,253 @@
1
+ import type { WorkflowDetails } from "./model.ts";
2
+ import type {
3
+ DurableResultDeliveryQueue,
4
+ DurableResultDeliveryReceipt,
5
+ } from "../shared/result-delivery.ts";
6
+
7
+ export interface WorkflowCompletionEnvelope {
8
+ deliveryId: string;
9
+ runId: string;
10
+ details: WorkflowDetails;
11
+ }
12
+
13
+ export interface WorkflowResultDeliveryOptions {
14
+ isIdle: () => boolean;
15
+ persist: (details: WorkflowDetails) => void;
16
+ deliver: (
17
+ envelopes: readonly WorkflowCompletionEnvelope[],
18
+ wake: boolean,
19
+ ) => Promise<readonly DurableResultDeliveryReceipt[]>;
20
+ }
21
+
22
+ function errorText(error: unknown) {
23
+ return error instanceof Error ? error.message : String(error);
24
+ }
25
+
26
+ /**
27
+ * Durable, per-run workflow completion delivery.
28
+ *
29
+ * Execution status remains authoritative in WorkflowDetails. This module owns
30
+ * only the orthogonal delivery plane. A transport batch is an optimization:
31
+ * every run keeps its own stable delivery id and receipt so partial success
32
+ * can be retried without duplicating siblings.
33
+ */
34
+ export function createWorkflowResultDelivery(
35
+ options: WorkflowResultDeliveryOptions,
36
+ ) {
37
+ const pending = new Map<string, WorkflowCompletionEnvelope>();
38
+ let flushing: Promise<void> | undefined;
39
+ let flushRequested = false;
40
+ let wakeRequested = false;
41
+
42
+ const persistState = (
43
+ details: WorkflowDetails,
44
+ state: NonNullable<WorkflowDetails["delivery"]>["state"],
45
+ patch: Partial<NonNullable<WorkflowDetails["delivery"]>> = {},
46
+ ) => {
47
+ const delivery = details.delivery;
48
+ if (!delivery) throw new Error("Workflow delivery identity is missing");
49
+ const next = {
50
+ ...delivery,
51
+ ...patch,
52
+ state,
53
+ updatedAt: Date.now(),
54
+ };
55
+ if (patch.lastError === undefined) delete next.lastError;
56
+ details.delivery = next;
57
+ options.persist(details);
58
+ };
59
+
60
+ const enqueue = (envelope: WorkflowCompletionEnvelope) => {
61
+ pending.set(envelope.deliveryId, envelope);
62
+ };
63
+
64
+ const retainPending = (
65
+ envelope: WorkflowCompletionEnvelope,
66
+ patch: Partial<NonNullable<WorkflowDetails["delivery"]>>,
67
+ persistenceFailure: string,
68
+ ) => {
69
+ // Memory owns the retry before persistence is attempted. A broken disk
70
+ // must not make this envelope, or any sibling after it, disappear from the
71
+ // current process.
72
+ enqueue(envelope);
73
+ try {
74
+ persistState(envelope.details, "pending", patch);
75
+ } catch (error) {
76
+ const delivery = envelope.details.delivery;
77
+ if (delivery) {
78
+ envelope.details.delivery = {
79
+ ...delivery,
80
+ state: "pending",
81
+ updatedAt: Date.now(),
82
+ lastError: `${persistenceFailure}: ${errorText(error)}`,
83
+ };
84
+ }
85
+ }
86
+ };
87
+
88
+ const flush = async (wake: boolean) => {
89
+ if (flushing) {
90
+ flushRequested = true;
91
+ wakeRequested ||= wake;
92
+ return flushing;
93
+ }
94
+ if (pending.size === 0) return;
95
+
96
+ flushing = (async () => {
97
+ let passWake = wake;
98
+ while (pending.size > 0) {
99
+ flushRequested = false;
100
+ wakeRequested = false;
101
+ const envelopes = [...pending.values()];
102
+ for (const envelope of envelopes) {
103
+ pending.delete(envelope.deliveryId);
104
+ }
105
+
106
+ let receipts: readonly DurableResultDeliveryReceipt[] | undefined;
107
+ try {
108
+ receipts = await options.deliver(envelopes, passWake);
109
+ } catch (error) {
110
+ const message = errorText(error);
111
+ for (const envelope of envelopes) {
112
+ retainPending(
113
+ envelope,
114
+ {
115
+ attempts: (envelope.details.delivery?.attempts ?? 0) + 1,
116
+ lastError: message,
117
+ },
118
+ "Pending delivery persistence failed",
119
+ );
120
+ }
121
+ }
122
+
123
+ if (receipts !== undefined) {
124
+ const byId = new Map(
125
+ receipts.map((receipt) => [receipt.deliveryId, receipt] as const),
126
+ );
127
+ for (const envelope of envelopes) {
128
+ const receipt = byId.get(envelope.deliveryId);
129
+ if (receipt?.delivered) {
130
+ try {
131
+ persistState(envelope.details, "delivered", {
132
+ attempts: (envelope.details.delivery?.attempts ?? 0) + 1,
133
+ deliveredAt: Date.now(),
134
+ lastError: undefined,
135
+ });
136
+ } catch (error) {
137
+ // The transport already accepted the message, but the durable
138
+ // receipt did not commit. Retain it for at-least-once recovery;
139
+ // the visible stable id lets the parent recognize a rare replay.
140
+ enqueue(envelope);
141
+ const delivery = envelope.details.delivery;
142
+ if (delivery) {
143
+ envelope.details.delivery = {
144
+ ...delivery,
145
+ state: "pending",
146
+ updatedAt: Date.now(),
147
+ lastError: `Delivery receipt persistence failed: ${errorText(error)}`,
148
+ };
149
+ }
150
+ }
151
+ continue;
152
+ }
153
+ retainPending(
154
+ envelope,
155
+ {
156
+ attempts: (envelope.details.delivery?.attempts ?? 0) + 1,
157
+ lastError:
158
+ receipt?.error ?? "Completion delivery was not acknowledged",
159
+ },
160
+ "Pending delivery persistence failed",
161
+ );
162
+ }
163
+ }
164
+
165
+ // A completion or lifecycle edge joined this pass while transport was
166
+ // in flight. Drain once more so that request is not lost. Failures
167
+ // retained above do not request their own immediate retry, preventing
168
+ // an unavailable transport from creating a busy loop.
169
+ if (!flushRequested) break;
170
+ passWake ||= wakeRequested;
171
+ }
172
+ })().finally(() => {
173
+ flushing = undefined;
174
+ });
175
+ return flushing;
176
+ };
177
+
178
+ const queue = {
179
+ /** Register inline interest before the run starts. */
180
+ holdInline(details: WorkflowDetails) {
181
+ persistState(details, "held-for-inline");
182
+ },
183
+
184
+ /** Terminal won the wait/abort arbitration and will be returned inline. */
185
+ consumeInline(details: WorkflowDetails) {
186
+ if (details.delivery) pending.delete(details.delivery.id);
187
+ persistState(details, "consumed-inline", {
188
+ deliveredAt: Date.now(),
189
+ lastError: undefined,
190
+ });
191
+ },
192
+
193
+ /** Abort won the wait/terminal arbitration; deliver the result later. */
194
+ releaseInline(envelope: WorkflowCompletionEnvelope) {
195
+ retainPending(
196
+ envelope,
197
+ { lastError: undefined },
198
+ "Initial delivery persistence failed",
199
+ );
200
+ if (options.isIdle()) void flush(true);
201
+ },
202
+
203
+ /** Queue a detached run with in-memory retry ownership before persistence. */
204
+ defer(envelope: WorkflowCompletionEnvelope) {
205
+ retainPending(
206
+ envelope,
207
+ { lastError: undefined },
208
+ "Initial delivery persistence failed",
209
+ );
210
+ if (options.isIdle()) void flush(true);
211
+ },
212
+
213
+ /** Restore only explicitly pending/held new-format runs. */
214
+ restore(envelope: WorkflowCompletionEnvelope) {
215
+ const state = envelope.details.delivery?.state;
216
+ if (state !== "pending" && state !== "held-for-inline") return false;
217
+ // A process restart cannot still own the inline waiter. Deterministically
218
+ // reconstruct pending delivery from the terminal artifact.
219
+ if (state === "held-for-inline") {
220
+ retainPending(
221
+ envelope,
222
+ { lastError: "Inline waiter was not active after session restart" },
223
+ "Restored delivery state persistence failed",
224
+ );
225
+ } else {
226
+ enqueue(envelope);
227
+ }
228
+ return true;
229
+ },
230
+
231
+ retryPending() {
232
+ return flush(true) ?? Promise.resolve();
233
+ },
234
+
235
+ parentSettled() {
236
+ return flush(true);
237
+ },
238
+
239
+ flushIfIdle() {
240
+ if (!options.isIdle()) return Promise.resolve();
241
+ return flush(true) ?? Promise.resolve();
242
+ },
243
+
244
+ size() {
245
+ return pending.size;
246
+ },
247
+
248
+ clear() {
249
+ pending.clear();
250
+ },
251
+ };
252
+ return queue satisfies DurableResultDeliveryQueue<WorkflowCompletionEnvelope>;
253
+ }