clinch-core 0.7.0 → 0.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/dist/index.d.ts CHANGED
@@ -25,6 +25,7 @@ export interface SessionState {
25
25
  constraints: ConstraintVector;
26
26
  currentTurn: number;
27
27
  lastKnownPrice: number;
28
+ sellerInstructions?: string | null;
28
29
  sandboxSequence?: any;
29
30
  sandboxSession?: any;
30
31
  }
@@ -94,6 +95,7 @@ export interface SellerRecord {
94
95
  categories: string[];
95
96
  capabilities: string[];
96
97
  display_name?: string;
98
+ custom_instructions?: string;
97
99
  }
98
100
  export declare class ClinchSeller extends EventEmitter {
99
101
  private config;
package/dist/index.js CHANGED
@@ -257,7 +257,8 @@ class ClinchCore extends events_1.EventEmitter {
257
257
  constraints: session.constraints,
258
258
  currentTurn: session.currentTurn,
259
259
  lastKnownPrice: session.lastKnownPrice,
260
- ephemeralSecretKeyHex: toHex(session.keyPair.secretKey)
260
+ ephemeralSecretKeyHex: toHex(session.keyPair.secretKey),
261
+ sellerInstructions: session.sellerInstructions
261
262
  };
262
263
  return JSON.stringify(exportable);
263
264
  }
@@ -273,7 +274,8 @@ class ClinchCore extends events_1.EventEmitter {
273
274
  constraints: data.constraints,
274
275
  currentTurn: data.currentTurn,
275
276
  lastKnownPrice: data.lastKnownPrice,
276
- keyPair: keyPair
277
+ keyPair: keyPair,
278
+ sellerInstructions: data.sellerInstructions
277
279
  });
278
280
  this.emit('log', `[State] Rehydrated session ${data.sessionId} pointing at ${data.sellerId}`);
279
281
  }
