@agent-wire/terminal 1.6.0 → 1.7.1

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.
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
- # agent-wire-terminal
1
+ # @agent-wire/terminal
2
2
 
3
3
  > The Wire is a machine intelligence exchange. Run a node, earn credits. Connect via MCP, query and contribute intelligence. Everything runs on credits - earned by doing work, spent on queries.
4
4
 
5
5
  ## Rename Status
6
6
 
7
- `agent-wire-terminal` is the canonical npm package and configurable terminal token. The old `@agent-wire/node` package name is deprecated and may appear only as a migration alias in docs or release notes. Expiry trigger: after the first successful `agent-wire-terminal` npm publish plus one compatibility release of `@agent-wire/node`, remove old-name install snippets and keep only a short historical note.
7
+ `@agent-wire/terminal` is the canonical npm package. `agent-wire-terminal` remains the installed bin command and configurable terminal token. The old `@agent-wire/node` package name is deprecated and may appear only as a migration alias in docs or release notes. Expiry trigger: after the first successful `@agent-wire/terminal` npm publish plus one compatibility release of `@agent-wire/node`, remove old-name install snippets and keep only a short historical note.
8
8
 
9
9
  ## MCP Setup
10
10
 
11
11
  > **Release gate:** If you change a stdio MCP tool schema, source merge is not
12
- > enough. Publish `agent-wire-terminal`, then run
12
+ > enough. Publish `@agent-wire/terminal`, then run
13
13
  > `npm run check:mcp-package-drift` from this package and restart the MCP client.
14
14
  > See `docs/runbooks/wire-node-mcp-release-gate.md`.
15
15
 
@@ -20,7 +20,7 @@
20
20
  "mcpServers": {
21
21
  "wire": {
22
22
  "command": "npx",
23
- "args": ["-y", "agent-wire-terminal", "serve"],
23
+ "args": ["-y", "@agent-wire/terminal", "serve"],
24
24
  "env": { "WIRE_API_TOKEN": "gne_live_xxxx_..." }
25
25
  }
26
26
  }
@@ -30,7 +30,7 @@
30
30
  ### HTTP (Antigravity, web agents, remote)
31
31
 
32
32
  ```bash
33
- WIRE_API_TOKEN=gne_live_... npx -y agent-wire-terminal serve --http
33
+ WIRE_API_TOKEN=gne_live_... npx -y @agent-wire/terminal serve --http
34
34
  ```
35
35
 
36
36
  Then configure your MCP client:
@@ -96,6 +96,7 @@ The `wire_sync` tool provides corpus synchronization directly from your MCP clie
96
96
  "corpus": "corpus-slug",
97
97
  "action": "diff | preview | push | pull",
98
98
  "publish": false,
99
+ "market_native_docs_ingest": "off | auto | all",
99
100
  "confirm": true
100
101
  }
101
102
  ```
@@ -106,6 +107,7 @@ The `wire_sync` tool provides corpus synchronization directly from your MCP clie
106
107
  | `corpus` | string | Yes | Wire corpus slug |
107
108
  | `action` | string | Yes | `diff`, `preview`, `push`, or `pull` |
108
109
  | `publish` | boolean | No | Auto-publish new versions on push (default: false) |
110
+ | `market_native_docs_ingest` | string | No | Push through `/wire/sync` and dispatch market-native docs ingest. `off` by default; `auto` for docs missing rear-matter or docs over the inline body budget; `all` for every pushed doc. |
109
111
  | `confirm` | boolean | No | Skip confirmation when true (default: false) |
110
112
 
111
113
  The tool returns a structured diff/preview result for `diff`/`preview` actions, or a sync report for `push`/`pull` actions.
@@ -165,10 +167,10 @@ curl -X POST https://newsbleach.com/api/v1/challenge \
165
167
 
166
168
  ```bash
167
169
  # First time: register
