@harrylabsj/kiwi 0.8.0 → 0.10.0
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 +1 -1
- package/dist/a2a/negotiate.d.ts +6 -2
- package/dist/a2a/negotiate.js +10 -3
- package/dist/a2a/negotiate.js.map +1 -1
- package/dist/a2a/node.d.ts +4 -1
- package/dist/a2a/node.js +56 -3
- package/dist/a2a/node.js.map +1 -1
- package/dist/a2a/server/merchant-handler.d.ts +11 -3
- package/dist/a2a/server/merchant-handler.js +84 -26
- package/dist/a2a/server/merchant-handler.js.map +1 -1
- package/dist/agent/buyer/buyer-tools.js +2 -2
- package/dist/agent/buyer/buyer-tools.js.map +1 -1
- package/dist/agent/kernel.js +5 -1
- package/dist/agent/kernel.js.map +1 -1
- package/dist/agent/memory/schema.d.ts +1 -1
- package/dist/agent/memory/schema.js +9 -1
- package/dist/agent/memory/schema.js.map +1 -1
- package/dist/agent/merchant/action-candidate.d.ts +18 -0
- package/dist/agent/merchant/action-candidate.js +51 -0
- package/dist/agent/merchant/action-candidate.js.map +1 -1
- package/dist/agent/merchant/fake-merchant-client.js +6 -1
- package/dist/agent/merchant/fake-merchant-client.js.map +1 -1
- package/dist/agent/merchant/intelligence/default-backend.js +25 -2
- package/dist/agent/merchant/intelligence/default-backend.js.map +1 -1
- package/dist/agent/merchant/merchant-client.d.ts +50 -1
- package/dist/agent/merchant/merchant-client.js +157 -8
- package/dist/agent/merchant/merchant-client.js.map +1 -1
- package/dist/agent/merchant/merchant-presentations.js +25 -2
- package/dist/agent/merchant/merchant-presentations.js.map +1 -1
- package/dist/agent/merchant/merchant-tools.js +102 -188
- package/dist/agent/merchant/merchant-tools.js.map +1 -1
- package/dist/agent/merchant/types.d.ts +6 -2
- package/dist/agent/merchant/types.js +45 -0
- package/dist/agent/merchant/types.js.map +1 -1
- package/dist/auth/merchant-authorization.d.ts +49 -0
- package/dist/auth/merchant-authorization.js +61 -0
- package/dist/auth/merchant-authorization.js.map +1 -0
- package/dist/auth/merchant-oauth.d.ts +255 -0
- package/dist/auth/merchant-oauth.js +764 -0
- package/dist/auth/merchant-oauth.js.map +1 -0
- package/dist/auth/merchant-pairing.d.ts +62 -0
- package/dist/auth/merchant-pairing.js +199 -0
- package/dist/auth/merchant-pairing.js.map +1 -0
- package/dist/auth/merchant-sessions.d.ts +71 -0
- package/dist/auth/merchant-sessions.js +168 -0
- package/dist/auth/merchant-sessions.js.map +1 -0
- package/dist/buyer-core/build-service.d.ts +5 -0
- package/dist/buyer-core/build-service.js +12 -0
- package/dist/buyer-core/build-service.js.map +1 -1
- package/dist/buyer-core/errors.d.ts +1 -1
- package/dist/buyer-core/errors.js +2 -0
- package/dist/buyer-core/errors.js.map +1 -1
- package/dist/buyer-core/merchant-index.d.ts +19 -4
- package/dist/buyer-core/merchant-index.js +137 -16
- package/dist/buyer-core/merchant-index.js.map +1 -1
- package/dist/buyer-core/negotiator.d.ts +0 -10
- package/dist/buyer-core/negotiator.js +12 -1
- package/dist/buyer-core/negotiator.js.map +1 -1
- package/dist/buyer-core/quote-fetcher.js +2 -1
- package/dist/buyer-core/quote-fetcher.js.map +1 -1
- package/dist/buyer-core/service.d.ts +104 -0
- package/dist/buyer-core/service.js +105 -1
- package/dist/buyer-core/service.js.map +1 -1
- package/dist/cli.d.ts +4 -2
- package/dist/cli.js +612 -20
- package/dist/cli.js.map +1 -1
- package/dist/config/profile.d.ts +30 -0
- package/dist/config/profile.js +126 -61
- package/dist/config/profile.js.map +1 -1
- package/dist/demo/demo-runner.js +12 -9
- package/dist/demo/demo-runner.js.map +1 -1
- package/dist/discovery/catalog-source/buyer-follows.d.ts +82 -0
- package/dist/discovery/catalog-source/buyer-follows.js +228 -0
- package/dist/discovery/catalog-source/buyer-follows.js.map +1 -0
- package/dist/discovery/catalog-source/connector-identity.d.ts +75 -0
- package/dist/discovery/catalog-source/connector-identity.js +175 -0
- package/dist/discovery/catalog-source/connector-identity.js.map +1 -0
- package/dist/discovery/catalog-source/errors.d.ts +1 -1
- package/dist/discovery/catalog-source/errors.js +2 -0
- package/dist/discovery/catalog-source/errors.js.map +1 -1
- package/dist/discovery/catalog-source/merchant-publications.d.ts +65 -0
- package/dist/discovery/catalog-source/merchant-publications.js +207 -0
- package/dist/discovery/catalog-source/merchant-publications.js.map +1 -0
- package/dist/discovery/catalog-source/register.d.ts +24 -0
- package/dist/discovery/catalog-source/register.js +46 -0
- package/dist/discovery/catalog-source/register.js.map +1 -1
- package/dist/discovery/catalog-source/source.js +2 -1
- package/dist/discovery/catalog-source/source.js.map +1 -1
- package/dist/fs/atomic-write.d.ts +18 -0
- package/dist/fs/atomic-write.js +29 -0
- package/dist/fs/atomic-write.js.map +1 -0
- package/dist/http/server.js +4 -1
- package/dist/http/server.js.map +1 -1
- package/dist/mcp/cli.d.ts +2 -0
- package/dist/mcp/cli.js +7 -6
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/merchant-auth.d.ts +78 -0
- package/dist/mcp/merchant-auth.js +146 -0
- package/dist/mcp/merchant-auth.js.map +1 -0
- package/dist/mcp/merchant-dirs.d.ts +26 -0
- package/dist/mcp/merchant-dirs.js +44 -0
- package/dist/mcp/merchant-dirs.js.map +1 -0
- package/dist/mcp/merchant-resources.d.ts +38 -0
- package/dist/mcp/merchant-resources.js +146 -0
- package/dist/mcp/merchant-resources.js.map +1 -0
- package/dist/mcp/merchant-server.d.ts +106 -0
- package/dist/mcp/merchant-server.js +615 -0
- package/dist/mcp/merchant-server.js.map +1 -0
- package/dist/mcp/merchant-tools.d.ts +103 -0
- package/dist/mcp/merchant-tools.js +517 -0
- package/dist/mcp/merchant-tools.js.map +1 -0
- package/dist/mcp/server.js +4 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +5 -3
- package/dist/mcp/tools.js +102 -5
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/types.d.ts +1 -1
- package/dist/mcp/types.js +4 -0
- package/dist/mcp/types.js.map +1 -1
- package/dist/merchant/ops.d.ts +0 -11
- package/dist/merchant/ops.js +13 -1
- package/dist/merchant/ops.js.map +1 -1
- package/dist/merchant/workbench-service.d.ts +189 -0
- package/dist/merchant/workbench-service.js +417 -0
- package/dist/merchant/workbench-service.js.map +1 -0
- package/dist/merchant-admin/pending-page.d.ts +35 -0
- package/dist/merchant-admin/pending-page.js +69 -0
- package/dist/merchant-admin/pending-page.js.map +1 -0
- package/dist/merchant-core/commands.d.ts +99 -0
- package/dist/merchant-core/commands.js +179 -0
- package/dist/merchant-core/commands.js.map +1 -0
- package/dist/merchant-core/executor.d.ts +69 -0
- package/dist/merchant-core/executor.js +218 -0
- package/dist/merchant-core/executor.js.map +1 -0
- package/dist/merchant-core/negotiation-adapters.d.ts +55 -0
- package/dist/merchant-core/negotiation-adapters.js +55 -0
- package/dist/merchant-core/negotiation-adapters.js.map +1 -0
- package/dist/merchant-core/network-checks.d.ts +65 -0
- package/dist/merchant-core/network-checks.js +111 -0
- package/dist/merchant-core/network-checks.js.map +1 -0
- package/dist/merchant-core/operations.d.ts +64 -0
- package/dist/merchant-core/operations.js +136 -0
- package/dist/merchant-core/operations.js.map +1 -0
- package/dist/merchant-core/policy-runtime.d.ts +70 -0
- package/dist/merchant-core/policy-runtime.js +181 -0
- package/dist/merchant-core/policy-runtime.js.map +1 -0
- package/dist/merchant-core/product-import.d.ts +67 -0
- package/dist/merchant-core/product-import.js +160 -0
- package/dist/merchant-core/product-import.js.map +1 -0
- package/dist/merchant-core/service.d.ts +203 -0
- package/dist/merchant-core/service.js +402 -0
- package/dist/merchant-core/service.js.map +1 -0
- package/dist/merchant-gateway/catalog-publications.d.ts +96 -0
- package/dist/merchant-gateway/catalog-publications.js +212 -0
- package/dist/merchant-gateway/catalog-publications.js.map +1 -0
- package/dist/merchant-gateway/catalog-tools.d.ts +46 -0
- package/dist/merchant-gateway/catalog-tools.js +315 -0
- package/dist/merchant-gateway/catalog-tools.js.map +1 -0
- package/dist/merchant-gateway/cli.d.ts +75 -0
- package/dist/merchant-gateway/cli.js +461 -0
- package/dist/merchant-gateway/cli.js.map +1 -0
- package/dist/merchant-gateway/credential-vault.d.ts +44 -0
- package/dist/merchant-gateway/credential-vault.js +111 -0
- package/dist/merchant-gateway/credential-vault.js.map +1 -0
- package/dist/merchant-gateway/entry-server.d.ts +117 -0
- package/dist/merchant-gateway/entry-server.js +747 -0
- package/dist/merchant-gateway/entry-server.js.map +1 -0
- package/dist/merchant-gateway/instance-registration.d.ts +144 -0
- package/dist/merchant-gateway/instance-registration.js +391 -0
- package/dist/merchant-gateway/instance-registration.js.map +1 -0
- package/dist/merchant-gateway/instance-tools.d.ts +58 -0
- package/dist/merchant-gateway/instance-tools.js +186 -0
- package/dist/merchant-gateway/instance-tools.js.map +1 -0
- package/dist/merchant-gateway/mcp-proxy.d.ts +25 -0
- package/dist/merchant-gateway/mcp-proxy.js +192 -0
- package/dist/merchant-gateway/mcp-proxy.js.map +1 -0
- package/dist/merchant-gateway/pinned-fetch.d.ts +54 -0
- package/dist/merchant-gateway/pinned-fetch.js +231 -0
- package/dist/merchant-gateway/pinned-fetch.js.map +1 -0
- package/dist/merchant-gateway/tenant-registry.d.ts +82 -0
- package/dist/merchant-gateway/tenant-registry.js +190 -0
- package/dist/merchant-gateway/tenant-registry.js.map +1 -0
- package/dist/merchant-gateway/tool-bundle.d.ts +26 -0
- package/dist/merchant-gateway/tool-bundle.js +56 -0
- package/dist/merchant-gateway/tool-bundle.js.map +1 -0
- package/dist/merchant-runtime/backup.d.ts +48 -0
- package/dist/merchant-runtime/backup.js +226 -0
- package/dist/merchant-runtime/backup.js.map +1 -0
- package/dist/merchant-runtime/health.d.ts +99 -0
- package/dist/merchant-runtime/health.js +206 -0
- package/dist/merchant-runtime/health.js.map +1 -0
- package/dist/merchant-runtime/jobs.d.ts +64 -0
- package/dist/merchant-runtime/jobs.js +107 -0
- package/dist/merchant-runtime/jobs.js.map +1 -0
- package/dist/merchant-runtime/manager.d.ts +94 -0
- package/dist/merchant-runtime/manager.js +305 -0
- package/dist/merchant-runtime/manager.js.map +1 -0
- package/dist/merchant-runtime/services.d.ts +30 -0
- package/dist/merchant-runtime/services.js +51 -0
- package/dist/merchant-runtime/services.js.map +1 -0
- package/dist/net/url.d.ts +26 -0
- package/dist/net/url.js +32 -0
- package/dist/net/url.js.map +1 -0
- package/dist/product-cli.js +22 -3
- package/dist/product-cli.js.map +1 -1
- package/dist/product-compat.d.ts +9 -1
- package/dist/product-compat.js +12 -1
- package/dist/product-compat.js.map +1 -1
- package/dist/product-init.js +17 -5
- package/dist/product-init.js.map +1 -1
- package/dist/product-publish.js +2 -1
- package/dist/product-publish.js.map +1 -1
- package/package.json +3 -2
- package/skills/kiwi-buyer/SKILL.md +2 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { contentHash, executeApprovedCandidate, WriteApprovalCandidateError, } from "../agent/merchant/action-candidate.js";
|
|
17
|
+
import { routeWriteCandidate } from "../agent/write-gate.js";
|
|
18
|
+
import { MerchantWorkbenchError } from "../merchant/workbench-service.js";
|
|
19
|
+
export class MerchantCommandLog {
|
|
20
|
+
deps;
|
|
21
|
+
constructor(deps) {
|
|
22
|
+
this.deps = deps;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 登记写命令(prepare):校验工具已注册 → 执行器重读前置版本 → 写门
|
|
26
|
+
* force_pending 产候选(任何模式都不自动执行)。
|
|
27
|
+
*/
|
|
28
|
+
async prepare(input) {
|
|
29
|
+
const executor = this.deps.executors.get(input.tool);
|
|
30
|
+
if (executor === undefined) {
|
|
31
|
+
throw new MerchantWorkbenchError("validation", `未注册的写工具 ${input.tool}(固定执行器注册表,禁止动态分发)`);
|
|
32
|
+
}
|
|
33
|
+
const preconditions = await executor.readPreconditions(input.arguments);
|
|
34
|
+
const args = { ...input.arguments, reason: input.reason ?? "" };
|
|
35
|
+
const outcome = await routeWriteCandidate({
|
|
36
|
+
mode: this.deps.mode,
|
|
37
|
+
approvals: this.deps.store,
|
|
38
|
+
profile: this.deps.profile,
|
|
39
|
+
now: this.deps.now,
|
|
40
|
+
}, {
|
|
41
|
+
tool: input.tool,
|
|
42
|
+
arguments: args,
|
|
43
|
+
preconditions,
|
|
44
|
+
risk: "write_catalog",
|
|
45
|
+
// 命令一律 pending:确认通道批准后才执行(任何模式都不自动执行)。
|
|
46
|
+
force_pending: true,
|
|
47
|
+
execute: (approvedArgs) => executor.execute(approvedArgs, this.deps.executorContext),
|
|
48
|
+
readPreconditions: () => executor.readPreconditions(input.arguments),
|
|
49
|
+
});
|
|
50
|
+
const candidate = "candidate" in outcome ? outcome.candidate : undefined;
|
|
51
|
+
if (candidate === undefined) {
|
|
52
|
+
throw new MerchantWorkbenchError("unavailable", "写门未产生候选");
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
candidate,
|
|
56
|
+
preview: {
|
|
57
|
+
tool: input.tool,
|
|
58
|
+
arguments: args,
|
|
59
|
+
before: preconditions,
|
|
60
|
+
note: "展示预览 ≠ 批准;批准 ≠ 执行成功(执行前重校验前置版本与硬策略)。",
|
|
61
|
+
},
|
|
62
|
+
outcome,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 批准并执行(确认通道;管理页面调用)。
|
|
67
|
+
* 授权主体一致性:调用主体必须等于命令记录主体(store 按 principal 绑定)。
|
|
68
|
+
* 配置了确认凭证存储时,必须携带与该候选内容/主体/动作匹配的一次性凭证。
|
|
69
|
+
*/
|
|
70
|
+
async executeApproved(commandId, callerPrincipalId, confirmationToken) {
|
|
71
|
+
if (callerPrincipalId !== this.deps.principalId) {
|
|
72
|
+
throw new MerchantWorkbenchError("auth", "批准主体与命令记录主体不一致(跨主体批准拒绝)");
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const candidate = this.deps.store.get(commandId);
|
|
76
|
+
if (candidate === undefined) {
|
|
77
|
+
throw new MerchantWorkbenchError("not_found", `未知命令 ${commandId}`);
|
|
78
|
+
}
|
|
79
|
+
const executor = this.deps.executors.get(candidate.tool);
|
|
80
|
+
if (executor === undefined) {
|
|
81
|
+
// 未注册工具的命令不可执行——fail-closed 失效。
|
|
82
|
+
this.deps.store.expireCandidate(commandId);
|
|
83
|
+
throw new MerchantWorkbenchError("validation", `命令 ${commandId} 的工具 ${candidate.tool} 未注册,已失效`);
|
|
84
|
+
}
|
|
85
|
+
// BUG-02:可信确认记录逐项核对(候选内容摘要/主体/商家/动作/有效期/单次)。
|
|
86
|
+
// 审查 P2:核销放在候选存在性/可执行性核对**之后**——候选已死时点击
|
|
87
|
+
// 批准不再白烧一次性凭证。
|
|
88
|
+
if (this.deps.confirmations !== undefined) {
|
|
89
|
+
const confirmation = this.deps.confirmations.consumeConfirmation(confirmationToken ?? "", {
|
|
90
|
+
candidateId: commandId,
|
|
91
|
+
candidateDigest: contentHash({
|
|
92
|
+
arguments: candidate.arguments,
|
|
93
|
+
preconditions: candidate.preconditions,
|
|
94
|
+
}),
|
|
95
|
+
principalId: callerPrincipalId,
|
|
96
|
+
merchantId: this.deps.profile.owner_id,
|
|
97
|
+
action: "approve",
|
|
98
|
+
});
|
|
99
|
+
if (confirmation === undefined) {
|
|
100
|
+
throw new MerchantWorkbenchError("validation", "确认凭证无效/已使用/已过期或不匹配——没有可信用户确认记录时写操作不可执行");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
this.deps.store.markApproved(commandId); // 过期/非 pending → 抛错(fail-closed)
|
|
104
|
+
const outcome = await executeApprovedCandidate(this.deps.store, commandId, {
|
|
105
|
+
readPreconditions: () => executor.readPreconditions(candidate.arguments),
|
|
106
|
+
execute: async (approvedArgs) => {
|
|
107
|
+
const output = await executor.execute(approvedArgs, this.deps.executorContext);
|
|
108
|
+
// 回读校验(写链路闭环)
|
|
109
|
+
await executor.verifyAfter?.(approvedArgs, this.deps.executorContext);
|
|
110
|
+
return output;
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
return outcome;
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
if (err instanceof MerchantWorkbenchError)
|
|
117
|
+
throw err;
|
|
118
|
+
if (err instanceof WriteApprovalCandidateError) {
|
|
119
|
+
throw new MerchantWorkbenchError(err.code === "not_found" ? "not_found" : "validation", err.message);
|
|
120
|
+
}
|
|
121
|
+
throw new MerchantWorkbenchError("unavailable", err instanceof Error ? err.message : String(err));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** 拒绝候选(确认通道;同样需确认凭证)。 */
|
|
125
|
+
async reject(commandId, callerPrincipalId, confirmationToken) {
|
|
126
|
+
if (callerPrincipalId !== this.deps.principalId) {
|
|
127
|
+
throw new MerchantWorkbenchError("auth", "拒绝主体与命令记录主体不一致");
|
|
128
|
+
}
|
|
129
|
+
const candidate = this.deps.store.get(commandId);
|
|
130
|
+
if (candidate === undefined) {
|
|
131
|
+
throw new MerchantWorkbenchError("not_found", `未知命令 ${commandId}`);
|
|
132
|
+
}
|
|
133
|
+
if (this.deps.confirmations !== undefined) {
|
|
134
|
+
const confirmation = this.deps.confirmations.consumeConfirmation(confirmationToken ?? "", {
|
|
135
|
+
candidateId: commandId,
|
|
136
|
+
candidateDigest: contentHash({
|
|
137
|
+
arguments: candidate.arguments,
|
|
138
|
+
preconditions: candidate.preconditions,
|
|
139
|
+
}),
|
|
140
|
+
principalId: callerPrincipalId,
|
|
141
|
+
merchantId: this.deps.profile.owner_id,
|
|
142
|
+
action: "reject",
|
|
143
|
+
});
|
|
144
|
+
if (confirmation === undefined) {
|
|
145
|
+
throw new MerchantWorkbenchError("validation", "确认凭证无效/已使用/已过期或不匹配(reject)");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return this.deps.store.reject(commandId);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* 重启恢复:从命令记录恢复全部已注册工具的 pending 命令(钩子按存储
|
|
152
|
+
* 参数经注册表确定性重建);未注册 tool 的命令 fail-closed 标 expired。
|
|
153
|
+
* 崩溃时停留在 executing 的候选一律 superseded(外部副作用不可判定,
|
|
154
|
+
* 绝不放行二次执行)。返回 { recovered, expiredUnknown, supersededExecuting }。
|
|
155
|
+
*/
|
|
156
|
+
recoverPending() {
|
|
157
|
+
let recovered = 0;
|
|
158
|
+
let expiredUnknown = 0;
|
|
159
|
+
for (const candidate of this.deps.store.listPending()) {
|
|
160
|
+
if (this.deps.executors.has(candidate.tool)) {
|
|
161
|
+
recovered += 1; // 钩子由注册表在执行时按存储参数重建,无需进程内闭包
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
this.deps.store.expireCandidate(candidate.candidate_id);
|
|
165
|
+
expiredUnknown += 1;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const supersededExecuting = this.deps.store.supersedeExecuting();
|
|
169
|
+
return { recovered, expiredUnknown, supersededExecuting };
|
|
170
|
+
}
|
|
171
|
+
listPending() {
|
|
172
|
+
return this.deps.store.listPending();
|
|
173
|
+
}
|
|
174
|
+
get(commandId) {
|
|
175
|
+
return this.deps.store.get(commandId);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export { WriteApprovalCandidateError };
|
|
179
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/merchant-core/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* 固定执行器注册表(V2 阶段三:src/merchant-core/executor.ts)。
|
|
18
|
+
*
|
|
19
|
+
* 执行器按 tool 名**静态注册**(禁止动态/字符串拼接分发到任意函数)——
|
|
20
|
+
* 注册表在进程启动时一次建成,未知 tool 名 fail-closed。每个执行器提供:
|
|
21
|
+
* - readPreconditions(args):重读目标对象当前状态(前置版本/digest);
|
|
22
|
+
* - execute(args):执行已批准参数(只执行命令记录里存储的参数);
|
|
23
|
+
* - verifyAfter?:执行后回读校验(写链路闭环的回读环节)。
|
|
24
|
+
*
|
|
25
|
+
* 恢复语义:进程重启后从命令记录(approval store)恢复 pending 时,钩子
|
|
26
|
+
* 由注册表按存储的 tool/arguments 确定性重建——不依赖任何进程内闭包。
|
|
27
|
+
*/
|
|
28
|
+
import type { MerchantClient } from "../agent/merchant/types.js";
|
|
29
|
+
import type { AgentProfile, MerchantPolicy } from "../config/profile.js";
|
|
30
|
+
import type { ApplyPolicyResult } from "./policy-runtime.js";
|
|
31
|
+
import type { MerchantOperationStore } from "./operations.js";
|
|
32
|
+
/** 执行器上下文(只读依赖 + 策略写接缝)。 */
|
|
33
|
+
export interface ExecutorContext {
|
|
34
|
+
merchantClient: MerchantClient;
|
|
35
|
+
profile: AgentProfile;
|
|
36
|
+
/** 商家 owner_id(导入/撤回执行归属)。 */
|
|
37
|
+
ownerId: string;
|
|
38
|
+
/** 长任务 operation store(CSV 导入/撤回等;缺省时相关执行器 fail-closed)。 */
|
|
39
|
+
operations?: MerchantOperationStore;
|
|
40
|
+
/** 策略热更新写入(F17/BUG-07):校验+原子写完整生效策略,返回版本/digest。 */
|
|
41
|
+
applyPolicyOverride?: ((patch: Record<string, unknown>) => Promise<ApplyPolicyResult>) | ((patch: Record<string, unknown>) => ApplyPolicyResult);
|
|
42
|
+
/** 运行中策略读取(BUG-07):配置后硬策略(底价兜底)按当前生效策略执行,
|
|
43
|
+
* 不再固定用启动 profile 的 merchant_policy。 */
|
|
44
|
+
currentPolicy?: () => MerchantPolicy | undefined;
|
|
45
|
+
/** F14 两轨人工处理:shopping 轨 resolve(A2A 轨绝不进这里)。 */
|
|
46
|
+
resolveShoppingReview?: (input: {
|
|
47
|
+
conversation_id: string;
|
|
48
|
+
resolution: string;
|
|
49
|
+
}) => Promise<unknown>;
|
|
50
|
+
}
|
|
51
|
+
/** 固定执行器(一个 tool 一个)。 */
|
|
52
|
+
export interface CommandExecutor {
|
|
53
|
+
readonly tool: string;
|
|
54
|
+
/** 重读目标对象前置状态(版本/digest 比对用)。 */
|
|
55
|
+
readPreconditions(args: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
56
|
+
/** 执行已批准参数。 */
|
|
57
|
+
execute(args: Record<string, unknown>, ctx: ExecutorContext): Promise<unknown>;
|
|
58
|
+
/** 执行后回读校验(可选;返回 false/抛错 = 回读不一致)。 */
|
|
59
|
+
verifyAfter?(args: Record<string, unknown>, ctx: ExecutorContext): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
export declare class MerchantExecutorRegistry {
|
|
62
|
+
private readonly registry;
|
|
63
|
+
private constructor();
|
|
64
|
+
/** 静态构造(固定白名单;新增写面必须显式加执行器)。 */
|
|
65
|
+
static buildDefault(ctx: ExecutorContext): MerchantExecutorRegistry;
|
|
66
|
+
get(tool: string): CommandExecutor | undefined;
|
|
67
|
+
has(tool: string): boolean;
|
|
68
|
+
tools(): string[];
|
|
69
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { parseProductCreateInput } from "../agent/merchant/types.js";
|
|
17
|
+
import { publicProductView } from "../merchant/workbench-service.js";
|
|
18
|
+
import { executeProductsImport } from "./product-import.js";
|
|
19
|
+
export class MerchantExecutorRegistry {
|
|
20
|
+
registry = new Map();
|
|
21
|
+
constructor(executors) {
|
|
22
|
+
for (const e of executors)
|
|
23
|
+
this.registry.set(e.tool, e);
|
|
24
|
+
}
|
|
25
|
+
/** 静态构造(固定白名单;新增写面必须显式加执行器)。 */
|
|
26
|
+
static buildDefault(ctx) {
|
|
27
|
+
const productPreconditions = async (args) => {
|
|
28
|
+
const sku = String(args.sku ?? "");
|
|
29
|
+
return publicProductView(await ctx.merchantClient.getProduct(sku));
|
|
30
|
+
};
|
|
31
|
+
/** 硬策略强制(执行器层兜底):价格变更不得低于私有底价(BUG-07:按
|
|
32
|
+
* 运行中生效策略校验,未配置运行中策略时回退启动 profile)。price 为
|
|
33
|
+
* undefined = 本次变更不涉及价格(跳过);非有限数值一律拒绝(审查 P1:
|
|
34
|
+
* 恒 false 比较会让底价检查纸面化)。 */
|
|
35
|
+
const enforceFloor = (price) => {
|
|
36
|
+
if (price === undefined)
|
|
37
|
+
return;
|
|
38
|
+
const floor = ctx.currentPolicy?.()?.min_unit_price_private ??
|
|
39
|
+
ctx.profile.merchant_policy?.min_unit_price_private;
|
|
40
|
+
if (floor === undefined)
|
|
41
|
+
return;
|
|
42
|
+
if (typeof price !== "number" || !Number.isFinite(price)) {
|
|
43
|
+
throw new Error("执行被硬策略拒绝:price 不是有限数值(不透出底价数值)");
|
|
44
|
+
}
|
|
45
|
+
if (price < floor) {
|
|
46
|
+
throw new Error("执行被硬策略拒绝:价格低于私有底价(不透出底价数值)");
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return new MerchantExecutorRegistry([
|
|
50
|
+
// V1 草稿候选(内部 tool 名不变——写门/恢复机制的历史标识)
|
|
51
|
+
{
|
|
52
|
+
tool: "draft_product_change",
|
|
53
|
+
readPreconditions: productPreconditions,
|
|
54
|
+
execute: async (args, c) => {
|
|
55
|
+
const changes = (args.changes ?? {});
|
|
56
|
+
enforceFloor(typeof changes.price === "number" ? changes.price : undefined);
|
|
57
|
+
return c.merchantClient.updateProduct(String(args.sku), changes);
|
|
58
|
+
},
|
|
59
|
+
verifyAfter: async (args, _c) => {
|
|
60
|
+
await productPreconditions(args); // 回读可达性校验(§16 前置重哈希已比内容)
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
tool: "kiwi_merchant_prepare_product_create",
|
|
65
|
+
// 审查 P1:执行前白名单重校验并钉死 merchant_id 归属——prepare 层
|
|
66
|
+
// 已校验(service),这里防御 store 参数被篡改/迁移旧库缺校验。
|
|
67
|
+
readPreconditions: async (args) => {
|
|
68
|
+
const product = (args.product ?? {});
|
|
69
|
+
const sku = String(product.sku ?? "");
|
|
70
|
+
// 已存在则旧授权失效(stale → superseded,见 executeApprovedCandidate)
|
|
71
|
+
let exists = false;
|
|
72
|
+
try {
|
|
73
|
+
await ctx.merchantClient.getProduct(sku);
|
|
74
|
+
exists = true;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
exists = false;
|
|
78
|
+
}
|
|
79
|
+
return { sku, exists };
|
|
80
|
+
},
|
|
81
|
+
execute: async (args, c) => {
|
|
82
|
+
const product = parseProductCreateInput(args.product, c.ownerId);
|
|
83
|
+
enforceFloor(product.price);
|
|
84
|
+
return c.merchantClient.createProduct(product);
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
tool: "kiwi_merchant_prepare_product_update",
|
|
89
|
+
readPreconditions: productPreconditions,
|
|
90
|
+
execute: async (args, c) => {
|
|
91
|
+
const changes = (args.changes ?? {});
|
|
92
|
+
enforceFloor(typeof changes.price === "number" ? changes.price : undefined);
|
|
93
|
+
return c.merchantClient.updateProduct(String(args.sku), changes);
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
tool: "kiwi_merchant_prepare_inventory_update",
|
|
98
|
+
readPreconditions: productPreconditions,
|
|
99
|
+
execute: async (args, c) => c.merchantClient.updateInventory(String(args.sku), Number(args.stock)),
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
// F08 语义落地:销售状态(paused flag);上游 shopping-cli 2.x 无端点
|
|
103
|
+
// → client fail-closed 报「不可得」(不库存写零伪装下架)。
|
|
104
|
+
tool: "kiwi_merchant_prepare_listing_change",
|
|
105
|
+
readPreconditions: productPreconditions,
|
|
106
|
+
execute: async (args, c) => c.merchantClient.pauseListing(String(args.sku), args.paused === true),
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
// F14 两轨人工处理:executor 只接 shopping 轨(路由守卫在命令准备层);
|
|
110
|
+
// A2A 轨人审由 A2A 侧机制处理,绝不进 shopping resolve。
|
|
111
|
+
tool: "kiwi_merchant_prepare_review_resolve",
|
|
112
|
+
readPreconditions: async (args) => ({
|
|
113
|
+
source_id: String(args.source_id ?? ""),
|
|
114
|
+
}),
|
|
115
|
+
execute: async (args, c) => {
|
|
116
|
+
if (c.resolveShoppingReview === undefined) {
|
|
117
|
+
throw new Error("shopping 轨人工处理接口未配置(不可得)");
|
|
118
|
+
}
|
|
119
|
+
return c.resolveShoppingReview({
|
|
120
|
+
conversation_id: String(args.source_id),
|
|
121
|
+
resolution: String(args.resolution ?? ""),
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
// F17 策略变更热更新(BUG-07):执行器经共享策略提供器校验+原子写
|
|
127
|
+
// 完整生效策略,A2A/执行器按运行中策略立即生效;回执带版本/digest。
|
|
128
|
+
tool: "kiwi_merchant_prepare_policy_change",
|
|
129
|
+
readPreconditions: async () => ({ scope: "merchant_policy" }),
|
|
130
|
+
execute: async (args, c) => {
|
|
131
|
+
if (c.applyPolicyOverride === undefined) {
|
|
132
|
+
throw new Error("策略热更新接缝未配置(不可得)");
|
|
133
|
+
}
|
|
134
|
+
const patch = (args.patch ?? {});
|
|
135
|
+
const result = await c.applyPolicyOverride(patch);
|
|
136
|
+
return {
|
|
137
|
+
applied: true,
|
|
138
|
+
version: result.version,
|
|
139
|
+
digest: result.digest,
|
|
140
|
+
updated_at: result.updated_at,
|
|
141
|
+
applied_keys: result.applied_keys,
|
|
142
|
+
};
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
// F04 CSV 导入(长任务 + 幂等键 + 逐项回执)。
|
|
147
|
+
tool: "kiwi_merchant_prepare_products_import",
|
|
148
|
+
// 幂等由 operation store 承载(同幂等键返回同一 operation),前置版本
|
|
149
|
+
// 用静态摘要(导入是批量意图,不因目录其他变化失效)。
|
|
150
|
+
readPreconditions: async (args) => ({
|
|
151
|
+
idempotency_key: String(args.idempotency_key ?? ""),
|
|
152
|
+
lines: String(args.csv ?? "")
|
|
153
|
+
.split(/\r?\n/)
|
|
154
|
+
.filter((l) => l.trim() !== "").length,
|
|
155
|
+
}),
|
|
156
|
+
execute: async (args, c) => {
|
|
157
|
+
if (c.operations === undefined) {
|
|
158
|
+
throw new Error("operation store 未配置(不可得)");
|
|
159
|
+
}
|
|
160
|
+
return executeProductsImport({
|
|
161
|
+
csv: String(args.csv ?? ""),
|
|
162
|
+
idempotencyKey: String(args.idempotency_key ?? ""),
|
|
163
|
+
merchantId: c.ownerId,
|
|
164
|
+
merchantClient: c.merchantClient,
|
|
165
|
+
operations: c.operations,
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
// F04 撤回(listing 销售状态语义;上游无端点 → 逐项回执失败,不库存写零)。
|
|
171
|
+
tool: "kiwi_merchant_prepare_products_withdraw",
|
|
172
|
+
readPreconditions: async (args) => ({
|
|
173
|
+
skus: Array.isArray(args.skus) ? args.skus.length : 0,
|
|
174
|
+
}),
|
|
175
|
+
execute: async (args, c) => {
|
|
176
|
+
if (c.operations === undefined) {
|
|
177
|
+
throw new Error("operation store 未配置(不可得)");
|
|
178
|
+
}
|
|
179
|
+
const skus = Array.isArray(args.skus) ? args.skus.map(String) : [];
|
|
180
|
+
const op = c.operations.createOrGet({
|
|
181
|
+
kind: "products_withdraw",
|
|
182
|
+
idempotencyKey: String(args.idempotency_key ?? ""),
|
|
183
|
+
});
|
|
184
|
+
if (!op.created)
|
|
185
|
+
return op.operation; // 幂等:不重复撤回
|
|
186
|
+
c.operations.markRunning(op.operation.operation_id);
|
|
187
|
+
const receipts = [];
|
|
188
|
+
for (const sku of skus) {
|
|
189
|
+
try {
|
|
190
|
+
await c.merchantClient.pauseListing(sku, true);
|
|
191
|
+
receipts.push({ item: sku, ok: true });
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
receipts.push({
|
|
195
|
+
item: sku,
|
|
196
|
+
ok: false,
|
|
197
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const finished = c.operations.finish(op.operation.operation_id, receipts);
|
|
202
|
+
// 全部项失败 → ok:false(审查 P1:否则候选仍被标 executed,审计谎报成功)
|
|
203
|
+
return finished.status === "failed" ? { ok: false, operation: finished } : finished;
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
]);
|
|
207
|
+
}
|
|
208
|
+
get(tool) {
|
|
209
|
+
return this.registry.get(tool);
|
|
210
|
+
}
|
|
211
|
+
has(tool) {
|
|
212
|
+
return this.registry.has(tool);
|
|
213
|
+
}
|
|
214
|
+
tools() {
|
|
215
|
+
return [...this.registry.keys()];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/merchant-core/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* 两轨磋商适配器(V2 §5.2;阶段二)。
|
|
18
|
+
*
|
|
19
|
+
* Kiwi Merchant 同时存在两条磋商轨:
|
|
20
|
+
* - a2a:A2A/KNP 轨(Ledger 权威,相位机状态名 OPEN/OFFER_OPEN/…);
|
|
21
|
+
* - shopping:shopping-cli 会话轨(conversation 状态名 waiting_merchant/…)。
|
|
22
|
+
*
|
|
23
|
+
* 统一列表:每条携带 source_protocol 与 source_id;详情保留各自协议的
|
|
24
|
+
* 状态名(不抹平)。人工处理入口按来源路由——A2A 人审走 A2A 侧机制,
|
|
25
|
+
* 绝不调 shopping-cli resolve-review;shopping 轨才走上游接口。
|
|
26
|
+
*/
|
|
27
|
+
import type { IncomingConsultation } from "../agent/merchant/types.js";
|
|
28
|
+
import type { A2aNegotiationRow } from "../merchant/workbench-service.js";
|
|
29
|
+
/** 磋商来源协议(两轨)。 */
|
|
30
|
+
export type NegotiationSourceProtocol = "a2a" | "shopping";
|
|
31
|
+
/** 统一磋商列表行(状态名保留各自协议口径,不抹平)。 */
|
|
32
|
+
export interface UnifiedNegotiationRow {
|
|
33
|
+
source_protocol: NegotiationSourceProtocol;
|
|
34
|
+
/** 轨道内 id:a2a = negotiation_id;shopping = conversation_id。 */
|
|
35
|
+
source_id: string;
|
|
36
|
+
/** 协议原生状态名(a2a 相位 / shopping 会话 status)。 */
|
|
37
|
+
status: string;
|
|
38
|
+
sku?: string;
|
|
39
|
+
buyer?: string;
|
|
40
|
+
updated_at: string;
|
|
41
|
+
needs_human_review: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** A2A 轨行 → 统一行。needsHumanReview 由调用方按轨道语义计算传入
|
|
44
|
+
* (A2A 侧权威口径在 intelligence 的 extractNegotiation:AWAITING_CLARIFICATION
|
|
45
|
+
* 或「非终态且最后一条为买家入站等待商家回应」)。 */
|
|
46
|
+
export declare function fromA2aRow(row: A2aNegotiationRow, needsHumanReview: boolean): UnifiedNegotiationRow;
|
|
47
|
+
/** shopping 会话轨行 → 统一行。 */
|
|
48
|
+
export declare function fromShoppingConsultation(c: IncomingConsultation): UnifiedNegotiationRow;
|
|
49
|
+
/** 人工处理路由(V2 §5.2):按来源返回处理通道,跨轨调用直接拒绝。 */
|
|
50
|
+
export declare function routeHumanReview(row: UnifiedNegotiationRow): "a2a" | "shopping";
|
|
51
|
+
/**
|
|
52
|
+
* 路由守卫:对 A2A 来源的磋商调用 shopping 轨处理接口(resolve-review)是
|
|
53
|
+
* 协议错误——fail-closed 抛错,绝不跨轨执行。
|
|
54
|
+
*/
|
|
55
|
+
export declare function assertReviewRoute(sourceProtocol: NegotiationSourceProtocol, channel: "a2a" | "shopping"): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/** A2A 轨行 → 统一行。needsHumanReview 由调用方按轨道语义计算传入
|
|
17
|
+
* (A2A 侧权威口径在 intelligence 的 extractNegotiation:AWAITING_CLARIFICATION
|
|
18
|
+
* 或「非终态且最后一条为买家入站等待商家回应」)。 */
|
|
19
|
+
export function fromA2aRow(row, needsHumanReview) {
|
|
20
|
+
return {
|
|
21
|
+
source_protocol: "a2a",
|
|
22
|
+
source_id: row.negotiation_id,
|
|
23
|
+
status: row.phase,
|
|
24
|
+
...(row.sku !== "" ? { sku: row.sku } : {}),
|
|
25
|
+
updated_at: row.recorded_at,
|
|
26
|
+
needs_human_review: needsHumanReview,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** shopping 会话轨行 → 统一行。 */
|
|
30
|
+
export function fromShoppingConsultation(c) {
|
|
31
|
+
return {
|
|
32
|
+
source_protocol: "shopping",
|
|
33
|
+
source_id: c.conversation_id,
|
|
34
|
+
status: c.status,
|
|
35
|
+
...(c.sku !== undefined ? { sku: c.sku } : {}),
|
|
36
|
+
...(c.buyer_id !== undefined ? { buyer: c.buyer_id } : {}),
|
|
37
|
+
updated_at: c.last_message_at,
|
|
38
|
+
needs_human_review: c.status === "human_required",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** 人工处理路由(V2 §5.2):按来源返回处理通道,跨轨调用直接拒绝。 */
|
|
42
|
+
export function routeHumanReview(row) {
|
|
43
|
+
return row.source_protocol;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 路由守卫:对 A2A 来源的磋商调用 shopping 轨处理接口(resolve-review)是
|
|
47
|
+
* 协议错误——fail-closed 抛错,绝不跨轨执行。
|
|
48
|
+
*/
|
|
49
|
+
export function assertReviewRoute(sourceProtocol, channel) {
|
|
50
|
+
if (sourceProtocol !== channel) {
|
|
51
|
+
throw new Error(`人工处理路由错误:${sourceProtocol} 轨磋商不能走 ${channel} 通道` +
|
|
52
|
+
"(A2A 人审走 A2A 侧机制,shopping 轨才走 shopping-cli resolve-review)");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=negotiation-adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"negotiation-adapters.js","sourceRoot":"","sources":["../../src/merchant-core/negotiation-adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAiCH;;+BAE+B;AAC/B,MAAM,UAAU,UAAU,CACxB,GAAsB,EACtB,gBAAyB;IAEzB,OAAO;QACL,eAAe,EAAE,KAAK;QACtB,SAAS,EAAE,GAAG,CAAC,cAAc;QAC7B,MAAM,EAAE,GAAG,CAAC,KAAK;QACjB,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,kBAAkB,EAAE,gBAAgB;KACrC,CAAC;AACJ,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,wBAAwB,CAAC,CAAuB;IAC9D,OAAO;QACL,eAAe,EAAE,UAAU;QAC3B,SAAS,EAAE,CAAC,CAAC,eAAe;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,UAAU,EAAE,CAAC,CAAC,eAAe;QAC7B,kBAAkB,EAAE,CAAC,CAAC,MAAM,KAAK,gBAAgB;KAClD,CAAC;AACJ,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,gBAAgB,CAAC,GAA0B;IACzD,OAAO,GAAG,CAAC,eAAe,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,cAAyC,EACzC,OAA2B;IAE3B,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,YAAY,cAAc,WAAW,OAAO,KAAK;YAC/C,4DAA4D,CAC/D,CAAC;IACJ,CAAC;AACH,CAAC"}
|