@@ -286,6 +288,9 @@ class ClinchCore extends events_1.EventEmitter {
286
288
  throw new Error("Cannot build prompt: Session not found.");
287
289
  const gap = session.lastKnownPrice - session.constraints.max_budget;
288
290
  const gapText = gap > 0 ? `-$${gap} (Over budget)` : `+$${Math.abs(gap)} (Under budget)`;
291
+ const customInstructionsBlock = session.sellerInstructions
292
+ ? `\nCUSTOM INSTRUCTIONS DIRECT FROM TARGET DOMAIN (${session.sellerId}):\n"""\n${session.sellerInstructions}\n"""\n`
293
+ : "";
289
294
  return `You are a professional AI purchasing agent negotiating via the Clinch Protocol.
290
295
  Your only goal is to secure the requested item below the maximum budget.
291
296
 
@@ -296,7 +301,7 @@ NEGOTIATION STATE:
296
301
  - Current turn: ${session.currentTurn}
297
302
  - Last seller price: $${session.lastKnownPrice}
298
303
  - Gap to budget: ${gapText}
299
-
304
+ ${customInstructionsBlock}
300
305
  SELLER'S LATEST MESSAGE:
301
306
  "${incomingMessage}"
302
307
 
@@ -321,7 +326,7 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
321
326
  return await this.networkRequest(url);
322
327
  }
323
328
  async negotiate(address, constraints) {
324
- this.emit('log', `[Protocol] Initiating handshake with ${address}...`);
329
+ this.emit('log', `[Protocol] Handshaking with ${address}...`);
325
330
  const parsed = this.parseAddress(address);
326
331
  const ephemeralKeys = tweetnacl_1.default.sign.keyPair();
327
332
  const ephemeralPubHex = toHex(ephemeralKeys.publicKey);
@@ -344,6 +349,7 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
344
349
  headers: { 'Content-Type': 'application/json' },
345
350
  body: JSON.stringify({ ...initPayload, sig: signature })
346
351
  });
352
+ const instructions = response.custom_instructions || null;
347
353
  this.activeSessions.set(response.session_id, {
348
354
  sessionId: response.session_id,
349
355
  sellerId: parsed.domain,
@@ -351,7 +357,8 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
351
357
  status: 'ACTIVE',
352
358
  constraints,
353
359
  currentTurn: 1,
354
- lastKnownPrice: 0
360
+ lastKnownPrice: 0,
361
+ sellerInstructions: instructions
355
362
  });
356
363
  this.setStatus('NEGOTIATING');
357
364
  this.emit('session_started', { sessionId: response.session_id, sellerId: parsed.domain });
@@ -387,9 +394,6 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
387
394
  session.exitTokenHash = res.token_hash;
388
395
  return res.token_hash;
389
396
  }
390
- // --------------------------------------------------------------------------
391
- // CASCADING ITERATIVE NEGOTIATION (Squeeze vs. Parallel Concurrency)
392
- // --------------------------------------------------------------------------
393
397
  async negotiateCascade(category, constraints, maxSellers = 3, strategy = 'sequential') {
394
398
  this.emit('log', `[Cascade] Querying registry for matching sellers under "${category}"...`);
395
399
  const discovery = await this.search(category);
@@ -398,7 +402,6 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
398
402
  this.emit('log', `[Cascade] No matching sellers found for category: "${category}"`);
399
403
  return null;
400
404
  }
401
- // ── STRATEGY 1: PARALLEL RACE (High Urgency / Ride Hailing) ──
402
405
  if (strategy === 'parallel') {
403
406
  this.emit('log', `[Cascade] ⚡ Running PARALLEL RACE simultaneously across ${sellers.length} seller nodes...`);
404
407
  const sessionPromises = sellers.map(async (seller) => {
@@ -428,7 +431,6 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
428
431
  finalPrice: winner.price
429
432
  };
430
433
  }
431
- // ── STRATEGY 2: SEQUENTIAL SQUEEZE (Low Urgency / Price Optimization) ──
432
434
  this.emit('log', `[Cascade] ➔ Running SEQUENTIAL SQUEEZE across ${sellers.length} seller nodes...`);
433
435
  let bestDeal = null;
434
436
  let currentBudgetCeiling = constraints.max_budget;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clinch-core",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
 
5
5
  "description": "Clinch Protocol Edge Client",
6
6
  "main": "dist/index.js",
package/src/index.ts CHANGED
@@ -63,6 +63,9 @@ export interface SessionState {
63
63
  currentTurn: number;
64
64
  lastKnownPrice: number;
65
65
 
66
+ // Direct, dynamic instructions injected by the target domain
67
+ sellerInstructions?: string | null;
68
+
66
69
  sandboxSequence?: any;
67
70
  sandboxSession?: any;
68
71
  }
@@ -295,7 +298,8 @@ export class ClinchCore extends EventEmitter {
295
298
  constraints: session.constraints,
296
299
  currentTurn: session.currentTurn,
297
300
  lastKnownPrice: session.lastKnownPrice,
298
- ephemeralSecretKeyHex: toHex(session.keyPair.secretKey)
301
+ ephemeralSecretKeyHex: toHex(session.keyPair.secretKey),
302
+ sellerInstructions: session.sellerInstructions
299
303
  };
300
304
 
301
305
  return JSON.stringify(exportable);
@@ -314,7 +318,8 @@ export class ClinchCore extends EventEmitter {
314
318
  constraints: data.constraints,
315
319
  currentTurn: data.currentTurn,
316
320
  lastKnownPrice: data.lastKnownPrice,
317
- keyPair: keyPair
321
+ keyPair: keyPair,
322
+ sellerInstructions: data.sellerInstructions
318
323
  });
319
324
 
320
325
  this.emit('log', `[State] Rehydrated session ${data.sessionId} pointing at ${data.sellerId}`);
@@ -331,6 +336,10 @@ export class ClinchCore extends EventEmitter {
331
336
  const gap = session.lastKnownPrice - session.constraints.max_budget;
332
337
  const gapText = gap > 0 ? `-$${gap} (Over budget)` : `+$${Math.abs(gap)} (Under budget)`;
333
338
 
339
+ const customInstructionsBlock = session.sellerInstructions
340
+ ? `\nCUSTOM INSTRUCTIONS DIRECT FROM TARGET DOMAIN (${session.sellerId}):\n"""\n${session.sellerInstructions}\n"""\n`
341
+ : "";
342
+
334
343
  return `You are a professional AI purchasing agent negotiating via the Clinch Protocol.
335
344
  Your only goal is to secure the requested item below the maximum budget.
336
345
 
@@ -341,7 +350,7 @@ NEGOTIATION STATE:
341
350
  - Current turn: ${session.currentTurn}
342
351
  - Last seller price: $${session.lastKnownPrice}
343
352
  - Gap to budget: ${gapText}
344
-
353
+ ${customInstructionsBlock}
345
354
  SELLER'S LATEST MESSAGE:
346
355
  "${incomingMessage}"
347
356
 
@@ -367,7 +376,7 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
367
376
  }
