@linzumi/cli 1.0.150 → 1.0.152

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.
@@ -216,7 +216,15 @@ async function runSessionCase(caseInput) {
216
216
  }
217
217
  throw new Error(step.message ?? 'scripted snapshot failure');
218
218
  },
219
- onTurnTerminal: (turnId, outcome, reason, retryableEmptyTurn, autoResume, fate) => {
219
+ onTurnTerminal: (
220
+ turnId,
221
+ outcome,
222
+ reason,
223
+ retryableEmptyTurn,
224
+ autoResume,
225
+ fate,
226
+ freshSessionResume
227
+ ) => {
220
228
  trace.push({
221
229
  t: 'terminal',
222
230
  turnId,
@@ -224,6 +232,10 @@ async function runSessionCase(caseInput) {
224
232
  reason: reason ?? null,
225
233
  retryableEmptyTurn: retryableEmptyTurn === true,
226
234
  autoResumeMidStreamStall: autoResume === true,
235
+ // #3455 leg 4 (Greptile P2): the second-stall fresh-session flag is
236
+ // part of the compared terminal surface, so a future divergence in
237
+ // the ReScript reducer goes red here, not just in the TS e2e tests.
238
+ freshSessionResumeMidStreamStall: freshSessionResume === true,
227
239
  fate: fate ?? null,
228
240
  });
229
241
  },
@@ -66,6 +66,29 @@ import {
66
66
  terminalFailureRetryableStamp,
67
67
  } from './src/terminalFailureRetry';
68
68
  import { readLocalConfig, readLocalSignupAuth } from './src/localConfig';
69
+ import {
70
+ ADT_BINDING_ACK_EVENT,
71
+ ADT_FRAME_ENTRY_KIND,
72
+ ADT_FRAME_EVENT,
73
+ ADT_STREAM_BINDING_KEY,
74
+ ADT_STREAM_V1_CAPABILITY,
75
+ adoptAdtStreamBinding,
76
+ adtBindingRefusalMessage,
77
+ adtFrameContentDigest,
78
+ adtFrameEntryData,
79
+ adtFrameTelemetry,
80
+ adtFrameWirePayload,
81
+ adtObserveOutboxEntry,
82
+ adtRejectionTelemetry,
83
+ classifyAdtAppendRejection,
84
+ fenceAdtEmitter,
85
+ finishAdtStream,
86
+ makeAdtFrameEmitter,
87
+ parseAdtStreamBinding,
88
+ pollAdtInterval,
89
+ pushAdtDelta,
90
+ utf8ByteLength,
91
+ } from './src/pipeline/contracts';
69
92
 
70
93
  const jsonHelpers = {
71
94
  isJsonObject,
@@ -102,6 +125,27 @@ function outcome(run) {
102
125
  }
103
126
  }
104
127
 
128
+ // --- adt_stream_v1 (Part C CLI-first leg): the adt protocol core rides
129
+ // THIS oracle (its charter: the TS protocol modules; the zero-raw-JS
130
+ // ratchet forbids a new sibling .mjs). Case ops are namespaced 'adt*'
131
+ // where they would collide.
132
+ const adtRowEntryKinds = {
133
+ postStreamedRow: 'pipeline.post_streamed_row',
134
+ streamSnapshot: 'pipeline.stream_snapshot',
135
+ finalizeRow: 'pipeline.finalize_row',
136
+ postCompletedRow: 'pipeline.post_completed_row',
137
+ messageState: 'pipeline.message_state',
138
+ };
139
+
140
+ const adtFrameOut = (frame) =>
141
+ frame === null
142
+ ? null
143
+ : {
144
+ entryData: adtFrameEntryData(frame),
145
+ wirePayload: adtFrameWirePayload(frame),
146
+ telemetry: adtFrameTelemetry(frame),
147
+ };
148
+
105
149
  function handle(testCase) {
106
150
  switch (testCase.op) {
107
151
  case 'jsonHelper': {
@@ -159,6 +203,114 @@ function handle(testCase) {
159
203
  const signupAuth = outcome(() => readLocalSignupAuth(path));
160
204
  return { config, signupAuth };
161
205
  }
206
+ case 'adtConstants':
207
+ return {
208
+ capability: ADT_STREAM_V1_CAPABILITY,
209
+ bindingKey: ADT_STREAM_BINDING_KEY,
210
+ frameEvent: ADT_FRAME_EVENT,
211
+ bindingAckEvent: ADT_BINDING_ACK_EVENT,
212
+ frameEntryKind: ADT_FRAME_ENTRY_KIND,
213
+ };
214
+ case 'parseBinding': {
215
+ const parsed = parseAdtStreamBinding(testCase.value);
216
+ return parsed.ok
217
+ ? { ok: true, binding: parsed.binding }
218
+ : { ok: false, reason: parsed.reason };
219
+ }
220
+ case 'refusalMessage':
221
+ return { message: adtBindingRefusalMessage(testCase.reason) };
222
+ case 'adopt': {
223
+ const adoption = adoptAdtStreamBinding(
224
+ testCase.binding,
225
+ testCase.sourceSeq,
226
+ testCase.nowMs ?? 0
227
+ );
228
+ if (adoption.kind === 'accepted') {
229
+ return {
230
+ kind: 'accepted',
231
+ ackPayload: adoption.ackPayload,
232
+ sourceSeq: adoption.session.sourceSeq,
233
+ };
234
+ }
235
+ if (adoption.kind === 'refused') {
236
+ return { kind: 'refused', reason: adoption.reason, message: adoption.message };
237
+ }
238
+ return { kind: 'absent' };
239
+ }
240
+ case 'emitterRun': {
241
+ const parsed = parseAdtStreamBinding(testCase.binding);
242
+ if (!parsed.ok) {
243
+ return { refused: parsed.reason };
244
+ }
245
+ const emitter = makeAdtFrameEmitter(parsed.binding, testCase.startMs ?? 0);
246
+ const results = [];
247
+ for (const step of testCase.steps) {
248
+ switch (step.op) {
249
+ case 'delta':
250
+ results.push(adtFrameOut(pushAdtDelta(emitter, step.chunk, step.nowMs)));
251
+ break;
252
+ case 'poll':
253
+ results.push(adtFrameOut(pollAdtInterval(emitter, step.nowMs)));
254
+ break;
255
+ case 'finish':
256
+ results.push(adtFrameOut(finishAdtStream(emitter, step.nowMs)));
257
+ break;
258
+ case 'fence':
259
+ fenceAdtEmitter(emitter);
260
+ results.push(null);
261
+ break;
262
+ default:
263
+ results.push({ unknownStep: String(step.op) });
264
+ }
265
+ }
266
+ return {
267
+ results,
268
+ final: {
269
+ cumulative: emitter.cumulative,
270
+ nextFrameIndex: emitter.nextFrameIndex,
271
+ emittedFrameCount: emitter.emittedFrameCount,
272
+ terminalEmitted: emitter.terminalEmitted,
273
+ fenced: emitter.fenced,
274
+ },
275
+ };
276
+ }
277
+ case 'tapRun': {
278
+ const adoption = adoptAdtStreamBinding(
279
+ testCase.binding,
280
+ testCase.sourceSeq,
281
+ testCase.startMs ?? 0
282
+ );
283
+ if (adoption.kind !== 'accepted') {
284
+ return { adoption: adoption.kind };
285
+ }
286
+ const session = adoption.session;
287
+ const results = testCase.entries.map((entry) =>
288
+ adtObserveOutboxEntry(
289
+ session,
290
+ entry.kind,
291
+ entry.data,
292
+ entry.nowMs ?? 0,
293
+ adtRowEntryKinds
294
+ ).map((frame) => adtFrameOut(frame))
295
+ );
296
+ return {
297
+ results,
298
+ final: {
299
+ trackedItemKey: session.trackedItemKey ?? null,
300
+ lastBody: session.lastBody,
301
+ done: session.done,
302
+ },
303
+ };
304
+ }
305
+ case 'classifyRejection':
306
+ return { reason: classifyAdtAppendRejection(testCase.value) };
307
+ case 'rejectionTelemetry':
308
+ return adtRejectionTelemetry(testCase.frame, testCase.reason);
309
+ case 'digest':
310
+ return {
311
+ digest: adtFrameContentDigest(testCase.frame),
312
+ byteLen: utf8ByteLength(testCase.frame.body),
313
+ };
162
314
  default:
163
315
  return { threw: true, message: 'unknown op ' + String(testCase.op) };
164
316
  }