@nuanu-ai/agentbrowse 0.2.49 → 0.2.50

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 (51) hide show
  1. package/README.md +22 -7
  2. package/dist/agentpay-gateway.d.ts +1 -0
  3. package/dist/agentpay-gateway.d.ts.map +1 -1
  4. package/dist/agentpay-gateway.js +4 -1
  5. package/dist/commands/act.d.ts.map +1 -1
  6. package/dist/commands/act.js +46 -61
  7. package/dist/commands/action-acceptance.d.ts +3 -7
  8. package/dist/commands/action-acceptance.d.ts.map +1 -1
  9. package/dist/commands/action-acceptance.js +8 -25
  10. package/dist/commands/browser-status.d.ts +6 -0
  11. package/dist/commands/browser-status.d.ts.map +1 -0
  12. package/dist/commands/browser-status.js +228 -0
  13. package/dist/commands/close.d.ts.map +1 -1
  14. package/dist/commands/close.js +35 -30
  15. package/dist/commands/end-session.d.ts +1 -1
  16. package/dist/commands/end-session.d.ts.map +1 -1
  17. package/dist/commands/end-session.js +3 -1
  18. package/dist/commands/launch.d.ts.map +1 -1
  19. package/dist/commands/launch.js +32 -25
  20. package/dist/commands/observe-projection.d.ts +2 -1
  21. package/dist/commands/observe-projection.d.ts.map +1 -1
  22. package/dist/commands/observe-projection.js +12 -1
  23. package/dist/commands/observe.d.ts.map +1 -1
  24. package/dist/commands/observe.js +62 -92
  25. package/dist/commands/start-session.d.ts.map +1 -1
  26. package/dist/commands/start-session.js +15 -11
  27. package/dist/commands/status.d.ts +22 -2
  28. package/dist/commands/status.d.ts.map +1 -1
  29. package/dist/commands/status.js +36 -215
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +16 -9
  32. package/dist/otel-exporter.d.ts.map +1 -1
  33. package/dist/otel-exporter.js +5 -11
  34. package/dist/run-store.d.ts +1 -1
  35. package/dist/run-store.d.ts.map +1 -1
  36. package/dist/run-store.js +3 -7
  37. package/dist/secrets/backend.d.ts +0 -1
  38. package/dist/secrets/backend.d.ts.map +1 -1
  39. package/dist/secrets/backend.js +0 -1
  40. package/dist/session-event-exporter.d.ts +1 -3
  41. package/dist/session-event-exporter.d.ts.map +1 -1
  42. package/dist/session-event-exporter.js +1 -14
  43. package/dist/sessions-backend.d.ts +20 -26
  44. package/dist/sessions-backend.d.ts.map +1 -1
  45. package/dist/sessions-backend.js +5 -5
  46. package/dist/solver/captcha-solver.d.ts.map +1 -1
  47. package/dist/solver/captcha-solver.js +12 -8
  48. package/dist/workflow-session-completion.d.ts +1 -1
  49. package/dist/workflow-session-completion.d.ts.map +1 -1
  50. package/dist/workflow-session-completion.js +23 -3
  51. package/package.json +1 -1