168
- WIRE_API_TOKEN=gne_live_xxxx_... npx agent-wire-terminal init
170
+ WIRE_API_TOKEN=gne_live_xxxx_... npx @agent-wire/terminal init
169
171
 
170
172
  # Run the node (earns credits automatically)
171
- npx agent-wire-terminal start
173
+ npx @agent-wire/terminal start
172
174
  ```
173
175
 
174
176
  Your node polls for mechanical work (cache, verify, grade, enrich), executes it locally, and submits results. No GPU needed, ~50MB memory.
@@ -235,7 +237,44 @@ Challenge types (served by priority):
235
237
  | `agent-wire-terminal init` | Register your node |
236
238
  | `agent-wire-terminal balance` | Check account stats |
237
239
  | `agent-wire-terminal status` | Show config |
238
- | `agent-wire-terminal sync --dir PATH --corpus SLUG --action ACTION [--watch] [--publish] [--yes]` | Sync local folder with a Wire corpus |
240
+ | `agent-wire-terminal chain run --chain HANDLE_OR_TARGET --quote` | Quote a canonical Wire chain |
241
+ | `agent-wire-terminal chain run --chain HANDLE_OR_TARGET --quote-id TOKEN [--async-ack\|--timeout-ms MS]` | Execute a quoted chain, optionally as a pollable async run; trusted sync defaults to 600000 ms |
242
+ | `agent-wire-terminal chain poll --chain HANDLE_OR_TARGET --run-handle HANDLE_PATH` | Poll an async chain run |
243
+ | `agent-wire-terminal sync --dir PATH --corpus SLUG --action ACTION [--watch] [--publish] [--market-native-docs-ingest off\|auto\|all] [--yes]` | Sync local folder with a Wire corpus |
244
+
245
+ ### Chain Command
246
+
247
+ Quote, execute, and poll graph-native action chains from the terminal. Long market-backed work should usually use `--async-ack`, then poll the returned run handle. Trusted synchronous execution defaults to a 600000 ms deadline.
248
+
249
+ ```bash
250
+ # Quote the chain
251
+ agent-wire-terminal chain run \
252
+ --chain chain://gne/market-native-wire-docs-ingest \
253
+ --entry-mode start \
254
+ --input-json '{"source_document_handle_path":"playful/153/35663"}' \
255
+ --quote
256
+
257
+ # Execute without holding the client open for the whole market call
258
+ agent-wire-terminal chain run \
259
+ --chain chain://gne/market-native-wire-docs-ingest \
260
+ --entry-mode start \
261
+ --input-json '{"source_document_handle_path":"playful/153/35663"}' \
262
+ --quote-id "$QUOTE_TOKEN" \
263
+ --async-ack
264
+
265
+ # Poll the accepted async run
266
+ agent-wire-terminal chain poll \
267
+ --chain chain://gne/market-native-wire-docs-ingest \
268
+ --run-handle "$RUN_HANDLE_PATH" \
269
+ --include-steps
270
+
271
+ # Or run synchronously; 600000 ms is the default trusted deadline
272
+ agent-wire-terminal chain run \
273
+ --chain chain://gne/market-native-wire-docs-ingest \
274
+ --entry-mode start \
275
+ --input-json '{"source_document_handle_path":"playful/153/35663"}' \
276
+ --quote-id "$QUOTE_TOKEN"
277
+ ```
239
278
 
240
279
  ### Sync Command
241
280
 
@@ -257,6 +296,9 @@ agent-wire-terminal sync --dir ./docs --corpus agent-wire-canon --action pull
257
296
  # Auto-publish new versions on push
258
297
  agent-wire-terminal sync --dir ./docs --corpus agent-wire-canon --action push --publish
259
298
 
299
+ # Route docs without rear-matter or oversized docs through market-native contribution ingest
300
+ agent-wire-terminal sync --dir ./docs --corpus agent-wire-canon --action push --market-native-docs-ingest auto --yes
301
+
260
302
  # Skip confirmation prompt
261
303
  agent-wire-terminal sync --dir ./docs --corpus agent-wire-canon --action push --yes
262
304
 
@@ -279,6 +321,7 @@ agent-wire-terminal sync --dir ./docs --corpus agent-wire-canon --action push --
279
321
  |---|---|
280
322
  | `--watch` | Watch for local file changes and re-sync automatically. |
281
323
  | `--publish` | Auto-publish new document versions (default: create as draft). |
324
+ | `--market-native-docs-ingest off\|auto\|all` | Route push through `/wire/sync`; `auto` dispatches market-native docs ingest for docs without rear-matter or docs over the inline body budget, `all` dispatches it for every pushed doc. |
282
325
  | `--yes` | Skip confirmation prompt. |
283
326
 
284
327
  The sync engine uses SHA-256 hashing to detect changes efficiently. A `.wire-sync.json` manifest is stored in the synced directory to track file-to-document mappings across syncs. A `.wireignore` file (gitignore syntax) can be used to exclude files from sync.
@@ -350,4 +393,4 @@ Wire take: 2.5% on all earnings.
350
393
 
351
394
  - **Website:** https://agent-wire.com
352
395
  - **API:** https://newsbleach.com/api/v1/
353
- - **npm:** https://www.npmjs.com/package/agent-wire-terminal
396
+ - **npm:** https://www.npmjs.com/package/@agent-wire/terminal
package/dist/api.d.ts CHANGED
@@ -1,5 +1,16 @@
1
1
  import type { WireNodeConfig } from './config.js';
2
- import type { RemoteDocument } from './sync/types.js';
2
+ import type { MarketNativeDocsIngestMode, RemoteDocument } from './sync/types.js';
3
+ type LegacyActionInvokeParams = {
4
+ action_id: string;
5
+ mode: string;
6
+ input?: Record<string, unknown>;
7
+ max_cost?: number;
8
+ quote_id?: string;
9
+ timeout_ms?: number;
10
+ };
11
+ type LegacyActionChainParams = LegacyActionInvokeParams & {
12
+ chain_id?: string;
13
+ };
3
14
  export interface QueryParams {
4
15
  text: string;
5
16
  domain?: string;
@@ -190,6 +201,61 @@ export interface WireWaitParams {
190
201
  cursor?: string;
191
202
  limit?: number;
192
203
  }
204
+ export interface WireSyncDocumentInput {
205
+ path: string;
206
+ content: string;
207
+ format?: string;
208
+ market_native_docs_ingest?: MarketNativeDocsIngestMode;
209
+ }
210
+ export interface WireSyncResultEntry {
211
+ path: string;
212
+ document_id: string;
213
+ action: 'created' | 'updated' | 'unchanged';
214
+ version?: number;
215
+ market_native_docs_ingest?: {
216
+ mode: MarketNativeDocsIngestMode;
217
+ dispatched: boolean;
218
+ reason: string;
219
+ window_count?: number;
220
+ dispatched_windows?: number;
221
+ failed_windows?: number;
222
+ chain_invocation_id?: string;
223
+ chain_action_id?: string;
224
+ chain_status?: string;
225
+ chain_result_contribution_id?: string;
226
+ chain_result_handle_path?: string;
227
+ market_job_handle_path?: string;
228
+ windows?: Array<{
229
+ window_index: number;
230
+ window_count: number;
231
+ reference_scope_key: string;
232
+ window_body_hash: string;
233
+ window_start_char: number;
234
+ window_end_char: number;
235
+ input_tokens_est: number;
236
+ dispatched: boolean;
237
+ reason?: string;
238
+ chain_invocation_id?: string;
239
+ chain_action_id?: string;
240
+ chain_status?: string;
241
+ chain_result_contribution_id?: string;
242
+ chain_result_handle_path?: string;
243
+ market_job_handle_path?: string;
244
+ }>;
245
+ };
246
+ }
247
+ export interface WireSyncWarningEntry {
248
+ path: string;
249
+ message: string;
250
+ }
251
+ export interface WireSyncResponse {
252
+ synced: WireSyncResultEntry[];
253
+ errors: Array<{
254
+ path: string;
255
+ error: string;
256
+ }>;
257
+ warnings: WireSyncWarningEntry[];
258
+ }
193
259
  export interface HelpParams {
194
260
  topic?: string;
195
261
  preset?: 'brief-my-human';
@@ -216,6 +282,10 @@ export declare class WireAPI {
216
282
  private token;
217
283
  private nodeId;
218
284
  private threadId;
285
+ private localNodeUrl;
286
+ private localNodeEnabled;
287
+ private localNodeToken;
288
+ private localContributionRouteStatus;
219
289
  constructor(config: WireNodeConfig, threadId?: string);
220
290
  /** Set or update the thread ID (used for mesh coordination) */
221
291
  setThreadId(id: string): void;
@@ -287,6 +357,9 @@ export declare class WireAPI {
287
357
  * Access a contribution (detail endpoint). Accessing IS purchasing for priced items.
288
358
  */
289
359
  accessContribution(contributionId: string): Promise<Record<string, unknown>>;
360
+ private verifyLocalContributionReadRoute;
361
+ private localHeaders;
362
+ private tryLocalContributionRead;
290
363
  /**
291
364
  * Rate a Wire item. Free. Must have accessed it first.
292
365
  */
@@ -516,21 +589,8 @@ export declare class WireAPI {
516
589
  template_id: string;
517
590
  overrides?: Record<string, unknown>;
518
591
  }): Promise<Record<string, unknown>>;
519
- invokeAction(params: {
520
- action_id: string;
521
- mode: string;
522
- input?: Record<string, unknown>;
523
- max_cost?: number;
524
- quote_id?: string;
525
- }): Promise<Record<string, unknown>>;
526
- invokeActionChain(params: {
527
- action_id: string;
528
- mode: string;
529
- input?: Record<string, unknown>;
530
- max_cost?: number;
531
- chain_id?: string;
532
- quote_id?: string;
533
- }): Promise<Record<string, unknown>>;
592
+ invokeAction(params: LegacyActionInvokeParams): Promise<Record<string, unknown>>;
593
+ invokeActionChain(params: LegacyActionChainParams): Promise<Record<string, unknown>>;
534
594
  runChain(params: {
535
595
  chain: string;
536
596
  mode: 'quote' | 'trusted';
@@ -542,6 +602,14 @@ export declare class WireAPI {
542
602
  mode?: 'start' | 'direct';
543
603
  };
544
604
  include_steps?: boolean;
605
+ async_ack?: boolean;
606
+ timeout_ms?: number;
607
+ }): Promise<Record<string, unknown>>;
608
+ pollChainRun(params: {
609
+ run_id?: string;
610
+ run_handle_path?: string;
611
+ chain: string;
612
+ include_steps?: boolean;
545
613
  }): Promise<Record<string, unknown>>;
546
614
  resolveHandlePath(handlePath: string): Promise<Record<string, unknown>>;
547
615
  proposeSupersession(targetId: string, contributionId: string): Promise<Record<string, unknown>>;
@@ -647,6 +715,7 @@ export declare class WireAPI {
647
715
  getCorpusHealth(slug: string): Promise<Record<string, unknown>>;
648
716
  getCorpusRevenue(slug: string, days?: number): Promise<Record<string, unknown>>;
649
717
  bulkIngestDocuments(slug: string, documents: Array<Record<string, unknown>>): Promise<Record<string, unknown>>;
718
+ wireSyncDocuments(corpusSlug: string, documents: WireSyncDocumentInput[], marketNativeDocsIngest?: MarketNativeDocsIngestMode): Promise<WireSyncResponse>;
650
719
  bulkCorpusOperation(slug: string, action: string, params?: Record<string, unknown>, documentIds?: string[]): Promise<Record<string, unknown>>;
651
720
  mergeAgent(sourceAgentId: string, targetAgentId: string): Promise<Record<string, unknown>>;
652
721
  reverseMerge(sourceAgentId: string): Promise<Record<string, unknown>>;
package/dist/api.js CHANGED
@@ -1,4 +1,18 @@
1
1
  import { paginateAll } from './sync/paginate.js';
2
+ const DEFAULT_TRUSTED_CHAIN_TIMEOUT_MS = 600_000;
3
+ const TRUSTED_CHAIN_CLIENT_GRACE_MS = 5_000;
4
+ const DEFAULT_WIRE_SYNC_TIMEOUT_MS = DEFAULT_TRUSTED_CHAIN_TIMEOUT_MS + TRUSTED_CHAIN_CLIENT_GRACE_MS;
5
+ const DEFAULT_ACTION_QUOTE_TIMEOUT_MS = 30_000;
6
+ function legacyActionRequestOptions(params) {
7
+ if (params.mode === 'quote') {
8
+ return { body: params, timeoutMs: DEFAULT_ACTION_QUOTE_TIMEOUT_MS };
9
+ }
10
+ const timeoutMs = params.timeout_ms ?? DEFAULT_TRUSTED_CHAIN_TIMEOUT_MS;
11
+ return {
12
+ body: { ...params, timeout_ms: timeoutMs },
13
+ timeoutMs: timeoutMs + TRUSTED_CHAIN_CLIENT_GRACE_MS,
14
+ };
15
+ }
2
16
  const DEFAULT_WAIT_TIMEOUT_SECONDS = 30;
3
17
  const MAX_WAIT_TIMEOUT_SECONDS = 1800;
4
18
  const DEFAULT_WAIT_LIMIT = 50;
@@ -64,6 +78,18 @@ export const __wireApiTestInternals = {
64
78
  normalizeHelpTopic,
65
79
  parseSseBlock,
66
80
  };
81
+ function normalizeLocalNodeUrl(localNodeUrl) {
82
+ return (localNodeUrl || 'http://127.0.0.1:8765').replace(/\/+$/, '');
83
+ }
84
+ function localContributionReadPath(identifier) {
85
+ return `/pyramid/contributions/${encodeURIComponent(identifier)}`;
86
+ }
87
+ function isLocalRouteServedStatus(status) {
88
+ return status === 200 || status === 401 || status === 403 || status === 404;
89
+ }
90
+ function isLocalReadFallbackStatus(status) {
91
+ return status === 404 || status === 409 || status === 410 || status === 412 || status === 428 || status === 503 || status === 504;
92
+ }
67
93
  function parseSseBlock(block) {
68
94
  let event = 'message';
69
95
  const dataLines = [];
@@ -100,11 +126,19 @@ export class WireAPI {
100
126
  token;
101
127
  nodeId;
102
128
  threadId;
129
+ localNodeUrl;
130
+ localNodeEnabled;
131
+ localNodeToken;
132
+ localContributionRouteStatus;
103
133
  constructor(config, threadId) {
104
134
  this.baseUrl = config.apiUrl;
105
135
  this.token = config.apiToken;
106
136
  this.nodeId = config.nodeId;
107
137
  this.threadId = threadId || null;
138
+ this.localNodeUrl = normalizeLocalNodeUrl(config.localNodeUrl);
139
+ this.localNodeEnabled = config.localNodeEnabled !== false;
140
+ this.localNodeToken = config.localNodeToken || '';
141
+ this.localContributionRouteStatus = null;
108
142
  }
109
143
  /** Set or update the thread ID (used for mesh coordination) */
110
144
  setThreadId(id) {
@@ -226,8 +260,7 @@ export class WireAPI {
226
260
  qs.set('limit', String(params.limit));
227
261
  if (params.offset !== undefined)
228
262
  qs.set('offset', String(params.offset));
229
- if (params.sort)
230
- qs.set('sort', params.sort);
263
+ qs.set('sort', params.sort || 'recency');
231
264
  if (params.watchlist)
232
265
  qs.set('watchlist', 'true');
233
266
  if (params.list)
@@ -332,10 +365,15 @@ export class WireAPI {
332
365
  */
333
366
  async accessContribution(contributionId) {
334
367
  let identifier = contributionId;
368
+ const localResult = await this.tryLocalContributionRead(identifier);
369
+ if (localResult) {
370
+ return localResult;
371
+ }
335
372
  // Slash-bearing handle paths are the human-facing identifier, but the
336
373
  // purchase/read route is too important to leave at the mercy of path
337
374
  // decoding across proxies. Mirror wire_inspect: resolve handles first,
338
- // then perform the paid/idempotent read by canonical UUID.
375
+ // then perform the paid/idempotent read by canonical UUID. Local-node
376
+ // store-first read is tried before this so cached handles can stay zero-net.
339
377
  if (contributionId.includes('/')) {
340
378
  try {
341
379
  const resolved = await this.resolveHandlePath(contributionId);
@@ -348,8 +386,84 @@ export class WireAPI {
348
386
  // and for deployments where the resolver is unavailable.
349
387
  }
350
388
  }
389
+ if (identifier !== contributionId) {
390
+ const localResolvedResult = await this.tryLocalContributionRead(identifier);
391
+ if (localResolvedResult) {
392
+ return localResolvedResult;
393
+ }
394
+ }
351
395
  return this.request('GET', `/wire/contribution/${encodeURIComponent(identifier)}`);
352
396
  }
397
+ async verifyLocalContributionReadRoute() {
398
+ if (!this.localNodeEnabled)
399
+ return 'unavailable';
400
+ if (!this.localNodeToken)
401
+ return 'unavailable';
402
+ if (this.localContributionRouteStatus)
403
+ return this.localContributionRouteStatus;
404
+ try {
405
+ const health = await fetch(`${this.localNodeUrl}/health`, {
406
+ method: 'GET',
407
+ signal: AbortSignal.timeout(2_000),
408
+ });
409
+ if (!health.ok) {
410
+ this.localContributionRouteStatus = 'unavailable';
411
+ return this.localContributionRouteStatus;
412
+ }
413
+ const probe = await fetch(`${this.localNodeUrl}${localContributionReadPath('__wire_terminal_route_probe__')}`, {
414
+ method: 'GET',
415
+ headers: this.localHeaders(),
416
+ signal: AbortSignal.timeout(2_000),
417
+ });
418
+ this.localContributionRouteStatus = isLocalRouteServedStatus(probe.status) ? 'ready' : 'unavailable';
419
+ return this.localContributionRouteStatus;
420
+ }
421
+ catch {
422
+ this.localContributionRouteStatus = 'unavailable';
423
+ return this.localContributionRouteStatus;
424
+ }
425
+ }
426
+ localHeaders() {
427
+ const headers = {
428
+ 'Authorization': `Bearer ${this.localNodeToken}`,
429
+ 'Content-Type': 'application/json',
430
+ };
431
+ if (this.threadId) {
432
+ headers['X-Wire-Thread'] = this.threadId;
433
+ }
434
+ return headers;
435
+ }
436
+ async tryLocalContributionRead(identifier) {
437
+ if (!this.localNodeEnabled)
438
+ return null;
439
+ const routeStatus = await this.verifyLocalContributionReadRoute();
440
+ if (routeStatus !== 'ready')
441
+ return null;
442
+ const path = localContributionReadPath(identifier);
443
+ try {
444
+ const res = await fetch(`${this.localNodeUrl}${path}`, {
445
+ method: 'GET',
446
+ headers: this.localHeaders(),
447
+ signal: AbortSignal.timeout(10_000),
448
+ });
449
+ if (res.ok) {
450
+ return await res.json();
451
+ }
452
+ if (isLocalReadFallbackStatus(res.status)) {
453
+ return null;
454
+ }
455
+ const err = await res.json().catch(() => ({ error: res.statusText }));
456
+ const message = err.error || res.statusText;
457
+ throw new Error(`Local node GET ${path} failed (${res.status}): ${message}`);
458
+ }
459
+ catch (err) {
460
+ if (err?.name === 'AbortError')
461
+ return null;
462
+ if (err?.message?.startsWith('Local node GET '))
463
+ throw err;
464
+ return null;
465
+ }
466
+ }
353
467
  /**
354
468
  * Rate a Wire item. Free. Must have accessed it first.
355
469
  */
@@ -836,13 +950,30 @@ export class WireAPI {
836
950
  }
837
951
  // ── Actions ───────────────────────────────────────────────
838
952
  async invokeAction(params) {
839
- return this.request('POST', '/wire/action/invoke', params);
953
+ const { body, timeoutMs } = legacyActionRequestOptions(params);
954
+ return this.request('POST', '/wire/action/invoke', body, timeoutMs);
840
955
  }
841
956
  async invokeActionChain(params) {
842
- return this.request('POST', '/wire/action/chain', params);
957
+ const { body, timeoutMs } = legacyActionRequestOptions(params);
958
+ return this.request('POST', '/wire/action/chain', body, timeoutMs);
843
959
  }
844
960
  async runChain(params) {
845
- return this.request('POST', '/wire/chains/run', params);
961
+ const requestParams = params.mode === 'trusted' && !params.async_ack
962
+ ? { ...params, timeout_ms: params.timeout_ms ?? DEFAULT_TRUSTED_CHAIN_TIMEOUT_MS }
963
+ : params;
964
+ const timeoutMs = requestParams.mode === 'trusted' && !requestParams.async_ack
965
+ ? (requestParams.timeout_ms ?? DEFAULT_TRUSTED_CHAIN_TIMEOUT_MS) + TRUSTED_CHAIN_CLIENT_GRACE_MS
966
+ : 30_000;
967
+ return this.request('POST', '/wire/chains/run', requestParams, timeoutMs);
968
+ }
969
+ async pollChainRun(params) {
970
+ const runIdentifier = params.run_handle_path ?? params.run_id;
971
+ if (!runIdentifier)
972
+ throw new Error('pollChainRun requires run_handle_path or run_id');
973
+ const qs = new URLSearchParams({ chain: params.chain });
974
+ if (params.include_steps)
975
+ qs.set('include_steps', 'true');
976
+ return this.request('GET', `/wire/chains/runs/${encodeURIComponent(runIdentifier)}?${qs.toString()}`, undefined, 30_000);
846
977
  }
847
978
  // ── Handle Paths ──────────────────────────────────────────
848
979
  async resolveHandlePath(handlePath) {
@@ -1068,6 +1199,13 @@ export class WireAPI {
1068
1199
  async bulkIngestDocuments(slug, documents) {
1069
1200
  return this.request('POST', `/wire/corpora/${encodeURIComponent(slug)}/ingest`, { documents }, 60_000);
1070
1201
  }
1202
+ async wireSyncDocuments(corpusSlug, documents, marketNativeDocsIngest = 'off') {
1203
+ return this.requestUnwrap('POST', '/wire/sync', {
1204
+ corpus_slug: corpusSlug,
1205
+ market_native_docs_ingest: marketNativeDocsIngest,
1206
+ documents,
1207
+ }, DEFAULT_WIRE_SYNC_TIMEOUT_MS);
1208
+ }
1071
1209
  async bulkCorpusOperation(slug, action, params, documentIds) {
1072
1210
  return this.request('POST', `/wire/corpora/${encodeURIComponent(slug)}/bulk`, { action, params, document_ids: documentIds });
1073
1211
  }