368
377
 
369
378
  async negotiate(address: string, constraints: ConstraintVector): Promise<string> {
370
- this.emit('log', `[Protocol] Initiating handshake with ${address}...`);
379
+ this.emit('log', `[Protocol] Handshaking with ${address}...`);
371
380
  const parsed = this.parseAddress(address);
372
381
 
373
382
  const ephemeralKeys = nacl.sign.keyPair();
@@ -397,6 +406,8 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
397
406
  body: JSON.stringify({ ...initPayload, sig: signature })
398
407
  });
399
408
 
409
+ const instructions = response.custom_instructions || null;
410
+
400
411
  this.activeSessions.set(response.session_id, {
401
412
  sessionId: response.session_id,
402
413
  sellerId: parsed.domain,
@@ -404,7 +415,8 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
404
415
  status: 'ACTIVE',
405
416
  constraints,
406
417
  currentTurn: 1,
407
- lastKnownPrice: 0
418
+ lastKnownPrice: 0,
419
+ sellerInstructions: instructions
408
420
  });
409
421
 
410
422
  this.setStatus('NEGOTIATING');
@@ -450,9 +462,6 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
450
462
  return res.token_hash;
451
463
  }
452
464
 
453
- // --------------------------------------------------------------------------
454
- // CASCADING ITERATIVE NEGOTIATION (Squeeze vs. Parallel Concurrency)
455
- // --------------------------------------------------------------------------
456
465
  public async negotiateCascade(
457
466
  category: string,
458
467
  constraints: ConstraintVector,
@@ -468,7 +477,6 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
468
477
  return null;
469
478
  }
470
479
 
471
- // ── STRATEGY 1: PARALLEL RACE (High Urgency / Ride Hailing) ──
472
480
  if (strategy === 'parallel') {
473
481
  this.emit('log', `[Cascade] ⚡ Running PARALLEL RACE simultaneously across ${sellers.length} seller nodes...`);
474
482
 
@@ -503,7 +511,6 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
503
511
  };
504
512
  }
505
513
 
506
- // ── STRATEGY 2: SEQUENTIAL SQUEEZE (Low Urgency / Price Optimization) ──
507
514
  this.emit('log', `[Cascade] ➔ Running SEQUENTIAL SQUEEZE across ${sellers.length} seller nodes...`);
508
515
  let bestDeal: { sessionId: string, sellerId: string, finalPrice: number } | null = null;
509
516
  let currentBudgetCeiling = constraints.max_budget;
@@ -735,12 +742,13 @@ You MUST respond ONLY in valid JSON matching this exact schema. Do not include m
735
742
  // THE CLINCH SELLER LIBRARY (Server-Side)
736
743
  // ============================================================================
737
744
  export interface SellerRecord {
738
- agent_id: string;
739
- endpoint: string;
740
- supported_modes: string[];
741
- categories: string[];
742
- capabilities: string[];
743
- display_name?: string;
745
+ agent_id: string;
746
+ endpoint: string;
747
+ supported_modes: string[];
748
+ categories: string[];
749
+ capabilities: string[];
750
+ display_name?: string;
751
+ custom_instructions?: string; // Strictly typed dynamic record instructions mapping
744
752
  }
745
753
 
746
754
  export class ClinchSeller extends EventEmitter {