@@ -25,6 +25,30 @@ import { buildGroupedObserveScopes, buildGoalProjectionScopeRefs, buildGoalObser
25
25
  import { collectSurfaceDescriptors, selectScopesForOutput } from './observe-surfaces.js';
26
26
  import { toStagehandDescriptor } from './observe-stagehand.js';
27
27
  import { rerankDomTargetsForGoal } from './semantic-observe.js';
28
+ function flattenObserveTargets(scopes) {
29
+ if (!Array.isArray(scopes)) {
30
+ return [];
31
+ }
32
+ return scopes.flatMap((scope) => {
33
+ if (!scope || typeof scope !== 'object' || Array.isArray(scope)) {
34
+ return [];
35
+ }
36
+ const typedScope = scope;
37
+ return Array.isArray(typedScope.targets) ? typedScope.targets : [];
38
+ });
39
+ }
40
+ function withObserveCounts(payload) {
41
+ const explicitTargets = Array.isArray(payload.targets) ? payload.targets : [];
42
+ const scopeTargets = flattenObserveTargets(payload.scopes);
43
+ const targets = explicitTargets.length > 0 || Array.isArray(payload.targets) ? explicitTargets : scopeTargets;
44
+ const scopeCount = Array.isArray(payload.scopes) ? payload.scopes.length : 0;
45
+ return {
46
+ ...payload,
47
+ targetCount: targets.length,
48
+ scopeCount,
49
+ projectedTargetCount: targets.length,
50
+ };
51
+ }
28
52
  function finalizeObserveStepBestEffort(runId, stepId, options) {
29
53
  if (!runId || !stepId) {
30
54
  return;
@@ -39,30 +63,39 @@ function finalizeObserveStepBestEffort(runId, stepId, options) {
39
63
  catch { }
40
64
  }
41
65
  async function emitObserveSuccess(session, step, payload) {
66
+ const normalizedPayload = withObserveCounts(payload);
42
67
  captureStepSnapshotBestEffort({
43
68
  session,
44
69
  step,
45
70
  phase: 'after',
46
- pageRef: typeof payload.pageRef === 'string' ? payload.pageRef : session.runtime?.currentPageRef,
47
- url: typeof payload.url === 'string' ? payload.url : undefined,
48
- title: typeof payload.title === 'string' ? payload.title : undefined,
71
+ pageRef: typeof normalizedPayload.pageRef === 'string'
72
+ ? normalizedPayload.pageRef
73
+ : session.runtime?.currentPageRef,
74
+ url: typeof normalizedPayload.url === 'string' ? normalizedPayload.url : undefined,
75
+ title: typeof normalizedPayload.title === 'string' ? normalizedPayload.title : undefined,
49
76
  });
50
77
  appendCommandLifecycleEventBestEffort({
51
78
  step,
52
79
  phase: 'completed',
53
80
  attributes: {
54
81
  outcomeType: 'observation_completed',
55
- ...(typeof payload.pageRef === 'string' ? { pageRef: payload.pageRef } : {}),
56
- ...(typeof payload.resolvedBy === 'string' ? { resolvedBy: payload.resolvedBy } : {}),
82
+ ...(typeof normalizedPayload.pageRef === 'string'
83
+ ? { pageRef: normalizedPayload.pageRef }
84
+ : {}),
85
+ ...(typeof normalizedPayload.resolvedBy === 'string'
86
+ ? { resolvedBy: normalizedPayload.resolvedBy }
87
+ : {}),
57
88
  },
58
89
  });
59
90
  finalizeObserveStepBestEffort(step?.runId, step?.stepId, {
60
91
  success: true,
61
92
  outcomeType: 'observation_completed',
62
- message: typeof payload.message === 'string' ? payload.message : 'Observe completed.',
93
+ message: typeof normalizedPayload.message === 'string'
94
+ ? normalizedPayload.message
95
+ : 'Observe completed.',
63
96
  });
64
97
  await exportRunStepToOtlpHttpJsonBestEffort(step?.runId, step?.stepId);
65
- return outputJSON(payload);
98
+ return outputJSON(normalizedPayload);
66
99
  }
67
100
  async function emitObserveContractFailure(session, params) {
68
101
  const step = params.runId && params.stepId
@@ -146,44 +179,26 @@ export async function observe(session, instruction) {
146
179
  };
147
180
  if (!instruction) {
148
181
  try {
149
- browser = await tracedStepOperation(() => connectPlaywright(session.cdpUrl), {
150
- spanName: 'agentbrowse.observe.connect_browser',
151
- attributes: observePhaseAttributes,
152
- });
153
- const resolvedPage = await tracedStepOperation(() => resolveCurrentPageContext(browser, session), {
154
- spanName: 'agentbrowse.observe.resolve_page_context',
155
- attributes: observePhaseAttributes,
156
- });
182
+ browser = await connectPlaywright(session.cdpUrl);
183
+ const resolvedPage = await resolveCurrentPageContext(browser, session);
157
184
  pageRef = resolvedPage.pageRef;
158
185
  const page = resolvedPage.page;
159
- const { url, title } = await tracedStepOperation(() => syncSessionPage(session, pageRef, page), {
160
- spanName: 'agentbrowse.observe.sync_session_page',
161
- attributes: observePhaseAttributes,
162
- });
186
+ const { url, title } = await syncSessionPage(session, pageRef, page);
163
187
  bumpPageScopeEpoch(session, pageRef);
164
188
  setCurrentPage(session, pageRef);
165
- const collectedTargets = await tracedStepOperation(() => collectDomTargets(page), {
166
- spanName: 'agentbrowse.observe.collect_dom_targets',
167
- attributes: observePhaseAttributes,
168
- });
189
+ const collectedTargets = await collectDomTargets(page);
169
190
  let observeAccessibilityStats;
170
- const domTargets = compressSemanticallyDuplicateTargets(orderBySurfaceCompetition(annotateDomTargets(await tracedStepOperation(() => enrichDomTargetsWithAccessibility(page, collectedTargets, {
191
+ const domTargets = compressSemanticallyDuplicateTargets(orderBySurfaceCompetition(annotateDomTargets(await enrichDomTargetsWithAccessibility(page, collectedTargets, {
171
192
  onStats: (stats) => {
172
193
  observeAccessibilityStats = stats;
173
194
  },
174
- }), {
175
- spanName: 'agentbrowse.observe.enrich_accessibility',
176
- attributes: observePhaseAttributes,
177
195
  }))));
178
196
  if (observeAccessibilityStats) {
179
197
  incrementMetric(session, 'observeAxAttempts', observeAccessibilityStats.axAttempts);
180
198
  incrementMetric(session, 'observeAxHits', observeAccessibilityStats.axHits);
181
199
  incrementMetric(session, 'observeFallbackUses', observeAccessibilityStats.fallbackUses);
182
200
  }
183
- const signals = compactSignals(await tracedStepOperation(() => collectPageSignals(page).catch(() => []), {
184
- spanName: 'agentbrowse.observe.collect_page_signals',
185
- attributes: observePhaseAttributes,
186
- }));
201
+ const signals = compactSignals(await collectPageSignals(page).catch(() => []));
187
202
  const pageState = classifyObservePageState(signals);
188
203
  const persisted = persistObservedSurfacesForPage(session, pageRef, domTargets);
189
204
  observedScopes = persisted.observedScopes;
@@ -195,13 +210,7 @@ export async function observe(session, instruction) {
195
210
  observedScopes = linkObservedSurfaceGraph(session, pageRef, domTargets, targets, observedScopes, surfaceRefMap);
196
211
  const fillableForms = shouldSuppressFillableFormsForObserve(pageState)
197
212
  ? clearProtectedFillableFormsForPage(session, pageRef)
198
- : await tracedStepOperation(() => persistProtectedFillableFormsForPage(session, pageRef, url, targets, new Date().toISOString()), {
199
- spanName: 'agentbrowse.observe.persist_fillable_forms',
200
- attributes: {
201
- ...observePhaseAttributes,
202
- 'agentbrowse.observe.target_count': targets.length,
203
- },
204
- });
213
+ : await persistProtectedFillableFormsForPage(session, pageRef, url, targets, new Date().toISOString());
205
214
  saveSession(session);
206
215
  await disconnectPlaywright(browser);
207
216
  browser = null;
@@ -219,7 +228,7 @@ export async function observe(session, instruction) {
219
228
  signals,
220
229
  fillableForms: compactFillableForms(fillableForms),
221
230
  metrics: session.runtime?.metrics,
222
- message: targets.length === 0 ? 'No targets found.' : undefined,
231
+ message: targets.length === 0 ? 'This observe pass returned zero targets.' : undefined,
223
232
  url,
224
233
  title,
225
234
  });
@@ -234,47 +243,29 @@ export async function observe(session, instruction) {
234
243
  if (instruction) {
235
244
  try {
236
245
  if (!browser) {
237
- browser = await tracedStepOperation(() => connectPlaywright(session.cdpUrl), {
238
- spanName: 'agentbrowse.observe.connect_browser',
239
- attributes: observePhaseAttributes,
240
- });
246
+ browser = await connectPlaywright(session.cdpUrl);
241
247
  }
242
- const resolvedPage = await tracedStepOperation(() => resolveCurrentPageContext(browser, session), {
243
- spanName: 'agentbrowse.observe.resolve_page_context',
244
- attributes: observePhaseAttributes,
245
- });
248
+ const resolvedPage = await resolveCurrentPageContext(browser, session);
246
249
  pageRef = resolvedPage.pageRef;
247
250
  const page = resolvedPage.page;
248
- const { url, title } = await tracedStepOperation(() => syncSessionPage(session, pageRef, page), {
249
- spanName: 'agentbrowse.observe.sync_session_page',
250
- attributes: observePhaseAttributes,
251
- });
251
+ const { url, title } = await syncSessionPage(session, pageRef, page);
252
252
  bumpPageScopeEpoch(session, pageRef);
253
253
  setCurrentPage(session, pageRef);
254
- const collectedTargets = await tracedStepOperation(() => collectDomTargets(page, {
254
+ const collectedTargets = await collectDomTargets(page, {
255
255
  includeActivationAffordances: true,
256
- }), {
257
- spanName: 'agentbrowse.observe.collect_dom_targets',
258
- attributes: observePhaseAttributes,
259
256
  });
260
257
  let observeAccessibilityStats;
261
- const domTargets = compressSemanticallyDuplicateTargets(orderBySurfaceCompetition(annotateDomTargets(await tracedStepOperation(() => enrichDomTargetsWithAccessibility(page, collectedTargets, {
258
+ const domTargets = compressSemanticallyDuplicateTargets(orderBySurfaceCompetition(annotateDomTargets(await enrichDomTargetsWithAccessibility(page, collectedTargets, {
262
259
  onStats: (stats) => {
263
260
  observeAccessibilityStats = stats;
264
261
  },
265
- }), {
266
- spanName: 'agentbrowse.observe.enrich_accessibility',
267
- attributes: observePhaseAttributes,
268
262
  }))));
269
263
  if (observeAccessibilityStats) {
270
264
  incrementMetric(session, 'observeAxAttempts', observeAccessibilityStats.axAttempts);
271
265
  incrementMetric(session, 'observeAxHits', observeAccessibilityStats.axHits);
272
266
  incrementMetric(session, 'observeFallbackUses', observeAccessibilityStats.fallbackUses);
273
267
  }
274
- const signals = compactSignals(await tracedStepOperation(() => collectPageSignals(page).catch(() => []), {
275
- spanName: 'agentbrowse.observe.collect_page_signals',
276
- attributes: observePhaseAttributes,
277
- }));
268
+ const signals = compactSignals(await collectPageSignals(page).catch(() => []));
278
269
  const pageState = classifyObservePageState(signals);
279
270
  const surfaceInputs = collectSurfaceDescriptors(pageRef, domTargets);
280
271
  if (domTargets.length > 0) {
@@ -299,13 +290,7 @@ export async function observe(session, instruction) {
299
290
  observedScopes = linkObservedSurfaceGraph(session, pageRef, domTargets, targets, observedScopes, surfaceRefMap);
300
291
  const fillableForms = shouldSuppressFillableFormsForObserve(pageState)
301
292
  ? clearProtectedFillableFormsForPage(session, pageRef)
302
- : await tracedStepOperation(() => persistProtectedFillableFormsForPage(session, pageRef, url, targets, new Date().toISOString()), {
303
- spanName: 'agentbrowse.observe.persist_fillable_forms',
304
- attributes: {
305
- ...observePhaseAttributes,
306
- 'agentbrowse.observe.target_count': targets.length,
307
- },
308
- });
293
+ : await persistProtectedFillableFormsForPage(session, pageRef, url, targets, new Date().toISOString());
309
294
  if (selectedTargets.length > 0 || selectedSurfaceIds.size > 0) {
310
295
  const projectedTargets = projectPersistedTargetsForGoal(domTargets, targets, selectedTargets);
311
296
  const explicitScopeRefs = buildGoalProjectionScopeRefs(projectedTargets, selectedSurfaceIds, surfaceRefMap);
@@ -342,7 +327,7 @@ export async function observe(session, instruction) {
342
327
  signals,
343
328
  fillableForms: compactFillableForms(fillableForms),
344
329
  metrics: session.runtime?.metrics,
345
- message: 'No targets matched the requested goal.',
330
+ message: 'This goal-based observe pass returned zero matching targets.',
346
331
  url,
347
332
  title,
348
333
  });
@@ -356,10 +341,7 @@ export async function observe(session, instruction) {
356
341
  }
357
342
  try {
358
343
  if (!browser) {
359
- browser = await tracedStepOperation(() => connectPlaywright(session.cdpUrl), {
360
- spanName: 'agentbrowse.observe.connect_browser',
361
- attributes: observePhaseAttributes,
362
- });
344
+ browser = await connectPlaywright(session.cdpUrl);
363
345
  }
364
346
  }
365
347
  catch (err) {
@@ -375,30 +357,18 @@ export async function observe(session, instruction) {
375
357
  });
376
358
  }
377
359
  try {
378
- const resolvedPage = await tracedStepOperation(() => resolveCurrentPageContext(browser, session), {
379
- spanName: 'agentbrowse.observe.resolve_page_context',
380
- attributes: observePhaseAttributes,
381
- });
360
+ const resolvedPage = await resolveCurrentPageContext(browser, session);
382
361
  pageRef = resolvedPage.pageRef;
383
362
  const page = resolvedPage.page;
384
- const { url, title } = await tracedStepOperation(() => syncSessionPage(session, pageRef, page), {
385
- spanName: 'agentbrowse.observe.sync_session_page',
386
- attributes: observePhaseAttributes,
387
- });
363
+ const { url, title } = await syncSessionPage(session, pageRef, page);
388
364
  bumpPageScopeEpoch(session, pageRef);
389
365
  setCurrentPage(session, pageRef);
390
- const signals = compactSignals(await tracedStepOperation(() => collectPageSignals(page).catch(() => []), {
391
- spanName: 'agentbrowse.observe.collect_page_signals',
392
- attributes: observePhaseAttributes,
393
- }));
394
- const actions = await tracedStepOperation(() => withStagehand(session, async (stagehand) => {
366
+ const signals = compactSignals(await collectPageSignals(page).catch(() => []));
367
+ const actions = await withStagehand(session, async (stagehand) => {
395
368
  incrementMetric(session, 'stagehandCalls');
396
369
  return instruction
397
370
  ? (await stagehand.observe(instruction, { page }))
398
371
  : (await stagehand.observe({ page }));
399
- }), {
400
- spanName: 'agentbrowse.observe.stagehand_observe',
401
- attributes: observePhaseAttributes,
402
372
  });
403
373
  const targets = replaceTargetsForPage(session, pageRef, await Promise.all(actions.map((action) => toStagehandDescriptor(pageRef, action, page, normalizePageSignature(url)))));
404
374
  const fillableForms = markProtectedFillableFormsUnknownForPage(session, pageRef);
@@ -418,7 +388,7 @@ export async function observe(session, instruction) {
418
388
  signals,
419
389
  fillableForms: compactFillableForms(fillableForms),
420
390
  metrics: session.runtime?.metrics,
421
- message: targets.length === 0 ? 'No targets found.' : undefined,
391
+ message: targets.length === 0 ? 'This observe pass returned zero targets.' : undefined,
422
392
  url,
423
393
  title,
424
394
  });
@@ -1 +1 @@
1
- {"version":3,"file":"start-session.d.ts","sourceRoot":"","sources":["../../src/commands/start-session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyBH,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EACD,6BAA6B,GAC7B,8BAA8B,GAC9B,8BAA8B,GAC9B,0BAA0B,GAC1B,2BAA2B,GAC3B,kCAAkC,CAAC;IACvC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;IAClC,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,GAAG,yBAAyB,CAAC;AAIvF,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAgLD,wBAAsB,YAAY,CAChC,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA4N7B"}
1
+ {"version":3,"file":"start-session.d.ts","sourceRoot":"","sources":["../../src/commands/start-session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyBH,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EACD,6BAA6B,GAC7B,8BAA8B,GAC9B,8BAA8B,GAC9B,0BAA0B,GAC1B,2BAA2B,GAC3B,kCAAkC,CAAC;IACvC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;IAClC,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,GAAG,yBAAyB,CAAC;AAIvF,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAqMD,wBAAsB,YAAY,CAChC,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA0N7B"}
@@ -2,7 +2,7 @@
2
2
  * browse start-session — Start the workflow/run context on top of an existing browser session.
3
3
  */
4
4
  import { info } from '../output.js';
5
- import { buildRunRootOtlpTraceRequest, buildRunStepOtlpTraceRequest, } from '../otel-exporter.js';
5
+ import { exportRunRootToOtlpHttpJsonBestEffort, exportRunStepToOtlpHttpJsonBestEffort, } from '../otel-exporter.js';
6
6
  import { appendCommandLifecycleEventBestEffort, captureStepSnapshotBestEffort, } from '../run-observability.js';
7
7
  import { finishRunRecord, finishRunStep, startCliRun, startRunStep } from '../run-store.js';
8
8
  import { createRemoteSession } from '../sessions-backend.js';
@@ -113,6 +113,12 @@ function finalizeRunRecordBestEffort(runId, options) {
113
113
  info(`[start-session] failed to finalize local run ${runId}: ${formatUnknownError(error)}`);
114
114
  }
115
115
  }
116
+ function isStalePreviousWorkflowCompletionFailure(error) {
117
+ return (error === 'workflow_session_unavailable' ||
118
+ error === 'workflow_session_already_closed' ||
119
+ error === 'workflow_run_unavailable' ||
120
+ error === 'workflow_step_unavailable');
121
+ }
116
122
  async function completePreviousWorkflowSessionIfNeeded(session) {
117
123
  if (!session.intentSessionId) {
118
124
  return null;
@@ -132,12 +138,14 @@ async function completePreviousWorkflowSessionIfNeeded(session) {
132
138
  if (remoteCompletion.success) {
133
139
  return null;
134
140
  }
141
+ if (isStalePreviousWorkflowCompletionFailure(remoteCompletion.error)) {
142
+ info(`[start-session] clearing stale previous workflow binding before creating a new session: ${remoteCompletion.reason}`);
143
+ return null;
144
+ }
135
145
  return {
136
146
  success: false,
137
- error: remoteCompletion.error === 'backend_session_complete_failed'
138
- ? 'workflow_session_complete_failed'
139
- : remoteCompletion.error,
140
- outcomeType: remoteCompletion.error === 'backend_session_complete_failed' ? 'failed' : 'blocked',
147
+ error: 'workflow_session_complete_failed',
148
+ outcomeType: 'failed',
141
149
  message: 'Session start failed.',
142
150
  reason: `Active workflow session cleanup blocked start-session: ${remoteCompletion.reason}`,
143
151
  };
@@ -239,7 +247,6 @@ export async function startSession(requestedName, options = {}) {
239
247
  : {}),
240
248
  run: {
241
249
  id: run.runId,
242
- trace_id: traceId,
243
250
  started_at: run.startedAt,
244
251
  source: run.source,
245
252
  status: run.status,
@@ -252,7 +259,6 @@ export async function startSession(requestedName, options = {}) {
252
259
  ordinal: step.ordinal,
253
260
  command: step.command,
254
261
  started_at: step.startedAt,
255
- span_id: spanId,
256
262
  ...(currentPageRef ? { page_ref: currentPageRef } : {}),
257
263
  },
258
264
  context: {
@@ -261,10 +267,6 @@ export async function startSession(requestedName, options = {}) {
261
267
  metadata: {
262
268
  had_previous_run: replacedPreviousRun,
263
269
  },
264
- telemetry: {
265
- root_trace: buildRunRootOtlpTraceRequest(run.runId) ?? undefined,
266
- step_trace: buildRunStepOtlpTraceRequest(run.runId, step.stepId) ?? undefined,
267
- },
268
270
  });
269
271
  nextSession.activeRunId = run.runId;
270
272
  nextSession.browserSessionId = resolveBrowserSessionId(nextSession);
@@ -296,6 +298,8 @@ export async function startSession(requestedName, options = {}) {
296
298
  outcomeType: 'workflow_session_started',
297
299
  message: 'Workflow session started.',
298
300
  });
301
+ await exportRunRootToOtlpHttpJsonBestEffort(run.runId);
302
+ await exportRunStepToOtlpHttpJsonBestEffort(run.runId, step.stepId);
299
303
  return {
300
304
  success: true,
301
305
  runId: run.runId,
@@ -1,6 +1,26 @@
1
1
  /**
2
- * browse status — Check browser state (alive, current URL, title).
2
+ * browse status — Check AgentPay gateway health and authenticated agent identity.
3
3
  */
4
4
  import type { BrowseResult } from '../output.js';
5
- export declare function status(): Promise<BrowseResult>;
5
+ import { type AgentBackendProfile } from '../sessions-backend.js';
6
+ type StatusSuccess = BrowseResult & {
7
+ success: true;
8
+ healthy: true;
9
+ message: 'AgentBrowse setup is healthy.';
10
+ apiUrl: string;
11
+ checkedEndpoint: string;
12
+ agent: AgentBackendProfile;
13
+ };
14
+ type StatusFailure = BrowseResult & {
15
+ success: false;
16
+ error: 'agent_status_failed';
17
+ outcomeType: 'blocked' | 'failed';
18
+ message: 'AgentBrowse status check failed.';
19
+ reason: string;
20
+ apiUrl: string;
21
+ checkedEndpoint: string;
22
+ httpStatus?: number;
23
+ };
24
+ export declare function status(): Promise<StatusSuccess | StatusFailure>;
25
+ export {};
6
26
  //# sourceMappingURL=status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA+LjD,wBAAsB,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC,CAwFpD"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAC;AAEhC,KAAK,aAAa,GAAG,YAAY,GAAG;IAClC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,+BAA+B,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,mBAAmB,CAAC;CAC5B,CAAC;AAEF,KAAK,aAAa,GAAG,YAAY,GAAG;IAClC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,qBAAqB,CAAC;IAC7B,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;IAClC,OAAO,EAAE,kCAAkC,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAuBF,wBAAsB,MAAM,IAAI,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC,CA8BrE"}