@lawrenceliang-btc/atel-sdk 1.1.30 → 1.1.32
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/bin/atel.mjs +84 -22
- package/package.json +1 -1
package/bin/atel.mjs
CHANGED
|
@@ -312,26 +312,26 @@ async function pushTradeNotification(eventType, payload, body) {
|
|
|
312
312
|
if (enabled.length === 0) return;
|
|
313
313
|
|
|
314
314
|
const templates = {
|
|
315
|
-
'order_created': (p) => `📥
|
|
316
|
-
'order_accepted': (p) => `📋
|
|
315
|
+
'order_created': (p) => `📥 收到新订单\n订单: ${p.orderId || body?.orderId || '?'}\n金额: $${p.priceAmount ?? '?'} USDC\n来自: ${p.requesterDid || '未知请求方'}\n请审核后决定是否接单`,
|
|
316
|
+
'order_accepted': (p) => `📋 订单已被接单\n订单: ${p.orderId || body?.orderId || '?'}\n执行方已开始处理,进入里程碑阶段`,
|
|
317
317
|
'milestone_submitted': (p) => {
|
|
318
|
-
const desc = p.milestoneDescription ? `\
|
|
319
|
-
const content = p.resultSummary ? `\
|
|
320
|
-
return `📝
|
|
318
|
+
const desc = p.milestoneDescription ? `\n目标: ${p.milestoneDescription}` : '';
|
|
319
|
+
const content = p.resultSummary ? `\n提交内容: ${String(p.resultSummary).substring(0, 200)}` : '';
|
|
320
|
+
return `📝 里程碑 M${p.milestoneIndex ?? '?'} 已提交\n订单: ${p.orderId || body?.orderId || '?'}${desc}${content}\n等待审核`;
|
|
321
321
|
},
|
|
322
322
|
'milestone_verified': (p) => {
|
|
323
|
-
const desc = p.milestoneDescription ? `\
|
|
324
|
-
const content = p.resultSummary ? `\
|
|
325
|
-
const progress = p.totalMilestones ? `\
|
|
326
|
-
return `✅
|
|
323
|
+
const desc = p.milestoneDescription ? `\n目标: ${p.milestoneDescription}` : '';
|
|
324
|
+
const content = p.resultSummary ? `\n提交内容: ${String(p.resultSummary).substring(0, 200)}` : '';
|
|
325
|
+
const progress = p.totalMilestones ? `\n进度: ${(p.milestoneIndex ?? 0) + 1}/${p.totalMilestones}` : '';
|
|
326
|
+
return `✅ 里程碑 M${p.milestoneIndex ?? '?'} 审核通过\n订单: ${p.orderId || body?.orderId || '?'}${desc}${content}${progress}`;
|
|
327
327
|
},
|
|
328
328
|
'milestone_rejected': (p) => {
|
|
329
|
-
const desc = p.milestoneDescription ? `\
|
|
330
|
-
return `❌
|
|
329
|
+
const desc = p.milestoneDescription ? `\n目标: ${p.milestoneDescription}` : '';
|
|
330
|
+
return `❌ 里程碑 M${p.milestoneIndex ?? '?'} 被拒绝\n订单: ${p.orderId || body?.orderId || '?'}${desc}\n原因: ${p.rejectReason || '未说明'}`;
|
|
331
331
|
},
|
|
332
332
|
'order_settled': (p) => {
|
|
333
|
-
const amount = p.priceAmount ? `\
|
|
334
|
-
return `💰
|
|
333
|
+
const amount = p.priceAmount ? `\n金额: $${p.priceAmount} USDC` : '';
|
|
334
|
+
return `💰 订单已结算完成\n订单: ${p.orderId || body?.orderId || '?'}${amount}\nUSDC 已支付`;
|
|
335
335
|
},
|
|
336
336
|
};
|
|
337
337
|
const tmpl = templates[eventType];
|
|
@@ -386,12 +386,12 @@ async function pushP2PNotification(eventType, payload = {}) {
|
|
|
386
386
|
if (enabled.length === 0) return;
|
|
387
387
|
|
|
388
388
|
const templates = {
|
|
389
|
-
'p2p_task_sent': (p) => `📤 P2P
|
|
390
|
-
'p2p_task_received': (p) => `📩
|
|
391
|
-
'p2p_task_started': (p) => `▶️ P2P
|
|
392
|
-
'p2p_result_submitted': (p) => `📨 P2P
|
|
393
|
-
'p2p_result_received': (p) => `✅ P2P
|
|
394
|
-
'p2p_task_failed': (p) => `❌ P2P
|
|
389
|
+
'p2p_task_sent': (p) => `📤 P2P任务已发送\n任务: ${p.taskId || '?'}\n目标: ${p.peerDid || '?'}`,
|
|
390
|
+
'p2p_task_received': (p) => `📩 收到新的P2P任务\n任务: ${p.taskId || '?'}\n来自: ${p.peerDid || '?'}`,
|
|
391
|
+
'p2p_task_started': (p) => `▶️ P2P任务开始处理\n任务: ${p.taskId || '?'}\n来自: ${p.peerDid || '?'}`,
|
|
392
|
+
'p2p_result_submitted': (p) => `📨 P2P结果已发回对方\n任务: ${p.taskId || '?'}\n目标: ${p.peerDid || '?'}`,
|
|
393
|
+
'p2p_result_received': (p) => `✅ P2P任务已完成\n任务: ${p.taskId || '?'}\n结果: ${String(p.result || '').slice(0, 80) || '已返回'}`,
|
|
394
|
+
'p2p_task_failed': (p) => `❌ P2P任务失败\n任务: ${p.taskId || '?'}\n原因: ${p.reason || '未知错误'}`,
|
|
395
395
|
};
|
|
396
396
|
const tmpl = templates[eventType];
|
|
397
397
|
if (!tmpl) return;
|
|
@@ -3438,7 +3438,20 @@ Format:
|
|
|
3438
3438
|
const orderId = order?.orderId;
|
|
3439
3439
|
if (!orderId) continue;
|
|
3440
3440
|
seenOrderIds.add(orderId);
|
|
3441
|
-
|
|
3441
|
+
// The list endpoint returns a slim projection that omits
|
|
3442
|
+
// `description` / `taskRequest`. Re-fetch the full order so
|
|
3443
|
+
// reconcileSingleTradeOrder has the authoritative order
|
|
3444
|
+
// description — without it ORDER_CONTEXT.md / agent prompts
|
|
3445
|
+
// would be missing the original task and the LLM would
|
|
3446
|
+
// hallucinate a topic from the milestone title alone.
|
|
3447
|
+
let fullOrder = order;
|
|
3448
|
+
try {
|
|
3449
|
+
const fetched = await fetchOrderState(orderId);
|
|
3450
|
+
if (fetched) fullOrder = fetched;
|
|
3451
|
+
} catch (e) {
|
|
3452
|
+
log({ event: 'trade_reconcile_order_fetch_error', orderId, error: e.message });
|
|
3453
|
+
}
|
|
3454
|
+
await reconcileSingleTradeOrder(fullOrder);
|
|
3442
3455
|
} catch (e) {
|
|
3443
3456
|
log({ event: 'trade_reconcile_order_error', orderId: order?.orderId, status, error: e.message });
|
|
3444
3457
|
}
|
|
@@ -3467,7 +3480,7 @@ Format:
|
|
|
3467
3480
|
const event = body.eventType || body.event;
|
|
3468
3481
|
const payload = body.payload || {};
|
|
3469
3482
|
const eventId = body.eventId;
|
|
3470
|
-
|
|
3483
|
+
let prompt = body.prompt || payload.prompt;
|
|
3471
3484
|
const recommendedActions = body.recommendedActions || payload.recommendedActions;
|
|
3472
3485
|
|
|
3473
3486
|
if (!event) {
|
|
@@ -3520,7 +3533,7 @@ Format:
|
|
|
3520
3533
|
|
|
3521
3534
|
const dedupeKey = body.dedupeKey || `${event}:${body.orderId || payload.orderId || ''}`;
|
|
3522
3535
|
const orderIdForCwd = body.orderId || payload.orderId || '';
|
|
3523
|
-
|
|
3536
|
+
let workspace = getOrderWorkspace(orderIdForCwd, {
|
|
3524
3537
|
chain: payload.chain || body.chain || '',
|
|
3525
3538
|
role: payload.executorDid === id.did ? 'executor' : (payload.requesterDid === id.did ? 'requester' : ''),
|
|
3526
3539
|
status: payload.orderStatus || body.orderStatus || '',
|
|
@@ -3534,6 +3547,55 @@ Format:
|
|
|
3534
3547
|
const hookCwd = workspace.dir;
|
|
3535
3548
|
const atelCwd = getAtelWorkspaceRoot();
|
|
3536
3549
|
|
|
3550
|
+
// ── Verifier context enrichment for milestone_submitted ──
|
|
3551
|
+
// Platform-side prompt for milestone_submitted historically did not
|
|
3552
|
+
// include the original order description, so the verifier LLM had no
|
|
3553
|
+
// ground truth to compare against. We re-fetch the full order here so
|
|
3554
|
+
// ORDER_CONTEXT.md (the LLM's authoritative source file) and the
|
|
3555
|
+
// prompt both contain the original task. We do NOT impose rule
|
|
3556
|
+
// checklists — judgment belongs to the agent.
|
|
3557
|
+
if (event === 'milestone_submitted' && orderIdForCwd) {
|
|
3558
|
+
try {
|
|
3559
|
+
const fullOrder = await fetchOrderState(orderIdForCwd);
|
|
3560
|
+
const fullDesc = (fullOrder?.description
|
|
3561
|
+
|| fullOrder?.Description
|
|
3562
|
+
|| fullOrder?.taskRequest?.description
|
|
3563
|
+
|| fullOrder?.TaskRequest?.description
|
|
3564
|
+
|| '');
|
|
3565
|
+
if (fullDesc) {
|
|
3566
|
+
workspace = getOrderWorkspace(orderIdForCwd, {
|
|
3567
|
+
chain: fullOrder?.chain || fullOrder?.Chain || payload.chain || body.chain || '',
|
|
3568
|
+
role: 'requester',
|
|
3569
|
+
status: fullOrder?.status || fullOrder?.Status || 'executing',
|
|
3570
|
+
phase: 'waiting_requester_verification',
|
|
3571
|
+
currentMilestone: payload.milestoneIndex ?? '',
|
|
3572
|
+
milestoneTitle: payload.milestoneDescription || '',
|
|
3573
|
+
orderDescription: fullDesc,
|
|
3574
|
+
milestoneObjective: payload.milestoneDescription || '',
|
|
3575
|
+
resultSummary: payload.resultSummary || '',
|
|
3576
|
+
});
|
|
3577
|
+
// Only override the prompt if the platform-supplied one is missing
|
|
3578
|
+
// the original task — newer platform builds embed it directly.
|
|
3579
|
+
if (typeof prompt === 'string' && !prompt.includes(fullDesc)) {
|
|
3580
|
+
const mIdx = payload.milestoneIndex ?? 0;
|
|
3581
|
+
const mDesc = payload.milestoneDescription || '';
|
|
3582
|
+
const subSummary = payload.resultSummary || '';
|
|
3583
|
+
const submitCount = payload.submitCount || 1;
|
|
3584
|
+
prompt = `你是 ATEL 发单方 Agent,正在评审执行方对里程碑 M${mIdx} 的提交。\n\n`
|
|
3585
|
+
+ `## 原任务\n${fullDesc}\n\n`
|
|
3586
|
+
+ `## 当前里程碑\nM${mIdx}: ${mDesc}\n\n`
|
|
3587
|
+
+ `## 执行方提交(第 ${submitCount}/3 次)\n${subSummary}\n\n`
|
|
3588
|
+
+ `请基于你自己的判断,评估这次提交是否真实地完成了原任务在当前里程碑应有的部分。如果符合原任务的要求和意图,PASS;如果偏离原任务、违反原任务的约束、或没有真正交付要求的内容,REJECT。\n\n`
|
|
3589
|
+
+ `通过:\ncd ~/atel-workspace && atel milestone-verify ${orderIdForCwd} ${mIdx} --pass\n\n`
|
|
3590
|
+
+ `不通过(必须给出具体理由):\ncd ~/atel-workspace && atel milestone-verify ${orderIdForCwd} ${mIdx} --reject '具体原因'\n`;
|
|
3591
|
+
log({ event: 'verifier_prompt_overridden', orderId: orderIdForCwd, milestoneIndex: mIdx });
|
|
3592
|
+
}
|
|
3593
|
+
}
|
|
3594
|
+
} catch (e) {
|
|
3595
|
+
log({ event: 'verifier_prompt_override_error', orderId: orderIdForCwd, error: e.message });
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
|
|
3537
3599
|
// 3. Policy mode: auto-execute deterministic operations (not thinking/work)
|
|
3538
3600
|
const currentPolicy = loadPolicy();
|
|
3539
3601
|
if (currentPolicy.agentMode === 'policy') {
|