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 +2 -0
- package/dist/index.js +12 -10
- package/package.json +1 -1
- package/src/index.ts +24 -16
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]
|
|
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
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]
|
|
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:
|
|
739
|
-
endpoint:
|
|
740
|
-
supported_modes:
|
|
741
|
-
categories:
|
|
742
|
-
capabilities:
|
|
743
|
-
display_name?:
|
|
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 {
|