@harrylabsj/kiwi 0.6.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/LICENSE +201 -0
- package/README.md +150 -0
- package/contracts/candidate-agent-dto-1.0.README.md +39 -0
- package/contracts/candidate-agent-dto-1.0.schema.json +172 -0
- package/contracts/interop/kiwi-buyer-message-send.json +43 -0
- package/contracts/interop/knp-data-part-examples.json +243 -0
- package/contracts/kiwi-catalog/1.0/agent-record.schema.json +78 -0
- package/contracts/kiwi-catalog/1.0/listing-record.schema.json +88 -0
- package/contracts/kiwi-catalog/1.0/listing-search-result.schema.json +60 -0
- package/contracts/negotiation/1.0/schema.json +501 -0
- package/contracts/shopping.negotiation/0.1/capabilities.schema.json +47 -0
- package/contracts/shopping.negotiation/0.1/decision.schema.json +120 -0
- package/contracts/shopping.negotiation/0.1/policy-result.schema.json +52 -0
- package/contracts/shopping.negotiation/0.1/snapshot.schema.json +172 -0
- package/dist/a2a/client/client.d.ts +33 -0
- package/dist/a2a/client/client.js +161 -0
- package/dist/a2a/client/client.js.map +1 -0
- package/dist/a2a/client/error.d.ts +35 -0
- package/dist/a2a/client/error.js +34 -0
- package/dist/a2a/client/error.js.map +1 -0
- package/dist/a2a/client/index.d.ts +29 -0
- package/dist/a2a/client/index.js +26 -0
- package/dist/a2a/client/index.js.map +1 -0
- package/dist/a2a/client/jsonrpc.d.ts +49 -0
- package/dist/a2a/client/jsonrpc.js +85 -0
- package/dist/a2a/client/jsonrpc.js.map +1 -0
- package/dist/a2a/client/parse.d.ts +18 -0
- package/dist/a2a/client/parse.js +134 -0
- package/dist/a2a/client/parse.js.map +1 -0
- package/dist/a2a/client/types.d.ts +102 -0
- package/dist/a2a/client/types.js +26 -0
- package/dist/a2a/client/types.js.map +1 -0
- package/dist/a2a/client/url-policy.d.ts +44 -0
- package/dist/a2a/client/url-policy.js +242 -0
- package/dist/a2a/client/url-policy.js.map +1 -0
- package/dist/a2a/negotiate.d.ts +68 -0
- package/dist/a2a/negotiate.js +288 -0
- package/dist/a2a/negotiate.js.map +1 -0
- package/dist/a2a/node.d.ts +37 -0
- package/dist/a2a/node.js +155 -0
- package/dist/a2a/node.js.map +1 -0
- package/dist/a2a/server/auth.d.ts +38 -0
- package/dist/a2a/server/auth.js +112 -0
- package/dist/a2a/server/auth.js.map +1 -0
- package/dist/a2a/server/card.d.ts +19 -0
- package/dist/a2a/server/card.js +81 -0
- package/dist/a2a/server/card.js.map +1 -0
- package/dist/a2a/server/errors.d.ts +109 -0
- package/dist/a2a/server/errors.js +178 -0
- package/dist/a2a/server/errors.js.map +1 -0
- package/dist/a2a/server/handler.d.ts +22 -0
- package/dist/a2a/server/handler.js +57 -0
- package/dist/a2a/server/handler.js.map +1 -0
- package/dist/a2a/server/inbound-message.d.ts +37 -0
- package/dist/a2a/server/inbound-message.js +104 -0
- package/dist/a2a/server/inbound-message.js.map +1 -0
- package/dist/a2a/server/index.d.ts +43 -0
- package/dist/a2a/server/index.js +42 -0
- package/dist/a2a/server/index.js.map +1 -0
- package/dist/a2a/server/merchant-handler.d.ts +69 -0
- package/dist/a2a/server/merchant-handler.js +316 -0
- package/dist/a2a/server/merchant-handler.js.map +1 -0
- package/dist/a2a/server/pipeline.d.ts +69 -0
- package/dist/a2a/server/pipeline.js +329 -0
- package/dist/a2a/server/pipeline.js.map +1 -0
- package/dist/a2a/server/server.d.ts +64 -0
- package/dist/a2a/server/server.js +420 -0
- package/dist/a2a/server/server.js.map +1 -0
- package/dist/a2a/server/task-registry.d.ts +31 -0
- package/dist/a2a/server/task-registry.js +67 -0
- package/dist/a2a/server/task-registry.js.map +1 -0
- package/dist/a2a/server/throttle.d.ts +154 -0
- package/dist/a2a/server/throttle.js +289 -0
- package/dist/a2a/server/throttle.js.map +1 -0
- package/dist/a2a/server/types.d.ts +191 -0
- package/dist/a2a/server/types.js +17 -0
- package/dist/a2a/server/types.js.map +1 -0
- package/dist/a2a/server/ucp.d.ts +49 -0
- package/dist/a2a/server/ucp.js +85 -0
- package/dist/a2a/server/ucp.js.map +1 -0
- package/dist/a2a/task/index.d.ts +24 -0
- package/dist/a2a/task/index.js +22 -0
- package/dist/a2a/task/index.js.map +1 -0
- package/dist/a2a/task/ledger.d.ts +48 -0
- package/dist/a2a/task/ledger.js +65 -0
- package/dist/a2a/task/ledger.js.map +1 -0
- package/dist/a2a/task/poller.d.ts +93 -0
- package/dist/a2a/task/poller.js +184 -0
- package/dist/a2a/task/poller.js.map +1 -0
- package/dist/a2a/task/state.d.ts +72 -0
- package/dist/a2a/task/state.js +119 -0
- package/dist/a2a/task/state.js.map +1 -0
- package/dist/a2a/ucp-agent.d.ts +49 -0
- package/dist/a2a/ucp-agent.js +78 -0
- package/dist/a2a/ucp-agent.js.map +1 -0
- package/dist/agent/agent-db.d.ts +31 -0
- package/dist/agent/agent-db.js +91 -0
- package/dist/agent/agent-db.js.map +1 -0
- package/dist/agent/buyer/buyer-tools.d.ts +70 -0
- package/dist/agent/buyer/buyer-tools.js +1353 -0
- package/dist/agent/buyer/buyer-tools.js.map +1 -0
- package/dist/agent/buyer/ranker.d.ts +53 -0
- package/dist/agent/buyer/ranker.js +153 -0
- package/dist/agent/buyer/ranker.js.map +1 -0
- package/dist/agent/buyer/scheduler.d.ts +58 -0
- package/dist/agent/buyer/scheduler.js +317 -0
- package/dist/agent/buyer/scheduler.js.map +1 -0
- package/dist/agent/buyer/search-loop.d.ts +42 -0
- package/dist/agent/buyer/search-loop.js +280 -0
- package/dist/agent/buyer/search-loop.js.map +1 -0
- package/dist/agent/buyer/task-store.d.ts +178 -0
- package/dist/agent/buyer/task-store.js +637 -0
- package/dist/agent/buyer/task-store.js.map +1 -0
- package/dist/agent/buyer/types.d.ts +222 -0
- package/dist/agent/buyer/types.js +124 -0
- package/dist/agent/buyer/types.js.map +1 -0
- package/dist/agent/chat-tools.d.ts +41 -0
- package/dist/agent/chat-tools.js +193 -0
- package/dist/agent/chat-tools.js.map +1 -0
- package/dist/agent/chat-tui.d.ts +49 -0
- package/dist/agent/chat-tui.js +314 -0
- package/dist/agent/chat-tui.js.map +1 -0
- package/dist/agent/connector/fake-connector.d.ts +50 -0
- package/dist/agent/connector/fake-connector.js +138 -0
- package/dist/agent/connector/fake-connector.js.map +1 -0
- package/dist/agent/connector/http-connector.d.ts +49 -0
- package/dist/agent/connector/http-connector.js +208 -0
- package/dist/agent/connector/http-connector.js.map +1 -0
- package/dist/agent/connector/types.d.ts +103 -0
- package/dist/agent/connector/types.js +97 -0
- package/dist/agent/connector/types.js.map +1 -0
- package/dist/agent/fake-chat-model.d.ts +22 -0
- package/dist/agent/fake-chat-model.js +134 -0
- package/dist/agent/fake-chat-model.js.map +1 -0
- package/dist/agent/kernel.d.ts +258 -0
- package/dist/agent/kernel.js +1099 -0
- package/dist/agent/kernel.js.map +1 -0
- package/dist/agent/memory/schema.d.ts +32 -0
- package/dist/agent/memory/schema.js +291 -0
- package/dist/agent/memory/schema.js.map +1 -0
- package/dist/agent/memory/store.d.ts +193 -0
- package/dist/agent/memory/store.js +881 -0
- package/dist/agent/memory/store.js.map +1 -0
- package/dist/agent/memory/types.d.ts +139 -0
- package/dist/agent/memory/types.js +119 -0
- package/dist/agent/memory/types.js.map +1 -0
- package/dist/agent/memory/vault.d.ts +49 -0
- package/dist/agent/memory/vault.js +125 -0
- package/dist/agent/memory/vault.js.map +1 -0
- package/dist/agent/merchant/action-candidate.d.ts +106 -0
- package/dist/agent/merchant/action-candidate.js +241 -0
- package/dist/agent/merchant/action-candidate.js.map +1 -0
- package/dist/agent/merchant/credential-broker.d.ts +67 -0
- package/dist/agent/merchant/credential-broker.js +76 -0
- package/dist/agent/merchant/credential-broker.js.map +1 -0
- package/dist/agent/merchant/fake-merchant-client.d.ts +47 -0
- package/dist/agent/merchant/fake-merchant-client.js +143 -0
- package/dist/agent/merchant/fake-merchant-client.js.map +1 -0
- package/dist/agent/merchant/merchant-client.d.ts +49 -0
- package/dist/agent/merchant/merchant-client.js +186 -0
- package/dist/agent/merchant/merchant-client.js.map +1 -0
- package/dist/agent/merchant/merchant-tools.d.ts +74 -0
- package/dist/agent/merchant/merchant-tools.js +582 -0
- package/dist/agent/merchant/merchant-tools.js.map +1 -0
- package/dist/agent/merchant/types.d.ts +119 -0
- package/dist/agent/merchant/types.js +133 -0
- package/dist/agent/merchant/types.js.map +1 -0
- package/dist/agent/mode.d.ts +32 -0
- package/dist/agent/mode.js +34 -0
- package/dist/agent/mode.js.map +1 -0
- package/dist/agent/negotiation-chat.d.ts +81 -0
- package/dist/agent/negotiation-chat.js +330 -0
- package/dist/agent/negotiation-chat.js.map +1 -0
- package/dist/agent/session.d.ts +22 -0
- package/dist/agent/session.js +164 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/agent/system-prompt.d.ts +26 -0
- package/dist/agent/system-prompt.js +77 -0
- package/dist/agent/system-prompt.js.map +1 -0
- package/dist/agent/write-gate.d.ts +98 -0
- package/dist/agent/write-gate.js +76 -0
- package/dist/agent/write-gate.js.map +1 -0
- package/dist/cli.d.ts +18 -0
- package/dist/cli.js +1139 -0
- package/dist/cli.js.map +1 -0
- package/dist/commerce/data-source.d.ts +88 -0
- package/dist/commerce/data-source.js +25 -0
- package/dist/commerce/data-source.js.map +1 -0
- package/dist/commerce/erp-source.d.ts +51 -0
- package/dist/commerce/erp-source.js +184 -0
- package/dist/commerce/erp-source.js.map +1 -0
- package/dist/commerce/fake-client.d.ts +167 -0
- package/dist/commerce/fake-client.js +549 -0
- package/dist/commerce/fake-client.js.map +1 -0
- package/dist/commerce/http-client.d.ts +73 -0
- package/dist/commerce/http-client.js +284 -0
- package/dist/commerce/http-client.js.map +1 -0
- package/dist/commerce/local-db-source.d.ts +50 -0
- package/dist/commerce/local-db-source.js +162 -0
- package/dist/commerce/local-db-source.js.map +1 -0
- package/dist/commerce/shopping-cli-source.d.ts +57 -0
- package/dist/commerce/shopping-cli-source.js +206 -0
- package/dist/commerce/shopping-cli-source.js.map +1 -0
- package/dist/commerce/types.d.ts +146 -0
- package/dist/commerce/types.js +31 -0
- package/dist/commerce/types.js.map +1 -0
- package/dist/config/profile.d.ts +122 -0
- package/dist/config/profile.js +386 -0
- package/dist/config/profile.js.map +1 -0
- package/dist/contracts/negotiation-schema.d.ts +28 -0
- package/dist/contracts/negotiation-schema.js +101 -0
- package/dist/contracts/negotiation-schema.js.map +1 -0
- package/dist/contracts/schemas.d.ts +31 -0
- package/dist/contracts/schemas.js +122 -0
- package/dist/contracts/schemas.js.map +1 -0
- package/dist/counterparty/a2a-direct/index.d.ts +41 -0
- package/dist/counterparty/a2a-direct/index.js +330 -0
- package/dist/counterparty/a2a-direct/index.js.map +1 -0
- package/dist/counterparty/channel.d.ts +200 -0
- package/dist/counterparty/channel.js +61 -0
- package/dist/counterparty/channel.js.map +1 -0
- package/dist/counterparty/index.d.ts +28 -0
- package/dist/counterparty/index.js +24 -0
- package/dist/counterparty/index.js.map +1 -0
- package/dist/counterparty/platform-api/index.d.ts +41 -0
- package/dist/counterparty/platform-api/index.js +65 -0
- package/dist/counterparty/platform-api/index.js.map +1 -0
- package/dist/counterparty/registry.d.ts +51 -0
- package/dist/counterparty/registry.js +71 -0
- package/dist/counterparty/registry.js.map +1 -0
- package/dist/counterparty/shopping-cli-hosted/index.d.ts +36 -0
- package/dist/counterparty/shopping-cli-hosted/index.js +337 -0
- package/dist/counterparty/shopping-cli-hosted/index.js.map +1 -0
- package/dist/discovery/agent-card/error.d.ts +28 -0
- package/dist/discovery/agent-card/error.js +31 -0
- package/dist/discovery/agent-card/error.js.map +1 -0
- package/dist/discovery/agent-card/extensions.d.ts +20 -0
- package/dist/discovery/agent-card/extensions.js +59 -0
- package/dist/discovery/agent-card/extensions.js.map +1 -0
- package/dist/discovery/agent-card/index.d.ts +29 -0
- package/dist/discovery/agent-card/index.js +38 -0
- package/dist/discovery/agent-card/index.js.map +1 -0
- package/dist/discovery/agent-card/secrets.d.ts +30 -0
- package/dist/discovery/agent-card/secrets.js +240 -0
- package/dist/discovery/agent-card/secrets.js.map +1 -0
- package/dist/discovery/agent-card/types.d.ts +110 -0
- package/dist/discovery/agent-card/types.js +37 -0
- package/dist/discovery/agent-card/types.js.map +1 -0
- package/dist/discovery/agent-card/validate.d.ts +31 -0
- package/dist/discovery/agent-card/validate.js +210 -0
- package/dist/discovery/agent-card/validate.js.map +1 -0
- package/dist/discovery/capability/error.d.ts +23 -0
- package/dist/discovery/capability/error.js +28 -0
- package/dist/discovery/capability/error.js.map +1 -0
- package/dist/discovery/capability/index.d.ts +21 -0
- package/dist/discovery/capability/index.js +21 -0
- package/dist/discovery/capability/index.js.map +1 -0
- package/dist/discovery/capability/intersect.d.ts +56 -0
- package/dist/discovery/capability/intersect.js +137 -0
- package/dist/discovery/capability/intersect.js.map +1 -0
- package/dist/discovery/catalog-source/errors.d.ts +32 -0
- package/dist/discovery/catalog-source/errors.js +41 -0
- package/dist/discovery/catalog-source/errors.js.map +1 -0
- package/dist/discovery/catalog-source/index.d.ts +30 -0
- package/dist/discovery/catalog-source/index.js +29 -0
- package/dist/discovery/catalog-source/index.js.map +1 -0
- package/dist/discovery/catalog-source/kiwi-record.d.ts +183 -0
- package/dist/discovery/catalog-source/kiwi-record.js +72 -0
- package/dist/discovery/catalog-source/kiwi-record.js.map +1 -0
- package/dist/discovery/catalog-source/kiwi-schema.d.ts +33 -0
- package/dist/discovery/catalog-source/kiwi-schema.js +106 -0
- package/dist/discovery/catalog-source/kiwi-schema.js.map +1 -0
- package/dist/discovery/catalog-source/kiwi-source.d.ts +38 -0
- package/dist/discovery/catalog-source/kiwi-source.js +318 -0
- package/dist/discovery/catalog-source/kiwi-source.js.map +1 -0
- package/dist/discovery/catalog-source/register.d.ts +48 -0
- package/dist/discovery/catalog-source/register.js +83 -0
- package/dist/discovery/catalog-source/register.js.map +1 -0
- package/dist/discovery/catalog-source/schema.d.ts +21 -0
- package/dist/discovery/catalog-source/schema.js +63 -0
- package/dist/discovery/catalog-source/schema.js.map +1 -0
- package/dist/discovery/catalog-source/source.d.ts +45 -0
- package/dist/discovery/catalog-source/source.js +197 -0
- package/dist/discovery/catalog-source/source.js.map +1 -0
- package/dist/discovery/catalog-source/types.d.ts +122 -0
- package/dist/discovery/catalog-source/types.js +30 -0
- package/dist/discovery/catalog-source/types.js.map +1 -0
- package/dist/discovery/index.d.ts +25 -0
- package/dist/discovery/index.js +25 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/resolve.d.ts +175 -0
- package/dist/discovery/resolve.js +367 -0
- package/dist/discovery/resolve.js.map +1 -0
- package/dist/discovery/ucp/error.d.ts +25 -0
- package/dist/discovery/ucp/error.js +27 -0
- package/dist/discovery/ucp/error.js.map +1 -0
- package/dist/discovery/ucp/index.d.ts +33 -0
- package/dist/discovery/ucp/index.js +28 -0
- package/dist/discovery/ucp/index.js.map +1 -0
- package/dist/discovery/ucp/intersect.d.ts +148 -0
- package/dist/discovery/ucp/intersect.js +312 -0
- package/dist/discovery/ucp/intersect.js.map +1 -0
- package/dist/discovery/ucp/resolver.d.ts +62 -0
- package/dist/discovery/ucp/resolver.js +214 -0
- package/dist/discovery/ucp/resolver.js.map +1 -0
- package/dist/discovery/ucp/types.d.ts +97 -0
- package/dist/discovery/ucp/types.js +103 -0
- package/dist/discovery/ucp/types.js.map +1 -0
- package/dist/discovery/ucp/validate.d.ts +38 -0
- package/dist/discovery/ucp/validate.js +232 -0
- package/dist/discovery/ucp/validate.js.map +1 -0
- package/dist/discovery/ucp/vendor.d.ts +60 -0
- package/dist/discovery/ucp/vendor.js +61 -0
- package/dist/discovery/ucp/vendor.js.map +1 -0
- package/dist/doctor.d.ts +26 -0
- package/dist/doctor.js +113 -0
- package/dist/doctor.js.map +1 -0
- package/dist/exit-codes.d.ts +26 -0
- package/dist/exit-codes.js +27 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/fanout/disclosure.d.ts +138 -0
- package/dist/fanout/disclosure.js +188 -0
- package/dist/fanout/disclosure.js.map +1 -0
- package/dist/fanout/index.d.ts +32 -0
- package/dist/fanout/index.js +30 -0
- package/dist/fanout/index.js.map +1 -0
- package/dist/fanout/orchestrator.d.ts +153 -0
- package/dist/fanout/orchestrator.js +439 -0
- package/dist/fanout/orchestrator.js.map +1 -0
- package/dist/fanout/policy.d.ts +128 -0
- package/dist/fanout/policy.js +130 -0
- package/dist/fanout/policy.js.map +1 -0
- package/dist/handoff/acp-commerce.d.ts +58 -0
- package/dist/handoff/acp-commerce.js +69 -0
- package/dist/handoff/acp-commerce.js.map +1 -0
- package/dist/handoff/authorization.d.ts +127 -0
- package/dist/handoff/authorization.js +107 -0
- package/dist/handoff/authorization.js.map +1 -0
- package/dist/handoff/candidate.d.ts +94 -0
- package/dist/handoff/candidate.js +172 -0
- package/dist/handoff/candidate.js.map +1 -0
- package/dist/handoff/channel.d.ts +88 -0
- package/dist/handoff/channel.js +189 -0
- package/dist/handoff/channel.js.map +1 -0
- package/dist/handoff/completion.d.ts +44 -0
- package/dist/handoff/completion.js +136 -0
- package/dist/handoff/completion.js.map +1 -0
- package/dist/handoff/delivery.d.ts +59 -0
- package/dist/handoff/delivery.js +185 -0
- package/dist/handoff/delivery.js.map +1 -0
- package/dist/handoff/destination.d.ts +39 -0
- package/dist/handoff/destination.js +99 -0
- package/dist/handoff/destination.js.map +1 -0
- package/dist/handoff/errors.d.ts +34 -0
- package/dist/handoff/errors.js +47 -0
- package/dist/handoff/errors.js.map +1 -0
- package/dist/handoff/idempotency.d.ts +51 -0
- package/dist/handoff/idempotency.js +168 -0
- package/dist/handoff/idempotency.js.map +1 -0
- package/dist/handoff/index.d.ts +46 -0
- package/dist/handoff/index.js +48 -0
- package/dist/handoff/index.js.map +1 -0
- package/dist/handoff/ledger.d.ts +94 -0
- package/dist/handoff/ledger.js +195 -0
- package/dist/handoff/ledger.js.map +1 -0
- package/dist/handoff/lifecycle.d.ts +29 -0
- package/dist/handoff/lifecycle.js +102 -0
- package/dist/handoff/lifecycle.js.map +1 -0
- package/dist/handoff/metrics.d.ts +56 -0
- package/dist/handoff/metrics.js +78 -0
- package/dist/handoff/metrics.js.map +1 -0
- package/dist/handoff/operator-approval.d.ts +143 -0
- package/dist/handoff/operator-approval.js +287 -0
- package/dist/handoff/operator-approval.js.map +1 -0
- package/dist/handoff/order-record.d.ts +104 -0
- package/dist/handoff/order-record.js +235 -0
- package/dist/handoff/order-record.js.map +1 -0
- package/dist/handoff/package.d.ts +102 -0
- package/dist/handoff/package.js +132 -0
- package/dist/handoff/package.js.map +1 -0
- package/dist/handoff/transaction.d.ts +96 -0
- package/dist/handoff/transaction.js +263 -0
- package/dist/handoff/transaction.js.map +1 -0
- package/dist/handoff/ucp-checkout/cart-channel.d.ts +111 -0
- package/dist/handoff/ucp-checkout/cart-channel.js +370 -0
- package/dist/handoff/ucp-checkout/cart-channel.js.map +1 -0
- package/dist/handoff/ucp-checkout/cart-parse.d.ts +22 -0
- package/dist/handoff/ucp-checkout/cart-parse.js +102 -0
- package/dist/handoff/ucp-checkout/cart-parse.js.map +1 -0
- package/dist/handoff/ucp-checkout/cart-types.d.ts +93 -0
- package/dist/handoff/ucp-checkout/cart-types.js +38 -0
- package/dist/handoff/ucp-checkout/cart-types.js.map +1 -0
- package/dist/handoff/ucp-checkout/channel.d.ts +159 -0
- package/dist/handoff/ucp-checkout/channel.js +636 -0
- package/dist/handoff/ucp-checkout/channel.js.map +1 -0
- package/dist/handoff/ucp-checkout/client.d.ts +88 -0
- package/dist/handoff/ucp-checkout/client.js +228 -0
- package/dist/handoff/ucp-checkout/client.js.map +1 -0
- package/dist/handoff/ucp-checkout/endpoint.d.ts +36 -0
- package/dist/handoff/ucp-checkout/endpoint.js +145 -0
- package/dist/handoff/ucp-checkout/endpoint.js.map +1 -0
- package/dist/handoff/ucp-checkout/index.d.ts +35 -0
- package/dist/handoff/ucp-checkout/index.js +36 -0
- package/dist/handoff/ucp-checkout/index.js.map +1 -0
- package/dist/handoff/ucp-checkout/parse.d.ts +71 -0
- package/dist/handoff/ucp-checkout/parse.js +349 -0
- package/dist/handoff/ucp-checkout/parse.js.map +1 -0
- package/dist/handoff/ucp-checkout/totals.d.ts +41 -0
- package/dist/handoff/ucp-checkout/totals.js +36 -0
- package/dist/handoff/ucp-checkout/totals.js.map +1 -0
- package/dist/handoff/ucp-checkout/types.d.ts +149 -0
- package/dist/handoff/ucp-checkout/types.js +58 -0
- package/dist/handoff/ucp-checkout/types.js.map +1 -0
- package/dist/handoff/url-safety.d.ts +44 -0
- package/dist/handoff/url-safety.js +121 -0
- package/dist/handoff/url-safety.js.map +1 -0
- package/dist/i18n.d.ts +24 -0
- package/dist/i18n.js +27 -0
- package/dist/i18n.js.map +1 -0
- package/dist/negotiation/action-candidate.d.ts +97 -0
- package/dist/negotiation/action-candidate.js +160 -0
- package/dist/negotiation/action-candidate.js.map +1 -0
- package/dist/negotiation/condition/evaluator.d.ts +36 -0
- package/dist/negotiation/condition/evaluator.js +123 -0
- package/dist/negotiation/condition/evaluator.js.map +1 -0
- package/dist/negotiation/context-map/index.d.ts +23 -0
- package/dist/negotiation/context-map/index.js +22 -0
- package/dist/negotiation/context-map/index.js.map +1 -0
- package/dist/negotiation/context-map/store.d.ts +51 -0
- package/dist/negotiation/context-map/store.js +186 -0
- package/dist/negotiation/context-map/store.js.map +1 -0
- package/dist/negotiation/context-map/types.d.ts +29 -0
- package/dist/negotiation/context-map/types.js +57 -0
- package/dist/negotiation/context-map/types.js.map +1 -0
- package/dist/negotiation/domain/common.d.ts +95 -0
- package/dist/negotiation/domain/common.js +216 -0
- package/dist/negotiation/domain/common.js.map +1 -0
- package/dist/negotiation/domain/envelope.d.ts +55 -0
- package/dist/negotiation/domain/envelope.js +110 -0
- package/dist/negotiation/domain/envelope.js.map +1 -0
- package/dist/negotiation/domain/identifiers.d.ts +65 -0
- package/dist/negotiation/domain/identifiers.js +130 -0
- package/dist/negotiation/domain/identifiers.js.map +1 -0
- package/dist/negotiation/domain/objects.d.ts +149 -0
- package/dist/negotiation/domain/objects.js +335 -0
- package/dist/negotiation/domain/objects.js.map +1 -0
- package/dist/negotiation/idempotency/index.d.ts +26 -0
- package/dist/negotiation/idempotency/index.js +25 -0
- package/dist/negotiation/idempotency/index.js.map +1 -0
- package/dist/negotiation/idempotency/store.d.ts +52 -0
- package/dist/negotiation/idempotency/store.js +189 -0
- package/dist/negotiation/idempotency/store.js.map +1 -0
- package/dist/negotiation/idempotency/types.d.ts +102 -0
- package/dist/negotiation/idempotency/types.js +47 -0
- package/dist/negotiation/idempotency/types.js.map +1 -0
- package/dist/negotiation/jcs.d.ts +21 -0
- package/dist/negotiation/jcs.js +114 -0
- package/dist/negotiation/jcs.js.map +1 -0
- package/dist/negotiation/ledger/event.d.ts +142 -0
- package/dist/negotiation/ledger/event.js +206 -0
- package/dist/negotiation/ledger/event.js.map +1 -0
- package/dist/negotiation/ledger/index.d.ts +26 -0
- package/dist/negotiation/ledger/index.js +25 -0
- package/dist/negotiation/ledger/index.js.map +1 -0
- package/dist/negotiation/ledger/store.d.ts +97 -0
- package/dist/negotiation/ledger/store.js +338 -0
- package/dist/negotiation/ledger/store.js.map +1 -0
- package/dist/negotiation/prompt.d.ts +34 -0
- package/dist/negotiation/prompt.js +113 -0
- package/dist/negotiation/prompt.js.map +1 -0
- package/dist/negotiation/recovery/index.d.ts +26 -0
- package/dist/negotiation/recovery/index.js +24 -0
- package/dist/negotiation/recovery/index.js.map +1 -0
- package/dist/negotiation/recovery/outbound.d.ts +49 -0
- package/dist/negotiation/recovery/outbound.js +34 -0
- package/dist/negotiation/recovery/outbound.js.map +1 -0
- package/dist/negotiation/recovery/recover.d.ts +59 -0
- package/dist/negotiation/recovery/recover.js +486 -0
- package/dist/negotiation/recovery/recover.js.map +1 -0
- package/dist/negotiation/recovery/types.d.ts +85 -0
- package/dist/negotiation/recovery/types.js +17 -0
- package/dist/negotiation/recovery/types.js.map +1 -0
- package/dist/negotiation/state/phase.d.ts +70 -0
- package/dist/negotiation/state/phase.js +200 -0
- package/dist/negotiation/state/phase.js.map +1 -0
- package/dist/negotiation/types.d.ts +139 -0
- package/dist/negotiation/types.js +24 -0
- package/dist/negotiation/types.js.map +1 -0
- package/dist/net/safe-http.d.ts +54 -0
- package/dist/net/safe-http.js +116 -0
- package/dist/net/safe-http.js.map +1 -0
- package/dist/operator/controller.d.ts +181 -0
- package/dist/operator/controller.js +784 -0
- package/dist/operator/controller.js.map +1 -0
- package/dist/operator/runner.d.ts +128 -0
- package/dist/operator/runner.js +248 -0
- package/dist/operator/runner.js.map +1 -0
- package/dist/operator/store.d.ts +39 -0
- package/dist/operator/store.js +169 -0
- package/dist/operator/store.js.map +1 -0
- package/dist/operator/strategy.d.ts +54 -0
- package/dist/operator/strategy.js +249 -0
- package/dist/operator/strategy.js.map +1 -0
- package/dist/operator/tui.d.ts +27 -0
- package/dist/operator/tui.js +395 -0
- package/dist/operator/tui.js.map +1 -0
- package/dist/operator/types.d.ts +224 -0
- package/dist/operator/types.js +17 -0
- package/dist/operator/types.js.map +1 -0
- package/dist/product-buyer.d.ts +74 -0
- package/dist/product-buyer.js +161 -0
- package/dist/product-buyer.js.map +1 -0
- package/dist/product-cli.d.ts +56 -0
- package/dist/product-cli.js +175 -0
- package/dist/product-cli.js.map +1 -0
- package/dist/product-compat.d.ts +50 -0
- package/dist/product-compat.js +63 -0
- package/dist/product-compat.js.map +1 -0
- package/dist/product-init.d.ts +73 -0
- package/dist/product-init.js +203 -0
- package/dist/product-init.js.map +1 -0
- package/dist/product-publish.d.ts +85 -0
- package/dist/product-publish.js +216 -0
- package/dist/product-publish.js.map +1 -0
- package/dist/protocol/legacy-shopping-negotiation/adapter.d.ts +42 -0
- package/dist/protocol/legacy-shopping-negotiation/adapter.js +561 -0
- package/dist/protocol/legacy-shopping-negotiation/adapter.js.map +1 -0
- package/dist/protocol/legacy-shopping-negotiation/mapping.d.ts +78 -0
- package/dist/protocol/legacy-shopping-negotiation/mapping.js +321 -0
- package/dist/protocol/legacy-shopping-negotiation/mapping.js.map +1 -0
- package/dist/protocol/legacy-shopping-negotiation/money.d.ts +49 -0
- package/dist/protocol/legacy-shopping-negotiation/money.js +70 -0
- package/dist/protocol/legacy-shopping-negotiation/money.js.map +1 -0
- package/dist/protocol/legacy-shopping-negotiation/types.d.ts +107 -0
- package/dist/protocol/legacy-shopping-negotiation/types.js +34 -0
- package/dist/protocol/legacy-shopping-negotiation/types.js.map +1 -0
- package/dist/runtime/buyer-policy.d.ts +58 -0
- package/dist/runtime/buyer-policy.js +89 -0
- package/dist/runtime/buyer-policy.js.map +1 -0
- package/dist/runtime/fake-model.d.ts +77 -0
- package/dist/runtime/fake-model.js +307 -0
- package/dist/runtime/fake-model.js.map +1 -0
- package/dist/runtime/foreground.d.ts +56 -0
- package/dist/runtime/foreground.js +97 -0
- package/dist/runtime/foreground.js.map +1 -0
- package/dist/runtime/heartbeat.d.ts +36 -0
- package/dist/runtime/heartbeat.js +49 -0
- package/dist/runtime/heartbeat.js.map +1 -0
- package/dist/runtime/merchant-turn.d.ts +35 -0
- package/dist/runtime/merchant-turn.js +20 -0
- package/dist/runtime/merchant-turn.js.map +1 -0
- package/dist/runtime/model.d.ts +40 -0
- package/dist/runtime/model.js +86 -0
- package/dist/runtime/model.js.map +1 -0
- package/dist/runtime/negotiation-turn.d.ts +101 -0
- package/dist/runtime/negotiation-turn.js +317 -0
- package/dist/runtime/negotiation-turn.js.map +1 -0
- package/dist/runtime/tools.d.ts +64 -0
- package/dist/runtime/tools.js +236 -0
- package/dist/runtime/tools.js.map +1 -0
- package/dist/supervisor/init.d.ts +31 -0
- package/dist/supervisor/init.js +222 -0
- package/dist/supervisor/init.js.map +1 -0
- package/dist/supervisor/logs.d.ts +28 -0
- package/dist/supervisor/logs.js +101 -0
- package/dist/supervisor/logs.js.map +1 -0
- package/dist/supervisor/manage.d.ts +72 -0
- package/dist/supervisor/manage.js +419 -0
- package/dist/supervisor/manage.js.map +1 -0
- package/dist/supervisor/manifest.d.ts +69 -0
- package/dist/supervisor/manifest.js +209 -0
- package/dist/supervisor/manifest.js.map +1 -0
- package/dist/supervisor/stack-config.d.ts +79 -0
- package/dist/supervisor/stack-config.js +262 -0
- package/dist/supervisor/stack-config.js.map +1 -0
- package/dist/supervisor/wrapper.d.ts +17 -0
- package/dist/supervisor/wrapper.js +138 -0
- package/dist/supervisor/wrapper.js.map +1 -0
- package/dist/trust/identity/auth-verifier.d.ts +96 -0
- package/dist/trust/identity/auth-verifier.js +166 -0
- package/dist/trust/identity/auth-verifier.js.map +1 -0
- package/dist/trust/identity/identity-binding.d.ts +63 -0
- package/dist/trust/identity/identity-binding.js +59 -0
- package/dist/trust/identity/identity-binding.js.map +1 -0
- package/dist/trust/identity/index.d.ts +38 -0
- package/dist/trust/identity/index.js +31 -0
- package/dist/trust/identity/index.js.map +1 -0
- package/dist/trust/identity/jws.d.ts +64 -0
- package/dist/trust/identity/jws.js +178 -0
- package/dist/trust/identity/jws.js.map +1 -0
- package/dist/trust/identity/keys.d.ts +71 -0
- package/dist/trust/identity/keys.js +118 -0
- package/dist/trust/identity/keys.js.map +1 -0
- package/dist/trust/identity/message-signature.d.ts +105 -0
- package/dist/trust/identity/message-signature.js +297 -0
- package/dist/trust/identity/message-signature.js.map +1 -0
- package/dist/trust/identity/nonce.d.ts +45 -0
- package/dist/trust/identity/nonce.js +50 -0
- package/dist/trust/identity/nonce.js.map +1 -0
- package/dist/trust/identity/signature-base.d.ts +84 -0
- package/dist/trust/identity/signature-base.js +261 -0
- package/dist/trust/identity/signature-base.js.map +1 -0
- package/dist/trust/identity/trust-policy.d.ts +92 -0
- package/dist/trust/identity/trust-policy.js +95 -0
- package/dist/trust/identity/trust-policy.js.map +1 -0
- package/dist/trust/index.d.ts +21 -0
- package/dist/trust/index.js +22 -0
- package/dist/trust/index.js.map +1 -0
- package/dist/trust/records/evaluator.d.ts +76 -0
- package/dist/trust/records/evaluator.js +122 -0
- package/dist/trust/records/evaluator.js.map +1 -0
- package/dist/trust/records/index.d.ts +28 -0
- package/dist/trust/records/index.js +26 -0
- package/dist/trust/records/index.js.map +1 -0
- package/dist/trust/records/store.d.ts +75 -0
- package/dist/trust/records/store.js +339 -0
- package/dist/trust/records/store.js.map +1 -0
- package/dist/trust/records/types.d.ts +159 -0
- package/dist/trust/records/types.js +40 -0
- package/dist/trust/records/types.js.map +1 -0
- package/dist/tui/banner.d.ts +46 -0
- package/dist/tui/banner.js +99 -0
- package/dist/tui/banner.js.map +1 -0
- package/dist/tui/styles.d.ts +70 -0
- package/dist/tui/styles.js +197 -0
- package/dist/tui/styles.js.map +1 -0
- package/dist/tui/theme.d.ts +63 -0
- package/dist/tui/theme.js +136 -0
- package/dist/tui/theme.js.map +1 -0
- package/examples/profiles/buyer.deepseek.yaml +34 -0
- package/examples/profiles/buyer.fake.yaml +36 -0
- package/examples/profiles/buyer.local.yaml +40 -0
- package/examples/profiles/merchant.deepseek.yaml +32 -0
- package/examples/profiles/merchant.fake.yaml +31 -0
- package/examples/profiles/merchant.local.yaml +34 -0
- package/package.json +55 -0
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
export function translated(value, notes) {
|
|
17
|
+
return { translated: value, notes };
|
|
18
|
+
}
|
|
19
|
+
export function failClosed(reason) {
|
|
20
|
+
return { fail_closed: true, reason };
|
|
21
|
+
}
|
|
22
|
+
export function requiresHuman(reason) {
|
|
23
|
+
return { requires_human: true, reason };
|
|
24
|
+
}
|
|
25
|
+
export function isTranslated(r) {
|
|
26
|
+
return "translated" in r;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* KNP → legacy 方向无需额外上下文:legacy decision 的网关派生字段
|
|
30
|
+
* (retries_remaining、actor 等)不属于转译范围 —— KNP 侧的 actor 语义通过
|
|
31
|
+
* note 显式交给传输层断言(identity,绝不静默丢),其余 KNP-only 字段逐条
|
|
32
|
+
* 记录为 dropped note。
|
|
33
|
+
*/
|
|
34
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/protocol/legacy-shopping-negotiation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAyCH,MAAM,UAAU,UAAU,CAAI,KAAQ,EAAE,KAAwB;IAC9D,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,YAAY,CAAI,CAAuB;IACrD,OAAO,YAAY,IAAI,CAAC,CAAC;AAC3B,CAAC;AAmCD;;;;;GAKG"}
|
|
@@ -0,0 +1,58 @@
|
|
|
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
|
+
* Buyer-side LOCAL private policy gate (design §7.2, §16.3).
|
|
18
|
+
*
|
|
19
|
+
* The buyer's private budget lives only in the Kiwi profile; the marketplace
|
|
20
|
+
* never sees it and never checks it (shopping-cli's buyer gate is structural
|
|
21
|
+
* only). This module enforces the private policy inside the submit tool,
|
|
22
|
+
* BEFORE anything reaches the gateway:
|
|
23
|
+
*
|
|
24
|
+
* - proposal total (unit_price * quantity + delivery fee) must not exceed
|
|
25
|
+
* max_total_price_private;
|
|
26
|
+
* - proposal delivery eta_end must not be later than acceptable_eta_latest;
|
|
27
|
+
* - every required_after_sales_terms entry must be referenced by the
|
|
28
|
+
* accepted/issued proposal;
|
|
29
|
+
* - public_message must not leak the private budget: explicit budget talk
|
|
30
|
+
* ("我的预算" / "最高预算" / "内部预算" / "budget" …) is rejected locally.
|
|
31
|
+
* A plain quote that happens to equal the budget is fine — the number
|
|
32
|
+
* alone is not a leak; calling it a budget is.
|
|
33
|
+
*
|
|
34
|
+
* Privacy invariant: rejection reasons NEVER contain the private threshold
|
|
35
|
+
* value. The value is not logged, not sent to the gateway, and not echoed
|
|
36
|
+
* back to the model.
|
|
37
|
+
*/
|
|
38
|
+
import type { BuyerPolicy } from "../config/profile.js";
|
|
39
|
+
import type { NegotiationDecision, PolicyResult } from "../negotiation/types.js";
|
|
40
|
+
export interface BuyerPolicyViolation {
|
|
41
|
+
reason_codes: string[];
|
|
42
|
+
/** Safe to show the model and to log: never contains private numbers. */
|
|
43
|
+
public_reason: string;
|
|
44
|
+
}
|
|
45
|
+
/** Total price of a proposal: goods plus delivery fee. */
|
|
46
|
+
export declare function proposalTotal(decision: NegotiationDecision): number | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Check a decision against the local buyer policy. Returns undefined when
|
|
49
|
+
* the decision may go to the gateway, or a violation describing the first
|
|
50
|
+
* problem found (without any private values).
|
|
51
|
+
*/
|
|
52
|
+
export declare function checkBuyerLocalPolicy(decision: NegotiationDecision, policy: BuyerPolicy): BuyerPolicyViolation | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Build the local policy_result for a violated decision. Shaped like the
|
|
55
|
+
* frozen PolicyResult so the agent loop can handle it uniformly; it is
|
|
56
|
+
* produced locally and never touches the gateway.
|
|
57
|
+
*/
|
|
58
|
+
export declare function localBuyerPolicyResult(conversationId: string, violation: BuyerPolicyViolation, retriesRemaining: number): PolicyResult;
|
|
@@ -0,0 +1,89 @@
|
|
|
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 { PROTOCOL_VERSION } from "../negotiation/types.js";
|
|
17
|
+
/**
|
|
18
|
+
* Budget-threshold wording. A public message using these phrases is treated
|
|
19
|
+
* as leaking the private budget regardless of whether a number appears.
|
|
20
|
+
*/
|
|
21
|
+
const BUDGET_LEAK_PATTERN = /(我的|最高|最大|内部|私有|心里)?预算|预算上限|budget|price\s*ceiling|max(imum)?\s*budget/i;
|
|
22
|
+
/** Total price of a proposal: goods plus delivery fee. */
|
|
23
|
+
export function proposalTotal(decision) {
|
|
24
|
+
const p = decision.proposal;
|
|
25
|
+
if (!p)
|
|
26
|
+
return undefined;
|
|
27
|
+
return p.unit_price * p.quantity + p.delivery.fee;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check a decision against the local buyer policy. Returns undefined when
|
|
31
|
+
* the decision may go to the gateway, or a violation describing the first
|
|
32
|
+
* problem found (without any private values).
|
|
33
|
+
*/
|
|
34
|
+
export function checkBuyerLocalPolicy(decision, policy) {
|
|
35
|
+
// 1. Private-budget leak scan applies to every action with public text.
|
|
36
|
+
if (BUDGET_LEAK_PATTERN.test(decision.public_message)) {
|
|
37
|
+
return {
|
|
38
|
+
reason_codes: ["local_budget_leak"],
|
|
39
|
+
public_reason: "公开文本出现预算类措辞,可能泄露私有预算约束。请删除任何关于预算/上限的表述后重试。",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const proposal = decision.proposal;
|
|
43
|
+
if (!proposal)
|
|
44
|
+
return undefined;
|
|
45
|
+
// 2. Private budget: total price must fit the private maximum.
|
|
46
|
+
const total = proposalTotal(decision);
|
|
47
|
+
if (total !== undefined && total > policy.max_total_price_private) {
|
|
48
|
+
return {
|
|
49
|
+
reason_codes: ["local_budget_exceeded"],
|
|
50
|
+
public_reason: "该报价总价超出你的私有预算约束。请还价、放弃(decline)或转人工(escalate),不要透露预算数值。",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// 3. Delivery ETA must be acceptable.
|
|
54
|
+
const etaEnd = Date.parse(proposal.delivery.eta_end);
|
|
55
|
+
const latest = Date.parse(policy.acceptable_eta_latest);
|
|
56
|
+
if (!Number.isNaN(etaEnd) && !Number.isNaN(latest) && etaEnd > latest) {
|
|
57
|
+
return {
|
|
58
|
+
reason_codes: ["local_eta_violation"],
|
|
59
|
+
public_reason: "该报价的配送预计送达时间晚于你可接受的最晚时间。请要求更快的配送、放弃或转人工。",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// 4. Required after-sales terms must all be referenced.
|
|
63
|
+
const refs = new Set(proposal.after_sales_policy_refs);
|
|
64
|
+
const missing = policy.required_after_sales_terms.filter((term) => !refs.has(term));
|
|
65
|
+
if (missing.length > 0) {
|
|
66
|
+
return {
|
|
67
|
+
reason_codes: ["local_missing_after_sales_terms"],
|
|
68
|
+
public_reason: `该报价缺少必需的售后条款: ${missing.join(", ")}。请要求对方加入这些条款、放弃或转人工。`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Build the local policy_result for a violated decision. Shaped like the
|
|
75
|
+
* frozen PolicyResult so the agent loop can handle it uniformly; it is
|
|
76
|
+
* produced locally and never touches the gateway.
|
|
77
|
+
*/
|
|
78
|
+
export function localBuyerPolicyResult(conversationId, violation, retriesRemaining) {
|
|
79
|
+
return {
|
|
80
|
+
protocol_version: PROTOCOL_VERSION,
|
|
81
|
+
result: "rejected_retryable",
|
|
82
|
+
conversation_id: conversationId,
|
|
83
|
+
next_actor: "buyer",
|
|
84
|
+
reason_codes: violation.reason_codes,
|
|
85
|
+
public_reason: violation.public_reason,
|
|
86
|
+
retries_remaining: Math.max(0, retriesRemaining),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=buyer-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buyer-policy.js","sourceRoot":"","sources":["../../src/runtime/buyer-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA2BH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAQ3D;;;GAGG;AACH,MAAM,mBAAmB,GACvB,yEAAyE,CAAC;AAE5E,0DAA0D;AAC1D,MAAM,UAAU,aAAa,CAAC,QAA6B;IACzD,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC;IAC5B,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,OAAO,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAA6B,EAC7B,MAAmB;IAEnB,wEAAwE;IACxE,IAAI,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QACtD,OAAO;YACL,YAAY,EAAE,CAAC,mBAAmB,CAAC;YACnC,aAAa,EACX,4CAA4C;SAC/C,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACnC,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEhC,+DAA+D;IAC/D,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,MAAM,CAAC,uBAAuB,EAAE,CAAC;QAClE,OAAO;YACL,YAAY,EAAE,CAAC,uBAAuB,CAAC;YACvC,aAAa,EACX,yDAAyD;SAC5D,CAAC;IACJ,CAAC;IAED,sCAAsC;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,MAAM,EAAE,CAAC;QACtE,OAAO;YACL,YAAY,EAAE,CAAC,qBAAqB,CAAC;YACrC,aAAa,EACX,0CAA0C;SAC7C,CAAC;IACJ,CAAC;IAED,wDAAwD;IACxD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,MAAM,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACpF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,YAAY,EAAE,CAAC,iCAAiC,CAAC;YACjD,aAAa,EAAE,iBAAiB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB;SACzE,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,cAAsB,EACtB,SAA+B,EAC/B,gBAAwB;IAExB,OAAO;QACL,gBAAgB,EAAE,gBAAgB;QAClC,MAAM,EAAE,oBAAoB;QAC5B,eAAe,EAAE,cAAc;QAC/B,UAAU,EAAE,OAAO;QACnB,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,aAAa,EAAE,SAAS,CAAC,aAAa;QACtC,iBAAiB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,gBAAgB,CAAC;KACjD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
* Deterministic fake models — no network, no keys, fully reproducible.
|
|
18
|
+
*
|
|
19
|
+
* Two flavors:
|
|
20
|
+
* - createScriptedFakeStreamFn: replays canned assistant messages (tests).
|
|
21
|
+
* - createDeterministicStreamFn: tiny rule-based buyer/merchant "models"
|
|
22
|
+
* used by profiles with model.provider=fake. They read the snapshot from
|
|
23
|
+
* the tool result and produce a deterministic decision, enabling offline
|
|
24
|
+
* smoke runs of the full single-turn vertical slice for both roles.
|
|
25
|
+
*/
|
|
26
|
+
import { type FauxProviderHandle, type FauxResponseStep } from "@earendil-works/pi-ai";
|
|
27
|
+
import type { StreamFn } from "@earendil-works/pi-agent-core";
|
|
28
|
+
import type { AgentProfile } from "../config/profile.js";
|
|
29
|
+
import { type NegotiationDecision, type NegotiationSnapshot } from "../negotiation/types.js";
|
|
30
|
+
export interface ScriptedFake {
|
|
31
|
+
streamFn: StreamFn;
|
|
32
|
+
handle: FauxProviderHandle;
|
|
33
|
+
}
|
|
34
|
+
/** Replay canned responses in order. Used by tests. */
|
|
35
|
+
export declare function createScriptedFakeStreamFn(responses: FauxResponseStep[]): ScriptedFake;
|
|
36
|
+
/**
|
|
37
|
+
* Structured influence of applied operator strategy directives on candidate
|
|
38
|
+
* generation (docs/operator-tui-v0.2.md §7). Compiled by the operator runner
|
|
39
|
+
* from the session's directive list; never widens HardPolicy by itself — the
|
|
40
|
+
* authoritative policy gates still run on the profile at submit time.
|
|
41
|
+
*/
|
|
42
|
+
export interface DecisionHints {
|
|
43
|
+
/** Effective buyer budget ceiling (last budget directive, else profile). */
|
|
44
|
+
buyer_max_total_price?: number;
|
|
45
|
+
/** Per-unit buyer budget ("单价预算 94"); the decision derives the total. */
|
|
46
|
+
buyer_max_unit_price?: number;
|
|
47
|
+
/** Effective merchant floor (last floor directive, else profile). */
|
|
48
|
+
merchant_min_unit_price?: number;
|
|
49
|
+
/** Quantity cap ("最多买 N 件"). */
|
|
50
|
+
quantity_cap?: number;
|
|
51
|
+
/** Buyer target unit price: counter toward this before accepting ("砍到 100"). */
|
|
52
|
+
buyer_target_unit_price?: number;
|
|
53
|
+
/** Prefer free shipping: counter with fee 0 before accepting. */
|
|
54
|
+
prefer_free_shipping?: boolean;
|
|
55
|
+
/** This turn only asks; never accept or counter with a price. */
|
|
56
|
+
ask_only?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/** Build the deterministic decision from a snapshot. Pure function. */
|
|
59
|
+
export declare function deterministicMerchantDecision(snapshot: NegotiationSnapshot, quoteTtlSeconds: number, hints?: DecisionHints): NegotiationDecision;
|
|
60
|
+
/**
|
|
61
|
+
* Rule-based fake merchant model for offline smoke runs. First call fetches
|
|
62
|
+
* the snapshot; second call submits a deterministic decision derived from it.
|
|
63
|
+
*/
|
|
64
|
+
export declare function createDeterministicMerchantStreamFn(profile: AgentProfile): StreamFn;
|
|
65
|
+
/** Build the deterministic buyer decision from a snapshot. Pure function. */
|
|
66
|
+
export declare function deterministicBuyerDecision(snapshot: NegotiationSnapshot, policy: {
|
|
67
|
+
max_total_price_private: number;
|
|
68
|
+
acceptable_eta_latest: string;
|
|
69
|
+
required_after_sales_terms: string[];
|
|
70
|
+
}, hints?: DecisionHints): NegotiationDecision;
|
|
71
|
+
/**
|
|
72
|
+
* Rule-based fake buyer model for offline smoke runs. Reads the snapshot,
|
|
73
|
+
* then deterministically accepts an acceptable offer or escalates.
|
|
74
|
+
*/
|
|
75
|
+
export declare function createDeterministicBuyerStreamFn(profile: AgentProfile): StreamFn;
|
|
76
|
+
/** Role-dispatching deterministic fake: merchant or buyer, driven by the profile. */
|
|
77
|
+
export declare function createDeterministicStreamFn(profile: AgentProfile): StreamFn;
|
|
@@ -0,0 +1,307 @@
|
|
|
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
|
+
* Deterministic fake models — no network, no keys, fully reproducible.
|
|
18
|
+
*
|
|
19
|
+
* Two flavors:
|
|
20
|
+
* - createScriptedFakeStreamFn: replays canned assistant messages (tests).
|
|
21
|
+
* - createDeterministicStreamFn: tiny rule-based buyer/merchant "models"
|
|
22
|
+
* used by profiles with model.provider=fake. They read the snapshot from
|
|
23
|
+
* the tool result and produce a deterministic decision, enabling offline
|
|
24
|
+
* smoke runs of the full single-turn vertical slice for both roles.
|
|
25
|
+
*/
|
|
26
|
+
import { fauxAssistantMessage, fauxProvider, fauxToolCall, } from "@earendil-works/pi-ai";
|
|
27
|
+
import { PROTOCOL_VERSION, } from "../negotiation/types.js";
|
|
28
|
+
import { TOOL_GET_SNAPSHOT, TOOL_SUBMIT_DECISION } from "./tools.js";
|
|
29
|
+
/** Replay canned responses in order. Used by tests. */
|
|
30
|
+
export function createScriptedFakeStreamFn(responses) {
|
|
31
|
+
const handle = fauxProvider({ models: [{ id: "fake-model", name: "fake-model" }] });
|
|
32
|
+
handle.setResponses(responses);
|
|
33
|
+
const streamFn = (model, context, options) => handle.provider.streamSimple(model, context, options);
|
|
34
|
+
return { streamFn, handle };
|
|
35
|
+
}
|
|
36
|
+
/** Extract the latest tool result text for a tool from the LLM context. */
|
|
37
|
+
function latestToolResultText(context, toolName) {
|
|
38
|
+
for (let i = context.messages.length - 1; i >= 0; i--) {
|
|
39
|
+
const m = context.messages[i];
|
|
40
|
+
if (m && m.role === "toolResult" && m.toolName === toolName) {
|
|
41
|
+
const first = m.content[0];
|
|
42
|
+
if (first && first.type === "text")
|
|
43
|
+
return first.text;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
/** Build the deterministic decision from a snapshot. Pure function. */
|
|
49
|
+
export function deterministicMerchantDecision(snapshot, quoteTtlSeconds, hints = {}) {
|
|
50
|
+
const p = snapshot.product;
|
|
51
|
+
const buyerText = snapshot.messages
|
|
52
|
+
.filter((m) => m.sender_role === "buyer")
|
|
53
|
+
.map((m) => m.public_message)
|
|
54
|
+
.join("\n");
|
|
55
|
+
const qtyMatch = /(\d+)\s*(?:件|个|只|x\b)/i.exec(buyerText);
|
|
56
|
+
const quantity = Math.min(Math.max(Number(qtyMatch?.[1] ?? 1), 1), snapshot.stock.quantity || 1, hints.quantity_cap ?? Number.POSITIVE_INFINITY);
|
|
57
|
+
const validUntil = new Date(Date.parse(snapshot.stock.observed_at) + quoteTtlSeconds * 1000).toISOString();
|
|
58
|
+
// A floor directive above the list price raises the quote; at or below it
|
|
59
|
+
// the list price already satisfies the floor, so the quote is unchanged.
|
|
60
|
+
const unitPrice = hints.merchant_min_unit_price !== undefined && hints.merchant_min_unit_price > p.list_price
|
|
61
|
+
? hints.merchant_min_unit_price
|
|
62
|
+
: p.list_price;
|
|
63
|
+
if (snapshot.stock.status === "out_of_stock") {
|
|
64
|
+
return {
|
|
65
|
+
protocol_version: PROTOCOL_VERSION,
|
|
66
|
+
conversation_id: snapshot.conversation.id,
|
|
67
|
+
in_reply_to_message_id: snapshot.in_reply_to_message_id,
|
|
68
|
+
action: "decline",
|
|
69
|
+
open_issues: ["out_of_stock"],
|
|
70
|
+
public_message: "抱歉,该商品当前缺货,无法报价。",
|
|
71
|
+
confidence: 0.99,
|
|
72
|
+
reason_codes: ["out_of_stock"],
|
|
73
|
+
request_human_review: false,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// Convergence: accept the buyer's latest counter when it meets the merchant
|
|
77
|
+
// floor — otherwise the merchant would re-quote the list price forever and
|
|
78
|
+
// the autonomous negotiation never closes.
|
|
79
|
+
const floor = hints.merchant_min_unit_price;
|
|
80
|
+
const buyerProposal = snapshot.current_proposal;
|
|
81
|
+
if (floor !== undefined && buyerProposal !== null && buyerProposal !== undefined && buyerProposal.unit_price >= floor) {
|
|
82
|
+
return {
|
|
83
|
+
protocol_version: PROTOCOL_VERSION,
|
|
84
|
+
conversation_id: snapshot.conversation.id,
|
|
85
|
+
in_reply_to_message_id: snapshot.in_reply_to_message_id,
|
|
86
|
+
action: "accept_nonbinding",
|
|
87
|
+
proposal: buyerProposal,
|
|
88
|
+
open_issues: [...snapshot.open_issues],
|
|
89
|
+
public_message: "接受该报价,双方达成非约束性共识。",
|
|
90
|
+
confidence: 0.9,
|
|
91
|
+
reason_codes: ["within_policy", "consensus"],
|
|
92
|
+
request_human_review: false,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
protocol_version: PROTOCOL_VERSION,
|
|
97
|
+
conversation_id: snapshot.conversation.id,
|
|
98
|
+
in_reply_to_message_id: snapshot.in_reply_to_message_id,
|
|
99
|
+
action: "counter",
|
|
100
|
+
proposal: {
|
|
101
|
+
sku: p.sku,
|
|
102
|
+
quantity,
|
|
103
|
+
unit_price: unitPrice,
|
|
104
|
+
currency: p.currency,
|
|
105
|
+
stock: {
|
|
106
|
+
status: snapshot.stock.status,
|
|
107
|
+
quantity: snapshot.stock.quantity,
|
|
108
|
+
observed_at: snapshot.stock.observed_at,
|
|
109
|
+
reserved: false,
|
|
110
|
+
},
|
|
111
|
+
delivery: {
|
|
112
|
+
eta_start: snapshot.delivery.eta_start,
|
|
113
|
+
eta_end: snapshot.delivery.eta_end,
|
|
114
|
+
fee: snapshot.delivery.fee,
|
|
115
|
+
},
|
|
116
|
+
after_sales_policy_refs: snapshot.after_sales_policies.map((pol) => pol.ref),
|
|
117
|
+
valid_until: validUntil,
|
|
118
|
+
},
|
|
119
|
+
open_issues: [...snapshot.open_issues],
|
|
120
|
+
public_message: `可以按单价 ${unitPrice} ${p.currency} 提供 ${quantity} 件,报价 ${quoteTtlSeconds} 秒内有效。`,
|
|
121
|
+
confidence: 0.9,
|
|
122
|
+
reason_codes: ["within_policy", "inventory_observed"],
|
|
123
|
+
request_human_review: false,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Rule-based fake merchant model for offline smoke runs. First call fetches
|
|
128
|
+
* the snapshot; second call submits a deterministic decision derived from it.
|
|
129
|
+
*/
|
|
130
|
+
export function createDeterministicMerchantStreamFn(profile) {
|
|
131
|
+
const handle = fauxProvider({
|
|
132
|
+
models: [{ id: "fake-merchant-model", name: "fake-merchant-model" }],
|
|
133
|
+
});
|
|
134
|
+
const quoteTtl = profile.merchant_policy?.quote_ttl_seconds ?? 300;
|
|
135
|
+
handle.setResponses([
|
|
136
|
+
(context) => {
|
|
137
|
+
const snapshotText = latestToolResultText(context, TOOL_GET_SNAPSHOT);
|
|
138
|
+
if (snapshotText === undefined) {
|
|
139
|
+
return fauxAssistantMessage([fauxToolCall(TOOL_GET_SNAPSHOT, {})]);
|
|
140
|
+
}
|
|
141
|
+
const snapshot = JSON.parse(snapshotText);
|
|
142
|
+
const decision = deterministicMerchantDecision(snapshot, quoteTtl);
|
|
143
|
+
return fauxAssistantMessage([fauxToolCall(TOOL_SUBMIT_DECISION, { ...decision })]);
|
|
144
|
+
},
|
|
145
|
+
// Safety net if the first response was consumed by a retry.
|
|
146
|
+
(context) => {
|
|
147
|
+
const snapshotText = latestToolResultText(context, TOOL_GET_SNAPSHOT);
|
|
148
|
+
if (snapshotText === undefined) {
|
|
149
|
+
return fauxAssistantMessage([fauxToolCall(TOOL_GET_SNAPSHOT, {})]);
|
|
150
|
+
}
|
|
151
|
+
const snapshot = JSON.parse(snapshotText);
|
|
152
|
+
const decision = deterministicMerchantDecision(snapshot, quoteTtl);
|
|
153
|
+
return fauxAssistantMessage([fauxToolCall(TOOL_SUBMIT_DECISION, { ...decision })]);
|
|
154
|
+
},
|
|
155
|
+
]);
|
|
156
|
+
return (model, context, options) => handle.provider.streamSimple(model, context, options);
|
|
157
|
+
}
|
|
158
|
+
/** Build the deterministic buyer decision from a snapshot. Pure function. */
|
|
159
|
+
export function deterministicBuyerDecision(snapshot, policy, hints = {}) {
|
|
160
|
+
const base = {
|
|
161
|
+
protocol_version: PROTOCOL_VERSION,
|
|
162
|
+
conversation_id: snapshot.conversation.id,
|
|
163
|
+
in_reply_to_message_id: snapshot.in_reply_to_message_id,
|
|
164
|
+
};
|
|
165
|
+
const proposal = snapshot.current_proposal;
|
|
166
|
+
if (!proposal) {
|
|
167
|
+
return {
|
|
168
|
+
...base,
|
|
169
|
+
action: "ask",
|
|
170
|
+
open_issues: ["no_proposal"],
|
|
171
|
+
public_message: "请提供包含价格、配送与售后条款的完整报价。",
|
|
172
|
+
confidence: 0.8,
|
|
173
|
+
reason_codes: ["no_proposal"],
|
|
174
|
+
request_human_review: false,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// Turn-scoped ask-only directive: this turn asks, never accepts or counters
|
|
178
|
+
// with a price (design §7.3 example: "这一轮只问交期,不接受报价").
|
|
179
|
+
if (hints.ask_only) {
|
|
180
|
+
return {
|
|
181
|
+
...base,
|
|
182
|
+
action: "ask",
|
|
183
|
+
open_issues: ["turn_ask_only"],
|
|
184
|
+
public_message: "请先确认交付时间与售后条款。",
|
|
185
|
+
confidence: 0.8,
|
|
186
|
+
reason_codes: ["turn_ask_only"],
|
|
187
|
+
request_human_review: false,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
// A quantity cap ("最多买 N 件") re-scopes the check to the capped size.
|
|
191
|
+
const capped = hints.quantity_cap !== undefined && proposal.quantity > hints.quantity_cap
|
|
192
|
+
? { ...proposal, quantity: hints.quantity_cap }
|
|
193
|
+
: proposal;
|
|
194
|
+
// Total budget: explicit total, else per-unit × quantity, else profile.
|
|
195
|
+
const maxTotal = hints.buyer_max_total_price ??
|
|
196
|
+
(hints.buyer_max_unit_price !== undefined
|
|
197
|
+
? hints.buyer_max_unit_price * capped.quantity
|
|
198
|
+
: policy.max_total_price_private);
|
|
199
|
+
const fee = capped.delivery.fee;
|
|
200
|
+
const etaOk = Date.parse(proposal.delivery.eta_end) <= Date.parse(policy.acceptable_eta_latest);
|
|
201
|
+
const refs = new Set(proposal.after_sales_policy_refs);
|
|
202
|
+
const termsOk = policy.required_after_sales_terms.every((t) => refs.has(t));
|
|
203
|
+
// Counter toward the target / affordable unit price FIRST — a buyer who
|
|
204
|
+
// sees an over-budget offer should push the price down, not give up. Bounded
|
|
205
|
+
// by the per-unit budget and the total budget.
|
|
206
|
+
const targetPrice = hints.buyer_target_unit_price;
|
|
207
|
+
const perUnitBudget = hints.buyer_max_unit_price ?? maxTotal / capped.quantity;
|
|
208
|
+
const desiredUnit = targetPrice !== undefined ? Math.min(targetPrice, perUnitBudget) : undefined;
|
|
209
|
+
if (desiredUnit !== undefined &&
|
|
210
|
+
desiredUnit < capped.unit_price &&
|
|
211
|
+
desiredUnit * capped.quantity + fee <= maxTotal) {
|
|
212
|
+
return {
|
|
213
|
+
...base,
|
|
214
|
+
action: "counter",
|
|
215
|
+
proposal: { ...capped, unit_price: desiredUnit },
|
|
216
|
+
open_issues: [...snapshot.open_issues],
|
|
217
|
+
public_message: `单价 ${desiredUnit} ${proposal.currency}(${capped.quantity} 件)我可以接受,请确认。`,
|
|
218
|
+
confidence: 0.9,
|
|
219
|
+
reason_codes: ["within_policy", "target_price"],
|
|
220
|
+
request_human_review: false,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
// Hard constraints: if the offer still doesn't fit, escalate — never reveal
|
|
224
|
+
// why in numeric terms (the private budget must not leak).
|
|
225
|
+
const total = capped.unit_price * capped.quantity + fee;
|
|
226
|
+
if (total > maxTotal || !etaOk || !termsOk) {
|
|
227
|
+
return {
|
|
228
|
+
...base,
|
|
229
|
+
action: "escalate",
|
|
230
|
+
open_issues: ["offer_outside_constraints"],
|
|
231
|
+
public_message: "该报价需要人工确认后才能继续。",
|
|
232
|
+
confidence: 0.7,
|
|
233
|
+
reason_codes: ["human_review"],
|
|
234
|
+
request_human_review: true,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
// Soft preference: fight for free shipping before accepting a fee-bearing
|
|
238
|
+
// offer ("先争取包邮").
|
|
239
|
+
if (hints.prefer_free_shipping && proposal.delivery.fee > 0) {
|
|
240
|
+
return {
|
|
241
|
+
...base,
|
|
242
|
+
action: "counter",
|
|
243
|
+
proposal: { ...proposal, delivery: { ...proposal.delivery, fee: 0 } },
|
|
244
|
+
open_issues: [...snapshot.open_issues],
|
|
245
|
+
public_message: "如果免运费(包邮),我可以接受当前报价。",
|
|
246
|
+
confidence: 0.8,
|
|
247
|
+
reason_codes: ["within_policy", "shipping_discussed"],
|
|
248
|
+
request_human_review: false,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
// Quantity cap: accept at most the capped quantity.
|
|
252
|
+
if (capped !== proposal) {
|
|
253
|
+
return {
|
|
254
|
+
...base,
|
|
255
|
+
action: "counter",
|
|
256
|
+
proposal: capped,
|
|
257
|
+
open_issues: [...snapshot.open_issues],
|
|
258
|
+
public_message: `按 ${hints.quantity_cap} 件以内我可以接受,请确认。`,
|
|
259
|
+
confidence: 0.8,
|
|
260
|
+
reason_codes: ["within_policy", "quantity_capped"],
|
|
261
|
+
request_human_review: false,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
...base,
|
|
266
|
+
action: "accept_nonbinding",
|
|
267
|
+
proposal,
|
|
268
|
+
open_issues: [],
|
|
269
|
+
public_message: "接受该报价,双方达成非约束性共识。",
|
|
270
|
+
confidence: 0.9,
|
|
271
|
+
reason_codes: ["within_policy"],
|
|
272
|
+
request_human_review: false,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Rule-based fake buyer model for offline smoke runs. Reads the snapshot,
|
|
277
|
+
* then deterministically accepts an acceptable offer or escalates.
|
|
278
|
+
*/
|
|
279
|
+
export function createDeterministicBuyerStreamFn(profile) {
|
|
280
|
+
const handle = fauxProvider({
|
|
281
|
+
models: [{ id: "fake-buyer-model", name: "fake-buyer-model" }],
|
|
282
|
+
});
|
|
283
|
+
const policy = profile.buyer_policy ?? {
|
|
284
|
+
max_total_price_private: Number.POSITIVE_INFINITY,
|
|
285
|
+
acceptable_eta_latest: "9999-12-31T23:59:59Z",
|
|
286
|
+
required_after_sales_terms: [],
|
|
287
|
+
};
|
|
288
|
+
const respond = (context) => {
|
|
289
|
+
const snapshotText = latestToolResultText(context, TOOL_GET_SNAPSHOT);
|
|
290
|
+
if (snapshotText === undefined) {
|
|
291
|
+
return fauxAssistantMessage([fauxToolCall(TOOL_GET_SNAPSHOT, {})]);
|
|
292
|
+
}
|
|
293
|
+
const snapshot = JSON.parse(snapshotText);
|
|
294
|
+
const decision = deterministicBuyerDecision(snapshot, policy);
|
|
295
|
+
return fauxAssistantMessage([fauxToolCall(TOOL_SUBMIT_DECISION, { ...decision })]);
|
|
296
|
+
};
|
|
297
|
+
// Second entry is a safety net if the first response was consumed by a retry.
|
|
298
|
+
handle.setResponses([respond, respond]);
|
|
299
|
+
return (model, context, options) => handle.provider.streamSimple(model, context, options);
|
|
300
|
+
}
|
|
301
|
+
/** Role-dispatching deterministic fake: merchant or buyer, driven by the profile. */
|
|
302
|
+
export function createDeterministicStreamFn(profile) {
|
|
303
|
+
return profile.role === "buyer"
|
|
304
|
+
? createDeterministicBuyerStreamFn(profile)
|
|
305
|
+
: createDeterministicMerchantStreamFn(profile);
|
|
306
|
+
}
|
|
307
|
+
//# sourceMappingURL=fake-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-model.js","sourceRoot":"","sources":["../../src/runtime/fake-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
* Foreground polling loop (design §12.2).
|
|
18
|
+
*
|
|
19
|
+
* Serially runs negotiation turns for one profile — the same profile never
|
|
20
|
+
* runs two turns concurrently. no_work waits poll_interval_seconds;
|
|
21
|
+
* transient errors back off exponentially with a bounded cap and the loop
|
|
22
|
+
* continues. SIGINT/SIGTERM (an AbortSignal) aborts the in-flight turn —
|
|
23
|
+
* the turn itself settles its claim (abandon, never complete) — and the
|
|
24
|
+
* loop then exits cleanly.
|
|
25
|
+
*
|
|
26
|
+
* The loop never logs secrets or private policy values: turn reports carry
|
|
27
|
+
* only public policy reasons and usage counters.
|
|
28
|
+
*/
|
|
29
|
+
import type { StreamFn } from "@earendil-works/pi-agent-core";
|
|
30
|
+
import type { AgentProfile } from "../config/profile.js";
|
|
31
|
+
import { type CommerceClient } from "../commerce/types.js";
|
|
32
|
+
import { type TurnReport } from "./negotiation-turn.js";
|
|
33
|
+
/** Upper bound for the transient-error backoff (ms). */
|
|
34
|
+
export declare const MAX_BACKOFF_MS = 60000;
|
|
35
|
+
export type Sleeper = (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
36
|
+
/** Default sleeper: resolves early (without throwing) when aborted. */
|
|
37
|
+
export declare const defaultSleeper: Sleeper;
|
|
38
|
+
export interface ForegroundOptions {
|
|
39
|
+
profile: AgentProfile;
|
|
40
|
+
client: CommerceClient;
|
|
41
|
+
streamFn: StreamFn;
|
|
42
|
+
getApiKey?: () => string | undefined;
|
|
43
|
+
/** External shutdown signal (SIGINT/SIGTERM). */
|
|
44
|
+
signal?: AbortSignal;
|
|
45
|
+
/** Injectable sleeper for tests; defaults to real timers. */
|
|
46
|
+
sleep?: Sleeper;
|
|
47
|
+
/** Called with each finished turn report (CLI writes JSONL here). */
|
|
48
|
+
onReport?: (report: TurnReport) => void;
|
|
49
|
+
/** Optional bound on turns, for tests and smoke runs. */
|
|
50
|
+
maxTurns?: number;
|
|
51
|
+
}
|
|
52
|
+
export interface ForegroundResult {
|
|
53
|
+
turns: number;
|
|
54
|
+
stopped_by: "signal" | "max_turns";
|
|
55
|
+
}
|
|
56
|
+
export declare function runForeground(options: ForegroundOptions): Promise<ForegroundResult>;
|