@brand-map/ai-bot-extension 0.0.10-alpha.12 → 0.0.10-alpha.15
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 +14 -16
- package/dist/admin/index.js +1 -1
- package/dist/extension.js +4 -4
- package/dist/extension.manifest.json +16 -16
- package/docs/README.md +21 -21
- package/docs/SUMMARY.md +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
# AI
|
|
1
|
+
# Расширение AI-бота
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Официальное расширение Brand Map, которое запускает небольшой исполнитель AI-команд как Temporal-процесс `run-harness`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Процесс:
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
11
|
-
5.
|
|
7
|
+
1. Отправляет пользовательскую задачу, переданный контекст и системный промпт исполнителя настроенному AI-провайдеру.
|
|
8
|
+
2. Ожидает от модели точные JSON-команды.
|
|
9
|
+
3. Выполняет поддерживаемые команды расширений Brand Map и команды хранилища.
|
|
10
|
+
4. Отправляет накопленные эффекты команд обратно модели для финальной JSON-сводки.
|
|
11
|
+
5. Сохраняет последний запуск в хранилище расширения и возвращает сводку вызывающей стороне.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
`allowMutations: true`. `dryRun: true` runs reads but skips writes.
|
|
13
|
+
Команды мутаций требуют одновременно `allowMutations: true` в конфигурации установки и `allowMutations: true` во входных данных workflow. `dryRun: true` выполняет чтения, но пропускает записи.
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Пример входных данных workflow:
|
|
17
16
|
|
|
18
17
|
```json
|
|
19
18
|
{
|
|
20
|
-
"task": "
|
|
19
|
+
"task": "Проверь первые пять товаров и кратко опиши, где нет миниатюр.",
|
|
21
20
|
"context": {
|
|
22
21
|
"storeId": "store_1"
|
|
23
22
|
},
|
|
@@ -27,9 +26,8 @@ Example workflow input:
|
|
|
27
26
|
}
|
|
28
27
|
```
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
system prompt through the public Brand Map extension runtime APIs.
|
|
29
|
+
Расширение не запускает shell-команды. Оно выполняет явный каталог команд, объявленный в системном промпте, через публичные API runtime расширений Brand Map.
|
|
32
30
|
|
|
33
|
-
##
|
|
31
|
+
## Лицензия
|
|
34
32
|
|
|
35
|
-
UNLICENSED.
|
|
33
|
+
UNLICENSED. Этот пакет является проприетарным ПО Brand Map и публикуется только для авторизованного использования в runtime расширений Brand Map. Лицензия с открытым исходным кодом не предоставляется.
|
package/dist/admin/index.js
CHANGED
|
@@ -15,4 +15,4 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
15
15
|
<%s {...props} />
|
|
16
16
|
React keys must be passed directly to JSX without using spread:
|
|
17
17
|
let props = %s;
|
|
18
|
-
<%s key={someKey} {...props} />`,isStaticChildren,children,keys,children),didWarnAboutKeySpread[children+isStaticChildren]=true)}children=null;maybeKey!==undefined&&(checkKeyStringCoercion(maybeKey),children=""+maybeKey);hasValidKey(config)&&(checkKeyStringCoercion(config.key),children=""+config.key);if("key"in config){maybeKey={};for(var propName in config)propName!=="key"&&(maybeKey[propName]=config[propName])}else maybeKey=config;children&&defineKeyPropWarningGetter(maybeKey,typeof type==="function"?type.displayName||type.name||"Unknown":type);return ReactElement(type,children,maybeKey,getOwner(),debugStack,debugTask)}function validateChildKeys(node){isValidElement(node)?node._store&&(node._store.validated=1):typeof node==="object"&&node!==null&&node.$$typeof===REACT_LAZY_TYPE&&(node._payload.status==="fulfilled"?isValidElement(node._payload.value)&&node._payload.value._store&&(node._payload.value._store.validated=1):node._store&&(node._store.validated=1))}function isValidElement(object){return typeof object==="object"&&object!==null&&object.$$typeof===REACT_ELEMENT_TYPE}var REACT_ELEMENT_TYPE=Symbol.for("react.transitional.element"),REACT_PORTAL_TYPE=Symbol.for("react.portal"),REACT_FRAGMENT_TYPE=Symbol.for("react.fragment"),REACT_STRICT_MODE_TYPE=Symbol.for("react.strict_mode"),REACT_PROFILER_TYPE=Symbol.for("react.profiler"),REACT_CONSUMER_TYPE=Symbol.for("react.consumer"),REACT_CONTEXT_TYPE=Symbol.for("react.context"),REACT_FORWARD_REF_TYPE=Symbol.for("react.forward_ref"),REACT_SUSPENSE_TYPE=Symbol.for("react.suspense"),REACT_SUSPENSE_LIST_TYPE=Symbol.for("react.suspense_list"),REACT_MEMO_TYPE=Symbol.for("react.memo"),REACT_LAZY_TYPE=Symbol.for("react.lazy"),REACT_ACTIVITY_TYPE=Symbol.for("react.activity"),REACT_CLIENT_REFERENCE=Symbol.for("react.client.reference"),ReactSharedInternals=React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,hasOwnProperty=Object.prototype.hasOwnProperty,isArrayImpl=Array.isArray,createTask=console.createTask?console.createTask:function(){return null};React={react_stack_bottom_frame:function(callStackForError){return callStackForError()}};var specialPropKeyWarningShown;var didWarnAboutElementRef={};var unknownOwnerDebugStack=React.react_stack_bottom_frame.bind(React,UnknownOwner)();var unknownOwnerDebugTask=createTask(getTaskName(UnknownOwner));var didWarnAboutKeySpread={};exports.Fragment=REACT_FRAGMENT_TYPE;exports.jsxDEV=function(type,config,maybeKey,isStaticChildren){var trackActualOwner=1e4>ReactSharedInternals.recentlyCreatedOwnerStacks++;return jsxDEVImpl(type,config,maybeKey,isStaticChildren,trackActualOwner?Error("react-stack-top-frame"):unknownOwnerDebugStack,trackActualOwner?createTask(getTaskName(type)):unknownOwnerDebugTask)}})()});var require_jsx_dev_runtime=__commonJS((exports,module)=>{var react_jsx_dev_runtime_development=__toESM(require_react_jsx_dev_runtime_development());if(false){}else{module.exports=react_jsx_dev_runtime_development}});var exports_chat_widget={};__export(exports_chat_widget,{default:()=>AiBotChatWidget});function AiBotChatWidget(props){const admin=useAdmin();const[messages,setMessages]=import_react2.useState(initialMessages);const[draft,setDraft]=import_react2.useState("");const contextLabel=import_react2.useMemo(()=>props.storeId??"
|
|
18
|
+
<%s key={someKey} {...props} />`,isStaticChildren,children,keys,children),didWarnAboutKeySpread[children+isStaticChildren]=true)}children=null;maybeKey!==undefined&&(checkKeyStringCoercion(maybeKey),children=""+maybeKey);hasValidKey(config)&&(checkKeyStringCoercion(config.key),children=""+config.key);if("key"in config){maybeKey={};for(var propName in config)propName!=="key"&&(maybeKey[propName]=config[propName])}else maybeKey=config;children&&defineKeyPropWarningGetter(maybeKey,typeof type==="function"?type.displayName||type.name||"Unknown":type);return ReactElement(type,children,maybeKey,getOwner(),debugStack,debugTask)}function validateChildKeys(node){isValidElement(node)?node._store&&(node._store.validated=1):typeof node==="object"&&node!==null&&node.$$typeof===REACT_LAZY_TYPE&&(node._payload.status==="fulfilled"?isValidElement(node._payload.value)&&node._payload.value._store&&(node._payload.value._store.validated=1):node._store&&(node._store.validated=1))}function isValidElement(object){return typeof object==="object"&&object!==null&&object.$$typeof===REACT_ELEMENT_TYPE}var REACT_ELEMENT_TYPE=Symbol.for("react.transitional.element"),REACT_PORTAL_TYPE=Symbol.for("react.portal"),REACT_FRAGMENT_TYPE=Symbol.for("react.fragment"),REACT_STRICT_MODE_TYPE=Symbol.for("react.strict_mode"),REACT_PROFILER_TYPE=Symbol.for("react.profiler"),REACT_CONSUMER_TYPE=Symbol.for("react.consumer"),REACT_CONTEXT_TYPE=Symbol.for("react.context"),REACT_FORWARD_REF_TYPE=Symbol.for("react.forward_ref"),REACT_SUSPENSE_TYPE=Symbol.for("react.suspense"),REACT_SUSPENSE_LIST_TYPE=Symbol.for("react.suspense_list"),REACT_MEMO_TYPE=Symbol.for("react.memo"),REACT_LAZY_TYPE=Symbol.for("react.lazy"),REACT_ACTIVITY_TYPE=Symbol.for("react.activity"),REACT_CLIENT_REFERENCE=Symbol.for("react.client.reference"),ReactSharedInternals=React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,hasOwnProperty=Object.prototype.hasOwnProperty,isArrayImpl=Array.isArray,createTask=console.createTask?console.createTask:function(){return null};React={react_stack_bottom_frame:function(callStackForError){return callStackForError()}};var specialPropKeyWarningShown;var didWarnAboutElementRef={};var unknownOwnerDebugStack=React.react_stack_bottom_frame.bind(React,UnknownOwner)();var unknownOwnerDebugTask=createTask(getTaskName(UnknownOwner));var didWarnAboutKeySpread={};exports.Fragment=REACT_FRAGMENT_TYPE;exports.jsxDEV=function(type,config,maybeKey,isStaticChildren){var trackActualOwner=1e4>ReactSharedInternals.recentlyCreatedOwnerStacks++;return jsxDEVImpl(type,config,maybeKey,isStaticChildren,trackActualOwner?Error("react-stack-top-frame"):unknownOwnerDebugStack,trackActualOwner?createTask(getTaskName(type)):unknownOwnerDebugTask)}})()});var require_jsx_dev_runtime=__commonJS((exports,module)=>{var react_jsx_dev_runtime_development=__toESM(require_react_jsx_dev_runtime_development());if(false){}else{module.exports=react_jsx_dev_runtime_development}});var exports_chat_widget={};__export(exports_chat_widget,{default:()=>AiBotChatWidget});function AiBotChatWidget(props){const admin=useAdmin();const[messages,setMessages]=import_react2.useState(initialMessages);const[draft,setDraft]=import_react2.useState("");const contextLabel=import_react2.useMemo(()=>props.storeId??"текущий магазин",[props.storeId]);function sendMessage(event){event.preventDefault();const text=draft.trim();if(!text){return}setDraft("");admin.toast.info("Демо-ответ AI-бота сформирован.");setMessages((current)=>[...current,{id:`user-${Date.now()}`,role:"user",text},{id:`assistant-${Date.now()}`,role:"assistant",text:`Демо-режим для ${contextLabel}: "${text}"`}])}return jsx_dev_runtime.jsxDEV("div",{className:"flex h-full min-h-[28rem] flex-col",children:[jsx_dev_runtime.jsxDEV("div",{className:"flex-1 space-y-3 overflow-auto p-4",children:messages.map((message)=>jsx_dev_runtime.jsxDEV("div",{className:message.role==="user"?"flex justify-end":"flex justify-start",children:jsx_dev_runtime.jsxDEV("div",{className:message.role==="user"?"max-w-[85%] rounded-lg bg-primary px-3 py-2 text-sm text-primary-foreground":"max-w-[85%] rounded-lg border bg-muted/40 px-3 py-2 text-sm text-foreground",children:message.text},undefined,false,undefined,this)},message.id,false,undefined,this))},undefined,false,undefined,this),jsx_dev_runtime.jsxDEV("form",{className:"border-t p-3",onSubmit:sendMessage,children:jsx_dev_runtime.jsxDEV("div",{className:"flex gap-2",children:[jsx_dev_runtime.jsxDEV("input",{className:"min-w-0 flex-1 rounded-md border bg-background px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-ring",placeholder:"Сообщение AI-боту",value:draft,onChange:(event)=>setDraft(event.currentTarget.value)},undefined,false,undefined,this),jsx_dev_runtime.jsxDEV("button",{className:"rounded-md border bg-primary px-3 py-2 text-sm font-medium text-primary-foreground disabled:opacity-60",disabled:!draft.trim(),type:"submit",children:"Отправить"},undefined,false,undefined,this)]},undefined,true,undefined,this)},undefined,false,undefined,this)]},undefined,true,undefined,this)}var import_react2,jsx_dev_runtime,initialMessages;var init_chat_widget=__esm(()=>{init_dist();import_react2=__toESM(require_react(),1);jsx_dev_runtime=__toESM(require_jsx_dev_runtime(),1);initialMessages=[{id:"assistant-initial",role:"assistant",text:"Спросите, что проверить в этом магазине."}]});init_dist();var admin_default=defineAdminExtension({id:"ai-bot",name:"AI-бот",version:"0.0.10-alpha.15",description:"Демо-виджет чата для расширения AI-бота.",permissions:[],widgets:[{component:()=>Promise.resolve().then(() => (init_chat_widget(),exports_chat_widget)),icon:"message-circle",id:"chat",label:"AI-бот",order:10}]});export{admin_default as default};
|
package/dist/extension.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
function extension(input){return{callbacks:input.callbacks??[],eventHandlers:input.eventHandlers??[],hooks:input.hooks??[],jobs:input.jobs??[],manifest:{callbacks:(input.callbacks??[]).map((handler)=>({action:handler.action,name:handler.name})),config:input.config,description:input.description,developerUrl:input.developerUrl,displayName:input.displayName,eventHandlers:(input.eventHandlers??[]).map((handler)=>({event:handler.event,name:handler.name})),hooks:(input.hooks??[]).map((hook)=>({event:hook.event,name:hook.name})),jobs:(input.jobs??[]).map((job)=>({name:job.name,overlap:job.overlap,schedule:job.schedule,timezone:job.timezone})),logo:input.logo,name:input.name,permissions:input.permissions??[],publisher:input.publisher,version:input.version,workflows:(input.workflows??[]).map((workflow)=>({name:workflow.name}))},start:input.start,stop:input.stop,workflows:input.workflows??[]}}function callback(name,options,handler){const resolvedHandler=typeof options==="function"?options:handler;if(!resolvedHandler){throw new Error(`Extension callback "${name}" requires a handler`)}return{action:typeof options==="function"?name:options.action??name,handler:resolvedHandler,name}}function temporalWorkflow(name,handler){return{handler,name}}var store$4;var DEFAULT_CONFIG={lang:undefined,message:undefined,abortEarly:undefined,abortPipeEarly:undefined};function getGlobalConfig(config$1){if(!config$1&&!store$4)return DEFAULT_CONFIG;return{lang:config$1?.lang??store$4?.lang,message:config$1?.message,abortEarly:config$1?.abortEarly??store$4?.abortEarly,abortPipeEarly:config$1?.abortPipeEarly??store$4?.abortPipeEarly}}var store$3;function getGlobalMessage(lang){return store$3?.get(lang)}var store$2;function getSchemaMessage(lang){return store$2?.get(lang)}var store$1;function getSpecificMessage(reference,lang){return store$1?.get(reference)?.get(lang)}function _stringify(input){const type=typeof input;if(type==="string")return`"${input}"`;if(type==="number"||type==="bigint"||type==="boolean")return`${input}`;if(type==="object"||type==="function")return(input&&Object.getPrototypeOf(input)?.constructor?.name)??"null";return type}function _addIssue(context,label,dataset,config$1,other){const input=other&&"input"in other?other.input:dataset.value;const expected=other?.expected??context.expects??null;const received=other?.received??_stringify(input);const issue={kind:context.kind,type:context.type,input,expected,received,message:`Invalid ${label}: ${expected?`Expected ${expected} but r`:"R"}eceived ${received}`,requirement:context.requirement,path:other?.path,issues:other?.issues,lang:config$1.lang,abortEarly:config$1.abortEarly,abortPipeEarly:config$1.abortPipeEarly};const isSchema=context.kind==="schema";const message$1=other?.message??context.message??getSpecificMessage(context.reference,issue.lang)??(isSchema?getSchemaMessage(issue.lang):null)??config$1.message??getGlobalMessage(issue.lang);if(message$1!==undefined)issue.message=typeof message$1==="function"?message$1(issue):message$1;if(isSchema)dataset.typed=false;if(dataset.issues)dataset.issues.push(issue);else dataset.issues=[issue]}var _standardCache=new WeakMap;function _getStandardProps(context){let cached=_standardCache.get(context);if(!cached){cached={version:1,vendor:"valibot",validate(value$1){return context["~run"]({value:value$1},getGlobalConfig())}};_standardCache.set(context,cached)}return cached}function _isValidObjectKey(object$1,key){return Object.prototype.hasOwnProperty.call(object$1,key)&&key!=="__proto__"&&key!=="prototype"&&key!=="constructor"}function _joinExpects(values$1,separator){const list=[...new Set(values$1)];if(list.length>1)return`(${list.join(` ${separator} `)})`;return list[0]??"never"}var ValiError=class extends Error{constructor(issues){super(issues[0].message);this.name="ValiError";this.issues=issues}};function finite(message$1){return{kind:"validation",type:"finite",reference:finite,async:false,expects:null,requirement:Number.isFinite,message:message$1,"~run"(dataset,config$1){if(dataset.typed&&!this.requirement(dataset.value))_addIssue(this,"finite",dataset,config$1);return dataset}}}function minLength(requirement,message$1){return{kind:"validation",type:"min_length",reference:minLength,async:false,expects:`>=${requirement}`,requirement,message:message$1,"~run"(dataset,config$1){if(dataset.typed&&dataset.value.length<this.requirement)_addIssue(this,"length",dataset,config$1,{received:`${dataset.value.length}`});return dataset}}}function parseJson(config$1,message$1){return{kind:"transformation",type:"parse_json",reference:parseJson,config:config$1,message:message$1,async:false,"~run"(dataset,config$2){try{dataset.value=JSON.parse(dataset.value,this.config?.reviver)}catch(error){if(error instanceof Error){_addIssue(this,"JSON",dataset,config$2,{received:`"${error.message}"`});dataset.typed=false}else throw error}return dataset}}}function rawTransform(action){return{kind:"transformation",type:"raw_transform",reference:rawTransform,async:false,"~run"(dataset,config$1){const output=action({dataset,config:config$1,addIssue:(info)=>_addIssue(this,info?.label??"input",dataset,config$1,info),NEVER:null});if(dataset.issues)dataset.typed=false;else dataset.value=output;return dataset}}}function transform(operation){return{kind:"transformation",type:"transform",reference:transform,async:false,operation,"~run"(dataset){dataset.value=this.operation(dataset.value);return dataset}}}function trim(){return{kind:"transformation",type:"trim",reference:trim,async:false,"~run"(dataset){dataset.value=dataset.value.trim();return dataset}}}function getFallback(schema,dataset,config$1){return typeof schema.fallback==="function"?schema.fallback(dataset,config$1):schema.fallback}function getDefault(schema,dataset,config$1){return typeof schema.default==="function"?schema.default(dataset,config$1):schema.default}function array(item,message$1){return{kind:"schema",type:"array",reference:array,expects:"Array",async:false,item,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(Array.isArray(input)){dataset.typed=true;dataset.value=[];for(let key=0;key<input.length;key++){const value$1=input[key];const itemDataset=this.item["~run"]({value:value$1},config$1);if(itemDataset.issues){const pathItem={type:"array",origin:"value",input,key,value:value$1};for(const issue of itemDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=itemDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!itemDataset.typed)dataset.typed=false;dataset.value.push(itemDataset.value)}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function boolean(message$1){return{kind:"schema",type:"boolean",reference:boolean,expects:"boolean",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="boolean")dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function custom(check$1,message$1){return{kind:"schema",type:"custom",reference:custom,expects:"unknown",async:false,check:check$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(this.check(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function nullable(wrapped,default_){return{kind:"schema",type:"nullable",reference:nullable,expects:`(${wrapped.expects} | null)`,async:false,wrapped,default:default_,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(dataset.value===null){if(this.default!==undefined)dataset.value=getDefault(this,dataset,config$1);if(dataset.value===null){dataset.typed=true;return dataset}}return this.wrapped["~run"](dataset,config$1)}}}function number(message$1){return{kind:"schema",type:"number",reference:number,expects:"number",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="number"&&!isNaN(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function object(entries$1,message$1){return{kind:"schema",type:"object",reference:object,expects:"Object",async:false,entries:entries$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const key in this.entries){const valueSchema=this.entries[key];if(key in input||(valueSchema.type==="exact_optional"||valueSchema.type==="optional"||valueSchema.type==="nullish")&&valueSchema.default!==undefined){const value$1=key in input?input[key]:getDefault(valueSchema);const valueDataset=valueSchema["~run"]({value:value$1},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key,value:value$1};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!valueDataset.typed)dataset.typed=false;dataset.value[key]=valueDataset.value}else if(valueSchema.fallback!==undefined)dataset.value[key]=getFallback(valueSchema);else if(valueSchema.type!=="exact_optional"&&valueSchema.type!=="optional"&&valueSchema.type!=="nullish"){_addIssue(this,"key",dataset,config$1,{input:undefined,expected:`"${key}"`,path:[{type:"object",origin:"key",input,key,value:input[key]}]});if(config$1.abortEarly)break}}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function optional(wrapped,default_){return{kind:"schema",type:"optional",reference:optional,expects:`(${wrapped.expects} | undefined)`,async:false,wrapped,default:default_,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(dataset.value===undefined){if(this.default!==undefined)dataset.value=getDefault(this,dataset,config$1);if(dataset.value===undefined){dataset.typed=true;return dataset}}return this.wrapped["~run"](dataset,config$1)}}}function picklist(options,message$1){return{kind:"schema",type:"picklist",reference:picklist,expects:_joinExpects(options.map(_stringify),"|"),async:false,options,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(this.options.includes(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function record(key,value$1,message$1){return{kind:"schema",type:"record",reference:record,expects:"Object",async:false,key,value:value$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const entryKey in input)if(_isValidObjectKey(input,entryKey)){const entryValue=input[entryKey];const keyDataset=this.key["~run"]({value:entryKey},config$1);if(keyDataset.issues){const pathItem={type:"object",origin:"key",input,key:entryKey,value:entryValue};for(const issue of keyDataset.issues){issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=keyDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}const valueDataset=this.value["~run"]({value:entryValue},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key:entryKey,value:entryValue};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!keyDataset.typed||!valueDataset.typed)dataset.typed=false;if(keyDataset.typed)dataset.value[keyDataset.value]=valueDataset.value}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function strictObject(entries$1,message$1){return{kind:"schema",type:"strict_object",reference:strictObject,expects:"Object",async:false,entries:entries$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const key in this.entries){const valueSchema=this.entries[key];if(key in input||(valueSchema.type==="exact_optional"||valueSchema.type==="optional"||valueSchema.type==="nullish")&&valueSchema.default!==undefined){const value$1=key in input?input[key]:getDefault(valueSchema);const valueDataset=valueSchema["~run"]({value:value$1},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key,value:value$1};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!valueDataset.typed)dataset.typed=false;dataset.value[key]=valueDataset.value}else if(valueSchema.fallback!==undefined)dataset.value[key]=getFallback(valueSchema);else if(valueSchema.type!=="exact_optional"&&valueSchema.type!=="optional"&&valueSchema.type!=="nullish"){_addIssue(this,"key",dataset,config$1,{input:undefined,expected:`"${key}"`,path:[{type:"object",origin:"key",input,key,value:input[key]}]});if(config$1.abortEarly)break}}if(!dataset.issues||!config$1.abortEarly){for(const key in input)if(!(key in this.entries)){_addIssue(this,"key",dataset,config$1,{input:key,expected:"never",path:[{type:"object",origin:"key",input,key,value:input[key]}]});break}}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function string(message$1){return{kind:"schema",type:"string",reference:string,expects:"string",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="string")dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function _subIssues(datasets){let issues;if(datasets)for(const dataset of datasets)if(issues)for(const issue of dataset.issues)issues.push(issue);else issues=dataset.issues;return issues}function union(options,message$1){return{kind:"schema",type:"union",reference:union,expects:_joinExpects(options.map((option)=>option.expects),"|"),async:false,options,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){let validDataset;let typedDatasets;let untypedDatasets;for(const schema of this.options){const optionDataset=schema["~run"]({value:dataset.value},config$1);if(optionDataset.typed)if(optionDataset.issues)if(typedDatasets)typedDatasets.push(optionDataset);else typedDatasets=[optionDataset];else{validDataset=optionDataset;break}else if(untypedDatasets)untypedDatasets.push(optionDataset);else untypedDatasets=[optionDataset]}if(validDataset)return validDataset;if(typedDatasets){if(typedDatasets.length===1)return typedDatasets[0];_addIssue(this,"type",dataset,config$1,{issues:_subIssues(typedDatasets)});dataset.typed=true}else if(untypedDatasets?.length===1)return untypedDatasets[0];else _addIssue(this,"type",dataset,config$1,{issues:_subIssues(untypedDatasets)});return dataset}}}function unknown(){return{kind:"schema",type:"unknown",reference:unknown,expects:"unknown",async:false,get "~standard"(){return _getStandardProps(this)},"~run"(dataset){dataset.typed=true;return dataset}}}function parse(schema,input,config$1){const dataset=schema["~run"]({value:input},getGlobalConfig(config$1));if(dataset.issues)throw new ValiError(dataset.issues);return dataset.value}function partial(schema,keys){const entries$1={};for(const key in schema.entries)entries$1[key]=!keys||keys.includes(key)?optional(schema.entries[key]):schema.entries[key];return{...schema,entries:entries$1,get "~standard"(){return _getStandardProps(this)}}}function pipe(...pipe$1){return{...pipe$1[0],pipe:pipe$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){for(const item of pipe$1)if(item.kind!=="metadata"){if(dataset.issues&&(item.kind==="schema"||item.kind==="transformation")){dataset.typed=false;break}if(!dataset.issues||!config$1.abortEarly&&!config$1.abortPipeEarly)dataset=item["~run"](dataset,config$1)}return dataset}}}var ExtensionJsonSchema=custom(isExtensionJson,"Expected JSON-compatible value");var ExtensionSerializableValueSchema=custom(isExtensionSerializableValue,"Expected extension RPC-serializable value");var ExtensionOperationArgumentsSchema=array(ExtensionSerializableValueSchema);var OptionalExtensionJsonSchema=optional(nullable(ExtensionJsonSchema));var FiniteNumberSchema=pipe(number(),finite());var NonEmptyTrimmedStringSchema=pipe(string(),trim(),minLength(1));var StringFromScalarSchema=pipe(union([string(),FiniteNumberSchema,boolean()]),transform((value)=>String(value)));var NonEmptyStringFromScalarSchema=pipe(StringFromScalarSchema,trim(),minLength(1));var ExtensionJsonTransformSchema=pipe(unknown(),rawTransform((context)=>{try{return toExtensionJson(context.dataset.value)}catch(error){context.addIssue({message:error instanceof Error?error.message:"Expected JSON-compatible value"});return context.NEVER}}));var JsonTextSchema=pipe(string(),parseJson(),ExtensionJsonTransformSchema);var JsonRecordSchema=pipe(ExtensionJsonTransformSchema,rawTransform((context)=>{const value=context.dataset.value;if(!isPlainRecord(value)){context.addIssue({message:"Expected JSON object"});return context.NEVER}return value}));var JsonArraySchema=pipe(ExtensionJsonTransformSchema,rawTransform((context)=>{const value=context.dataset.value;if(!Array.isArray(value)){context.addIssue({message:"Expected JSON array"});return context.NEVER}return value}));var ExtensionReadQuerySchema=strictObject({joins:optional(ExtensionJsonSchema),limit:optional(FiniteNumberSchema),offset:optional(FiniteNumberSchema),order:optional(ExtensionJsonSchema),where:optional(ExtensionJsonSchema)});var ExtensionPermissionSchema=pipe(string(),minLength(1));var ExtensionConfigOptionSchema=object({label:pipe(string(),minLength(1)),value:pipe(string(),minLength(1))});var ExtensionConfigFieldSchema=object({defaultValue:optional(unknown()),description:optional(string()),key:pipe(string(),minLength(1)),label:pipe(string(),minLength(1)),options:optional(array(ExtensionConfigOptionSchema)),required:optional(boolean()),secret:optional(boolean()),type:picklist(["boolean","multi-select","number","select","string","url"])});var ExtensionLogoSchema=object({alt:optional(string()),src:pipe(string(),minLength(1))});var ExtensionHttpMethodSchema=picklist(["DELETE","GET","PATCH","POST","PUT"]);var ExtensionInvocationKindSchema=picklist(["callback","event","job","hook","workflow"]);var ExtensionCallbackSchema=object({action:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionEventHandlerSchema=object({event:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionJobOverlapPolicySchema=picklist(["ALLOW_ALL","BUFFER_ALL","BUFFER_ONE","CANCEL_OTHER","SKIP","TERMINATE_OTHER"]);var ExtensionJobSchema=object({name:pipe(string(),minLength(1)),overlap:optional(ExtensionJobOverlapPolicySchema),schedule:pipe(string(),minLength(1)),timezone:optional(string())});var ExtensionLifecycleHookSchema=object({event:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionTemporalWorkflowSchema=object({name:pipe(string(),minLength(1))});var ExtensionManifestSchema=object({config:optional(array(ExtensionConfigFieldSchema)),description:optional(string()),developerUrl:optional(pipe(string(),minLength(1))),displayName:optional(pipe(string(),minLength(1))),eventHandlers:optional(array(ExtensionEventHandlerSchema)),hooks:optional(array(ExtensionLifecycleHookSchema)),jobs:optional(array(ExtensionJobSchema)),logo:optional(ExtensionLogoSchema),name:pipe(string(),minLength(1)),permissions:optional(array(ExtensionPermissionSchema)),publisher:optional(pipe(string(),minLength(1))),callbacks:optional(array(ExtensionCallbackSchema)),version:pipe(string(),minLength(1)),workflows:optional(array(ExtensionTemporalWorkflowSchema))});var ExtensionCategoryCreateInputSchema=strictObject({metadata:OptionalExtensionJsonSchema,name:string(),parentCategoryId:optional(nullable(string())),slug:string(),status:optional(string())});var ExtensionCategoryUpdateInputSchema=partial(ExtensionCategoryCreateInputSchema);var ExtensionCategorySchema=object({id:string(),metadata:OptionalExtensionJsonSchema,name:optional(string()),parentCategoryId:optional(nullable(string())),slug:string(),status:optional(string())});var ExtensionProductImageSchema=object({rank:optional(nullable(FiniteNumberSchema)),url:string()});var ExtensionProductOptionInputSchema=strictObject({rank:optional(nullable(FiniteNumberSchema)),title:string()});var ExtensionProductOptionSchema=object({id:string(),productId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),title:string()});var ExtensionProductOptionValueInputSchema=strictObject({colorHex:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),value:string()});var ExtensionProductOptionValueSchema=object({colorHex:optional(nullable(string())),id:string(),optionId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),value:string()});var ExtensionProductVariantOptionValueSchema=object({id:string(),optionId:optional(string()),optionValueId:optional(string()),productId:optional(string()),variantId:optional(string())});var ExtensionProductAttributeInputSchema=strictObject({isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:string(),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"])))});var ExtensionProductAttributeSchema=object({id:string(),isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:string(),productId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"])))});var ExtensionProductAttributeValueInputSchema=strictObject({attributeId:string(),productId:optional(nullable(string())),valueBoolean:optional(nullable(boolean())),valueNumber:optional(nullable(union([FiniteNumberSchema,string()]))),valueText:optional(nullable(string())),variantId:optional(nullable(string()))});var ExtensionProductAttributeValueSchema=object({attributeId:optional(string()),id:string(),productId:optional(nullable(string())),valueBoolean:optional(nullable(boolean())),valueNumber:optional(nullable(union([FiniteNumberSchema,string()]))),valueText:optional(nullable(string())),variantId:optional(nullable(string()))});var ExtensionCatalogBatchImageSchema=strictObject({rank:optional(nullable(FiniteNumberSchema)),url:string()});var ExtensionCatalogBatchAttributeSchema=strictObject({isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"]))),value:union([boolean(),FiniteNumberSchema,string()])});var ExtensionCatalogBatchOptionSchema=strictObject({colorHex:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),title:optional(nullable(string())),value:string()});var ExtensionCatalogBatchPriceSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(nullable(FiniteNumberSchema)),costAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(nullable(string()))});var ExtensionCatalogBatchPriceListPriceSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(nullable(FiniteNumberSchema)),costAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(nullable(string())),key:string(),title:optional(nullable(string()))});var ExtensionCatalogBatchInventorySchema=strictObject({sku:optional(nullable(string())),stockLocationCode:string(),stockLocationName:optional(nullable(string())),stockedQuantity:FiniteNumberSchema,storeId:optional(nullable(string()))});var ExtensionCatalogBatchVariantSchema=strictObject({attributes:optional(array(ExtensionCatalogBatchAttributeSchema)),externalSku:string(),inventory:optional(array(ExtensionCatalogBatchInventorySchema)),isActive:optional(nullable(boolean())),manageInventory:optional(nullable(boolean())),metadata:optional(nullable(record(string(),ExtensionJsonSchema))),options:optional(record(string(),ExtensionCatalogBatchOptionSchema)),prices:optional(strictObject({base:optional(nullable(ExtensionCatalogBatchPriceSchema)),lists:optional(array(ExtensionCatalogBatchPriceListPriceSchema))})),title:optional(nullable(string()))});var ExtensionCatalogBatchProductSchema=strictObject({attributes:optional(array(ExtensionCatalogBatchAttributeSchema)),categoryId:optional(nullable(string())),description:optional(nullable(string())),images:optional(array(ExtensionCatalogBatchImageSchema)),metadata:optional(nullable(record(string(),ExtensionJsonSchema))),slug:string(),status:optional(nullable(string())),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string(),variants:array(ExtensionCatalogBatchVariantSchema)});var ExtensionCatalogBatchInputSchema=strictObject({products:array(ExtensionCatalogBatchProductSchema),source:string(),storeId:optional(nullable(string()))});var ExtensionCatalogBatchErrorSchema=strictObject({chunkIndex:nullable(FiniteNumberSchema),error:string(),index:FiniteNumberSchema,slug:string()});var ExtensionCatalogBatchResultSchema=strictObject({attributesUpserted:FiniteNumberSchema,chunksProcessed:FiniteNumberSchema,errors:array(ExtensionCatalogBatchErrorSchema),imagesAdded:FiniteNumberSchema,inventorySynced:FiniteNumberSchema,priceListPricesSet:FiniteNumberSchema,priceListsUpserted:FiniteNumberSchema,pricesSet:FiniteNumberSchema,productsCreated:FiniteNumberSchema,productsUpdated:FiniteNumberSchema,rowsProcessed:FiniteNumberSchema,variantOptionValuesLinked:FiniteNumberSchema,variantsCreated:FiniteNumberSchema,variantsUpdated:FiniteNumberSchema});var ExtensionProductCreateInputSchema=strictObject({categoryId:optional(nullable(string())),description:optional(nullable(string())),metadata:OptionalExtensionJsonSchema,slug:string(),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string()});var ExtensionProductUpdateInputSchema=strictObject({categoryId:optional(nullable(string())),description:optional(nullable(string())),id:string(),metadata:OptionalExtensionJsonSchema,slug:optional(string()),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:optional(string())});var ExtensionProductSchema=object({attributes:optional(nullable(array(ExtensionJsonSchema))),categoryId:optional(nullable(string())),description:optional(nullable(string())),id:string(),images:optional(array(ExtensionProductImageSchema)),metadata:OptionalExtensionJsonSchema,options:optional(nullable(array(ExtensionJsonSchema))),slug:string(),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string(),updatedAt:optional(string())});var ExtensionVariantCreateInputSchema=strictObject({externalSku:string(),isActive:optional(boolean()),manageInventory:optional(boolean()),metadata:OptionalExtensionJsonSchema,title:string()});var ExtensionVariantUpdateInputSchema=partial(ExtensionVariantCreateInputSchema);var ExtensionVariantSchema=object({attributeValues:optional(nullable(array(ExtensionJsonSchema))),externalSku:optional(nullable(string())),id:string(),inventoryItems:optional(nullable(array(ExtensionJsonSchema))),isActive:optional(nullable(boolean())),manageInventory:optional(nullable(boolean())),metadata:OptionalExtensionJsonSchema,optionValueLinks:optional(nullable(array(ExtensionJsonSchema))),priceListPrices:optional(nullable(array(ExtensionJsonSchema))),prices:optional(nullable(array(ExtensionJsonSchema))),productId:string(),title:optional(nullable(string())),updatedAt:optional(string())});var ExtensionFileContentSchema=custom((value)=>typeof value==="string"||value instanceof Uint8Array||value instanceof ArrayBuffer||value instanceof Blob,"Expected string, Uint8Array, ArrayBuffer, or Blob");var ExtensionFileCreateInputSchema=strictObject({access:optional(picklist(["private","public"])),content:ExtensionFileContentSchema,filename:string(),mimeType:string()});var ExtensionFileSchema=object({access:optional(picklist(["private","public"])),createdAt:optional(string()),filename:optional(string()),id:string(),mimeType:optional(nullable(string())),size:optional(nullable(FiniteNumberSchema)),updatedAt:optional(string()),url:optional(nullable(string()))});var ExtensionNotificationProviderDataSchema=strictObject({messageThreadId:optional(string()),parseMode:optional(picklist(["HTML","MarkdownV2"])),providerId:optional(string())});var ExtensionNotificationSendInputSchema=strictObject({channel:picklist(["telegram"]),content:strictObject({text:pipe(string(),minLength(1))}),data:optional(record(string(),ExtensionJsonSchema)),idempotencyKey:optional(string()),providerData:optional(ExtensionNotificationProviderDataSchema),to:pipe(string(),minLength(1))});var ExtensionNotificationSchema=object({channel:picklist(["telegram"]),createdAt:optional(string()),externalId:optional(string()),id:string(),idempotencyKey:optional(string()),providerData:optional(nullable(record(string(),ExtensionJsonSchema))),status:picklist(["failure","pending","success"]),to:string(),updatedAt:optional(string())});var ExtensionInventoryItemEnrollLevelInputSchema=strictObject({lastSyncedAt:optional(string()),metadata:OptionalExtensionJsonSchema,sourceSystem:optional(string()),stockLocationId:string(),stockedQuantity:FiniteNumberSchema});var ExtensionInventoryItemEnrollInputSchema=strictObject({inventoryLevels:optional(array(ExtensionInventoryItemEnrollLevelInputSchema)),isManaged:optional(boolean()),metadata:OptionalExtensionJsonSchema,sku:string(),storeId:string(),variantId:string()});var ExtensionInventoryItemSchema=object({code:optional(nullable(string())),id:string(),metadata:OptionalExtensionJsonSchema,sku:optional(nullable(string())),storeId:optional(string()),variantId:optional(string())});var ExtensionStockLocationCreateInputSchema=strictObject({code:string(),isEnabled:optional(boolean()),metadata:OptionalExtensionJsonSchema,name:string(),storeId:string(),type:optional(string())});var ExtensionStockLocationUpdateInputSchema=strictObject({code:optional(string()),id:string(),isEnabled:optional(boolean()),metadata:OptionalExtensionJsonSchema,name:optional(string()),storeId:optional(string()),type:optional(string())});var ExtensionStockLocationSchema=object({code:optional(nullable(string())),id:string(),isEnabled:optional(nullable(boolean())),metadata:OptionalExtensionJsonSchema,name:optional(string()),storeId:optional(string()),type:optional(string())});var ExtensionStockLevelSyncInputSchema=strictObject({inventoryItemId:string(),lastSyncedAt:optional(string()),metadata:OptionalExtensionJsonSchema,sourceSystem:optional(string()),stockLocationId:string(),stockedQuantity:FiniteNumberSchema});var ExtensionStockLevelSchema=object({id:optional(string()),inventoryItemId:optional(string()),stockLocationId:optional(string()),stockedQuantity:optional(FiniteNumberSchema)});var ExtensionPriceListCreateInputSchema=strictObject({automaticallyApplies:optional(boolean()),metadata:OptionalExtensionJsonSchema,priority:optional(FiniteNumberSchema),status:optional(string()),storeId:string(),title:string(),type:optional(string())});var ExtensionPriceListUpdateInputSchema=strictObject({automaticallyApplies:optional(boolean()),id:string(),metadata:OptionalExtensionJsonSchema,priority:optional(FiniteNumberSchema),status:optional(string()),title:optional(string()),type:optional(string())});var ExtensionPriceListSchema=object({automaticallyApplies:optional(nullable(boolean())),id:string(),metadata:OptionalExtensionJsonSchema,priority:optional(nullable(FiniteNumberSchema)),status:optional(string()),storeId:optional(string()),title:optional(string()),type:optional(string())});var ExtensionPriceListPriceCreateInputSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(FiniteNumberSchema),currencyCode:string(),metadata:OptionalExtensionJsonSchema,priceListId:string(),variantId:string()});var ExtensionPriceListPriceUpdateInputSchema=strictObject({amount:optional(FiniteNumberSchema),compareAtAmount:optional(FiniteNumberSchema),currencyCode:optional(string()),id:string(),metadata:OptionalExtensionJsonSchema,priceListId:optional(string()),variantId:optional(string())});var ExtensionPriceListPriceSchema=object({amount:optional(nullable(FiniteNumberSchema)),compareAtAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(string()),id:string(),metadata:OptionalExtensionJsonSchema,priceListId:optional(string()),variantId:optional(string())});var ExtensionBasePriceSetInputSchema=strictObject({amount:FiniteNumberSchema,atTime:optional(string()),compareAtAmount:optional(FiniteNumberSchema),costAmount:optional(FiniteNumberSchema),currencyCode:string(),taxIncluded:optional(boolean()),variantId:string()});var ExtensionPriceSchema=object({amount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(string()),id:string(),variantId:optional(string())});function parseJsonText(input){return parse(JsonTextSchema,input)}function toExtensionJson(value,seen=new WeakSet,depth=0){if(value===null||typeof value==="boolean"||typeof value==="string"){return value}if(typeof value==="number"){return Number.isFinite(value)?value:null}if(typeof value==="bigint"){return value.toString()}if(value===undefined||typeof value==="function"||typeof value==="symbol"){return null}if(value instanceof Date){return Number.isFinite(value.getTime())?value.toISOString():null}if(value instanceof Uint8Array){return Array.from(value)}if(value instanceof ArrayBuffer){return Array.from(new Uint8Array(value))}if(typeof value==="object"){if(seen.has(value)){return null}seen.add(value);if(depth>50){return"[Truncated]"}if(Array.isArray(value)){return value.map((entry)=>toExtensionJson(entry,seen,depth+1))}const output={};for(const[key,entry]of Object.entries(value)){if(entry!==undefined&&typeof entry!=="function"&&typeof entry!=="symbol"){output[key]=toExtensionJson(entry,seen,depth+1)}}return output}return null}function isExtensionJson(value){if(value===null){return true}switch(typeof value){case"boolean":case"string":return true;case"number":return Number.isFinite(value);case"object":if(Array.isArray(value)){return value.every(isExtensionJson)}if(!isPlainRecord(value)){return false}return Object.values(value).every(isExtensionJson);default:return false}}function isPlainRecord(value){if(!value||typeof value!=="object"||Array.isArray(value)){return false}const prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function isExtensionSerializableValue(value,seen=new Set){if(value===undefined||value===null){return true}switch(typeof value){case"boolean":case"string":return true;case"number":return Number.isFinite(value);case"object":{if(value instanceof Date){return Number.isFinite(value.getTime())}if(value instanceof Uint8Array||value instanceof ArrayBuffer){return true}if(seen.has(value)){return false}seen.add(value);if(Array.isArray(value)){return value.every((entry)=>isExtensionSerializableValue(entry,seen))}const prototype=Object.getPrototypeOf(value);if(prototype!==Object.prototype&&prototype!==null){return false}return Object.values(value).every((entry)=>isExtensionSerializableValue(entry,seen))}default:return false}}var AI_BOT_EXTENSION_NAME="ai-bot";var AI_BOT_VERSION="0.0.10-alpha.12";var DEFAULT_MODEL="gpt-4.1-mini";var DEFAULT_OPENAI_BASE_URL="https://api.openai.com/v1";var DEFAULT_ANTHROPIC_BASE_URL="https://api.anthropic.com/v1";var DEFAULT_MAX_COMMANDS=8;var RUN_HISTORY_PREFIX="ai-bot.runs.";var LAST_RUN_KEY="ai-bot.last-run";var MAX_EFFECT_RESULT_CHARS=8000;var MAX_MODEL_CONTEXT_CHARS=12000;var COMMANDS=[{command:"product.list",description:"List products with an optional read query.",mutates:false},{command:"product.retrieve",description:"Retrieve one product by id.",mutates:false},{command:"product.retrieveVariantByExternalSku",description:"Retrieve a variant by external SKU.",mutates:false},{command:"product.listVariants",description:"List variants for a product id.",mutates:false},{command:"product.listCategories",description:"List product categories.",mutates:false},{command:"price.listPriceList",description:"List price lists.",mutates:false},{command:"price.listPriceListPrice",description:"List price list prices.",mutates:false},{command:"stockLocation.listStockLocation",description:"List stock locations.",mutates:false},{command:"stockLocation.retrieveStockLocation",description:"Retrieve one stock location by id.",mutates:false},{command:"notification.listNotifications",description:"List notifications.",mutates:false},{command:"notification.retrieveNotification",description:"Retrieve one notification by id.",mutates:false},{command:"file.list",description:"List files.",mutates:false},{command:"file.retrieve",description:"Retrieve file metadata by id.",mutates:false},{command:"storage.db.get",description:"Read one extension storage record by key.",mutates:false},{command:"storage.db.list",description:"List extension storage records.",mutates:false},{command:"storage.cache.get",description:"Read one extension cache value by key.",mutates:false},{command:"product.create",description:"Create one or more products.",mutates:true},{command:"product.update",description:"Update one or more products.",mutates:true},{command:"product.createCategory",description:"Create a product category.",mutates:true},{command:"product.updateCategory",description:"Update a product category.",mutates:true},{command:"product.createVariant",description:"Create a product variant.",mutates:true},{command:"product.updateVariant",description:"Update a product variant.",mutates:true},{command:"product.addImage",description:"Add an image URL to a product.",mutates:true},{command:"product.upsertOption",description:"Create or update a product option.",mutates:true},{command:"product.upsertOptionValue",description:"Create or update a product option value.",mutates:true},{command:"product.linkVariantOptionValue",description:"Link a variant to an option value.",mutates:true},{command:"product.upsertAttribute",description:"Create or update a product attribute.",mutates:true},{command:"product.upsertAttributeValue",description:"Create or update a product attribute value.",mutates:true},{command:"price.createPriceList",description:"Create one or more price lists.",mutates:true},{command:"price.updatePriceList",description:"Update one or more price lists.",mutates:true},{command:"price.createPriceListPrice",description:"Create one or more price list prices.",mutates:true},{command:"price.updatePriceListPrice",description:"Update one or more price list prices.",mutates:true},{command:"price.setBasePrice",description:"Set a variant base price.",mutates:true},{command:"stockLocation.createStockLocation",description:"Create a stock location.",mutates:true},{command:"stockLocation.updateStockLocation",description:"Update a stock location.",mutates:true},{command:"stockLocation.upsertStockLocation",description:"Create or update a stock location.",mutates:true},{command:"inventory.enrollVariantInStore",description:"Enroll a variant in store inventory.",mutates:true},{command:"inventory.syncStockLevel",description:"Sync a stock level.",mutates:true},{command:"notification.createNotifications",description:"Create one or more notifications.",mutates:true},{command:"file.create",description:"Create a file from string content.",mutates:true},{command:"file.delete",description:"Delete one or more files by id.",mutates:true},{command:"storage.db.set",description:"Write an extension storage record.",mutates:true},{command:"storage.db.delete",description:"Delete extension storage records.",mutates:true},{command:"storage.cache.set",description:"Write an extension cache value.",mutates:true},{command:"storage.cache.delete",description:"Delete extension cache values.",mutates:true}];var COMMAND_BY_NAME=new Map(COMMANDS.map((command)=>[command.command,command]));var COMMAND_CATALOG_TEXT=COMMANDS.map((entry)=>`- ${entry.command} (${entry.mutates?"mutation":"read"}): ${entry.description}`).join(`
|
|
3
|
-
`);var AI_BOT_PERMISSIONS=["extension-storage:read","extension-storage:write","network:https://*/*","operation:file.create","operation:file.delete","operation:file.list","operation:file.retrieve","operation:inventory.enrollVariantInStore","operation:inventory.syncStockLevel","operation:notification.createNotifications","operation:notification.listNotifications","operation:notification.retrieveNotification","operation:price.createPriceList","operation:price.createPriceListPrice","operation:price.listPriceList","operation:price.listPriceListPrice","operation:price.setBasePrice","operation:price.updatePriceList","operation:price.updatePriceListPrice","operation:product.addImage","operation:product.create","operation:product.createCategory","operation:product.createVariant","operation:product.linkVariantOptionValue","operation:product.list","operation:product.listCategories","operation:product.listVariants","operation:product.retrieve","operation:product.retrieveVariantByExternalSku","operation:product.update","operation:product.updateCategory","operation:product.updateVariant","operation:product.upsertAttribute","operation:product.upsertAttributeValue","operation:product.upsertOption","operation:product.upsertOptionValue","operation:stockLocation.createStockLocation","operation:stockLocation.listStockLocation","operation:stockLocation.retrieveStockLocation","operation:stockLocation.updateStockLocation","operation:stockLocation.upsertStockLocation"];var DEFAULT_SYSTEM_PROMPT=["
|
|
2
|
+
function extension(input){return{callbacks:input.callbacks??[],eventHandlers:input.eventHandlers??[],hooks:input.hooks??[],jobs:input.jobs??[],manifest:{callbacks:(input.callbacks??[]).map((handler)=>({action:handler.action,name:handler.name})),config:input.config,description:input.description,developerUrl:input.developerUrl,displayName:input.displayName,eventHandlers:(input.eventHandlers??[]).map((handler)=>({event:handler.event,name:handler.name})),hooks:(input.hooks??[]).map((hook)=>({event:hook.event,name:hook.name})),jobs:(input.jobs??[]).map((job)=>({name:job.name,overlap:job.overlap,schedule:job.schedule,timezone:job.timezone})),logo:input.logo,name:input.name,permissions:input.permissions??[],publisher:input.publisher,version:input.version,workflows:(input.workflows??[]).map((workflow)=>({name:workflow.name}))},start:input.start,stop:input.stop,workflows:input.workflows??[]}}function callback(name,options,handler){const resolvedHandler=typeof options==="function"?options:handler;if(!resolvedHandler){throw new Error(`Extension callback "${name}" requires a handler`)}return{action:typeof options==="function"?name:options.action??name,handler:resolvedHandler,name}}function temporalWorkflow(name,handler){return{handler,name}}var store$4;var DEFAULT_CONFIG={lang:undefined,message:undefined,abortEarly:undefined,abortPipeEarly:undefined};function getGlobalConfig(config$1){if(!config$1&&!store$4)return DEFAULT_CONFIG;return{lang:config$1?.lang??store$4?.lang,message:config$1?.message,abortEarly:config$1?.abortEarly??store$4?.abortEarly,abortPipeEarly:config$1?.abortPipeEarly??store$4?.abortPipeEarly}}var store$3;function getGlobalMessage(lang){return store$3?.get(lang)}var store$2;function getSchemaMessage(lang){return store$2?.get(lang)}var store$1;function getSpecificMessage(reference,lang){return store$1?.get(reference)?.get(lang)}function _stringify(input){const type=typeof input;if(type==="string")return`"${input}"`;if(type==="number"||type==="bigint"||type==="boolean")return`${input}`;if(type==="object"||type==="function")return(input&&Object.getPrototypeOf(input)?.constructor?.name)??"null";return type}function _addIssue(context,label,dataset,config$1,other){const input=other&&"input"in other?other.input:dataset.value;const expected=other?.expected??context.expects??null;const received=other?.received??_stringify(input);const issue={kind:context.kind,type:context.type,input,expected,received,message:`Invalid ${label}: ${expected?`Expected ${expected} but r`:"R"}eceived ${received}`,requirement:context.requirement,path:other?.path,issues:other?.issues,lang:config$1.lang,abortEarly:config$1.abortEarly,abortPipeEarly:config$1.abortPipeEarly};const isSchema=context.kind==="schema";const message$1=other?.message??context.message??getSpecificMessage(context.reference,issue.lang)??(isSchema?getSchemaMessage(issue.lang):null)??config$1.message??getGlobalMessage(issue.lang);if(message$1!==undefined)issue.message=typeof message$1==="function"?message$1(issue):message$1;if(isSchema)dataset.typed=false;if(dataset.issues)dataset.issues.push(issue);else dataset.issues=[issue]}var _standardCache=new WeakMap;function _getStandardProps(context){let cached=_standardCache.get(context);if(!cached){cached={version:1,vendor:"valibot",validate(value$1){return context["~run"]({value:value$1},getGlobalConfig())}};_standardCache.set(context,cached)}return cached}function _isValidObjectKey(object$1,key){return Object.prototype.hasOwnProperty.call(object$1,key)&&key!=="__proto__"&&key!=="prototype"&&key!=="constructor"}function _joinExpects(values$1,separator){const list=[...new Set(values$1)];if(list.length>1)return`(${list.join(` ${separator} `)})`;return list[0]??"never"}var ValiError=class extends Error{constructor(issues){super(issues[0].message);this.name="ValiError";this.issues=issues}};function finite(message$1){return{kind:"validation",type:"finite",reference:finite,async:false,expects:null,requirement:Number.isFinite,message:message$1,"~run"(dataset,config$1){if(dataset.typed&&!this.requirement(dataset.value))_addIssue(this,"finite",dataset,config$1);return dataset}}}function minLength(requirement,message$1){return{kind:"validation",type:"min_length",reference:minLength,async:false,expects:`>=${requirement}`,requirement,message:message$1,"~run"(dataset,config$1){if(dataset.typed&&dataset.value.length<this.requirement)_addIssue(this,"length",dataset,config$1,{received:`${dataset.value.length}`});return dataset}}}function parseJson(config$1,message$1){return{kind:"transformation",type:"parse_json",reference:parseJson,config:config$1,message:message$1,async:false,"~run"(dataset,config$2){try{dataset.value=JSON.parse(dataset.value,this.config?.reviver)}catch(error){if(error instanceof Error){_addIssue(this,"JSON",dataset,config$2,{received:`"${error.message}"`});dataset.typed=false}else throw error}return dataset}}}function rawTransform(action){return{kind:"transformation",type:"raw_transform",reference:rawTransform,async:false,"~run"(dataset,config$1){const output=action({dataset,config:config$1,addIssue:(info)=>_addIssue(this,info?.label??"input",dataset,config$1,info),NEVER:null});if(dataset.issues)dataset.typed=false;else dataset.value=output;return dataset}}}function transform(operation){return{kind:"transformation",type:"transform",reference:transform,async:false,operation,"~run"(dataset){dataset.value=this.operation(dataset.value);return dataset}}}function trim(){return{kind:"transformation",type:"trim",reference:trim,async:false,"~run"(dataset){dataset.value=dataset.value.trim();return dataset}}}function getFallback(schema,dataset,config$1){return typeof schema.fallback==="function"?schema.fallback(dataset,config$1):schema.fallback}function getDefault(schema,dataset,config$1){return typeof schema.default==="function"?schema.default(dataset,config$1):schema.default}function array(item,message$1){return{kind:"schema",type:"array",reference:array,expects:"Array",async:false,item,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(Array.isArray(input)){dataset.typed=true;dataset.value=[];for(let key=0;key<input.length;key++){const value$1=input[key];const itemDataset=this.item["~run"]({value:value$1},config$1);if(itemDataset.issues){const pathItem={type:"array",origin:"value",input,key,value:value$1};for(const issue of itemDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=itemDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!itemDataset.typed)dataset.typed=false;dataset.value.push(itemDataset.value)}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function boolean(message$1){return{kind:"schema",type:"boolean",reference:boolean,expects:"boolean",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="boolean")dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function custom(check$1,message$1){return{kind:"schema",type:"custom",reference:custom,expects:"unknown",async:false,check:check$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(this.check(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function nullable(wrapped,default_){return{kind:"schema",type:"nullable",reference:nullable,expects:`(${wrapped.expects} | null)`,async:false,wrapped,default:default_,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(dataset.value===null){if(this.default!==undefined)dataset.value=getDefault(this,dataset,config$1);if(dataset.value===null){dataset.typed=true;return dataset}}return this.wrapped["~run"](dataset,config$1)}}}function number(message$1){return{kind:"schema",type:"number",reference:number,expects:"number",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="number"&&!isNaN(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function object(entries$1,message$1){return{kind:"schema",type:"object",reference:object,expects:"Object",async:false,entries:entries$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const key in this.entries){const valueSchema=this.entries[key];if(key in input||(valueSchema.type==="exact_optional"||valueSchema.type==="optional"||valueSchema.type==="nullish")&&valueSchema.default!==undefined){const value$1=key in input?input[key]:getDefault(valueSchema);const valueDataset=valueSchema["~run"]({value:value$1},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key,value:value$1};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!valueDataset.typed)dataset.typed=false;dataset.value[key]=valueDataset.value}else if(valueSchema.fallback!==undefined)dataset.value[key]=getFallback(valueSchema);else if(valueSchema.type!=="exact_optional"&&valueSchema.type!=="optional"&&valueSchema.type!=="nullish"){_addIssue(this,"key",dataset,config$1,{input:undefined,expected:`"${key}"`,path:[{type:"object",origin:"key",input,key,value:input[key]}]});if(config$1.abortEarly)break}}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function optional(wrapped,default_){return{kind:"schema",type:"optional",reference:optional,expects:`(${wrapped.expects} | undefined)`,async:false,wrapped,default:default_,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(dataset.value===undefined){if(this.default!==undefined)dataset.value=getDefault(this,dataset,config$1);if(dataset.value===undefined){dataset.typed=true;return dataset}}return this.wrapped["~run"](dataset,config$1)}}}function picklist(options,message$1){return{kind:"schema",type:"picklist",reference:picklist,expects:_joinExpects(options.map(_stringify),"|"),async:false,options,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(this.options.includes(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function record(key,value$1,message$1){return{kind:"schema",type:"record",reference:record,expects:"Object",async:false,key,value:value$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const entryKey in input)if(_isValidObjectKey(input,entryKey)){const entryValue=input[entryKey];const keyDataset=this.key["~run"]({value:entryKey},config$1);if(keyDataset.issues){const pathItem={type:"object",origin:"key",input,key:entryKey,value:entryValue};for(const issue of keyDataset.issues){issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=keyDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}const valueDataset=this.value["~run"]({value:entryValue},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key:entryKey,value:entryValue};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!keyDataset.typed||!valueDataset.typed)dataset.typed=false;if(keyDataset.typed)dataset.value[keyDataset.value]=valueDataset.value}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function strictObject(entries$1,message$1){return{kind:"schema",type:"strict_object",reference:strictObject,expects:"Object",async:false,entries:entries$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const key in this.entries){const valueSchema=this.entries[key];if(key in input||(valueSchema.type==="exact_optional"||valueSchema.type==="optional"||valueSchema.type==="nullish")&&valueSchema.default!==undefined){const value$1=key in input?input[key]:getDefault(valueSchema);const valueDataset=valueSchema["~run"]({value:value$1},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key,value:value$1};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!valueDataset.typed)dataset.typed=false;dataset.value[key]=valueDataset.value}else if(valueSchema.fallback!==undefined)dataset.value[key]=getFallback(valueSchema);else if(valueSchema.type!=="exact_optional"&&valueSchema.type!=="optional"&&valueSchema.type!=="nullish"){_addIssue(this,"key",dataset,config$1,{input:undefined,expected:`"${key}"`,path:[{type:"object",origin:"key",input,key,value:input[key]}]});if(config$1.abortEarly)break}}if(!dataset.issues||!config$1.abortEarly){for(const key in input)if(!(key in this.entries)){_addIssue(this,"key",dataset,config$1,{input:key,expected:"never",path:[{type:"object",origin:"key",input,key,value:input[key]}]});break}}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function string(message$1){return{kind:"schema",type:"string",reference:string,expects:"string",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="string")dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function _subIssues(datasets){let issues;if(datasets)for(const dataset of datasets)if(issues)for(const issue of dataset.issues)issues.push(issue);else issues=dataset.issues;return issues}function union(options,message$1){return{kind:"schema",type:"union",reference:union,expects:_joinExpects(options.map((option)=>option.expects),"|"),async:false,options,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){let validDataset;let typedDatasets;let untypedDatasets;for(const schema of this.options){const optionDataset=schema["~run"]({value:dataset.value},config$1);if(optionDataset.typed)if(optionDataset.issues)if(typedDatasets)typedDatasets.push(optionDataset);else typedDatasets=[optionDataset];else{validDataset=optionDataset;break}else if(untypedDatasets)untypedDatasets.push(optionDataset);else untypedDatasets=[optionDataset]}if(validDataset)return validDataset;if(typedDatasets){if(typedDatasets.length===1)return typedDatasets[0];_addIssue(this,"type",dataset,config$1,{issues:_subIssues(typedDatasets)});dataset.typed=true}else if(untypedDatasets?.length===1)return untypedDatasets[0];else _addIssue(this,"type",dataset,config$1,{issues:_subIssues(untypedDatasets)});return dataset}}}function unknown(){return{kind:"schema",type:"unknown",reference:unknown,expects:"unknown",async:false,get "~standard"(){return _getStandardProps(this)},"~run"(dataset){dataset.typed=true;return dataset}}}function parse(schema,input,config$1){const dataset=schema["~run"]({value:input},getGlobalConfig(config$1));if(dataset.issues)throw new ValiError(dataset.issues);return dataset.value}function partial(schema,keys){const entries$1={};for(const key in schema.entries)entries$1[key]=!keys||keys.includes(key)?optional(schema.entries[key]):schema.entries[key];return{...schema,entries:entries$1,get "~standard"(){return _getStandardProps(this)}}}function pipe(...pipe$1){return{...pipe$1[0],pipe:pipe$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){for(const item of pipe$1)if(item.kind!=="metadata"){if(dataset.issues&&(item.kind==="schema"||item.kind==="transformation")){dataset.typed=false;break}if(!dataset.issues||!config$1.abortEarly&&!config$1.abortPipeEarly)dataset=item["~run"](dataset,config$1)}return dataset}}}var ExtensionJsonSchema=custom(isExtensionJson,"Expected JSON-compatible value");var ExtensionSerializableValueSchema=custom(isExtensionSerializableValue,"Expected extension RPC-serializable value");var ExtensionOperationArgumentsSchema=array(ExtensionSerializableValueSchema);var OptionalExtensionJsonSchema=optional(nullable(ExtensionJsonSchema));var FiniteNumberSchema=pipe(number(),finite());var NonEmptyTrimmedStringSchema=pipe(string(),trim(),minLength(1));var StringFromScalarSchema=pipe(union([string(),FiniteNumberSchema,boolean()]),transform((value)=>String(value)));var NonEmptyStringFromScalarSchema=pipe(StringFromScalarSchema,trim(),minLength(1));var ExtensionJsonTransformSchema=pipe(unknown(),rawTransform((context)=>{try{return toExtensionJson(context.dataset.value)}catch(error){context.addIssue({message:error instanceof Error?error.message:"Expected JSON-compatible value"});return context.NEVER}}));var JsonTextSchema=pipe(string(),parseJson(),ExtensionJsonTransformSchema);var JsonRecordSchema=pipe(ExtensionJsonTransformSchema,rawTransform((context)=>{const value=context.dataset.value;if(!isPlainRecord(value)){context.addIssue({message:"Expected JSON object"});return context.NEVER}return value}));var JsonArraySchema=pipe(ExtensionJsonTransformSchema,rawTransform((context)=>{const value=context.dataset.value;if(!Array.isArray(value)){context.addIssue({message:"Expected JSON array"});return context.NEVER}return value}));var ExtensionReadQuerySchema=strictObject({joins:optional(ExtensionJsonSchema),limit:optional(FiniteNumberSchema),offset:optional(FiniteNumberSchema),order:optional(ExtensionJsonSchema),where:optional(ExtensionJsonSchema)});var ExtensionPermissionSchema=pipe(string(),minLength(1));var ExtensionConfigOptionSchema=object({label:pipe(string(),minLength(1)),value:pipe(string(),minLength(1))});var ExtensionConfigFieldSchema=object({defaultValue:optional(unknown()),description:optional(string()),key:pipe(string(),minLength(1)),label:pipe(string(),minLength(1)),options:optional(array(ExtensionConfigOptionSchema)),required:optional(boolean()),secret:optional(boolean()),type:picklist(["boolean","multi-select","number","select","string","url"])});var ExtensionLogoSchema=object({alt:optional(string()),src:pipe(string(),minLength(1))});var ExtensionHttpMethodSchema=picklist(["DELETE","GET","PATCH","POST","PUT"]);var ExtensionInvocationKindSchema=picklist(["callback","event","job","hook","workflow"]);var ExtensionCallbackSchema=object({action:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionEventHandlerSchema=object({event:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionJobOverlapPolicySchema=picklist(["ALLOW_ALL","BUFFER_ALL","BUFFER_ONE","CANCEL_OTHER","SKIP","TERMINATE_OTHER"]);var ExtensionJobSchema=object({name:pipe(string(),minLength(1)),overlap:optional(ExtensionJobOverlapPolicySchema),schedule:pipe(string(),minLength(1)),timezone:optional(string())});var ExtensionLifecycleHookSchema=object({event:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionTemporalWorkflowSchema=object({name:pipe(string(),minLength(1))});var ExtensionManifestSchema=object({config:optional(array(ExtensionConfigFieldSchema)),description:optional(string()),developerUrl:optional(pipe(string(),minLength(1))),displayName:optional(pipe(string(),minLength(1))),eventHandlers:optional(array(ExtensionEventHandlerSchema)),hooks:optional(array(ExtensionLifecycleHookSchema)),jobs:optional(array(ExtensionJobSchema)),logo:optional(ExtensionLogoSchema),name:pipe(string(),minLength(1)),permissions:optional(array(ExtensionPermissionSchema)),publisher:optional(pipe(string(),minLength(1))),callbacks:optional(array(ExtensionCallbackSchema)),version:pipe(string(),minLength(1)),workflows:optional(array(ExtensionTemporalWorkflowSchema))});var ExtensionCategoryCreateInputSchema=strictObject({metadata:OptionalExtensionJsonSchema,name:string(),parentCategoryId:optional(nullable(string())),slug:string(),status:optional(string())});var ExtensionCategoryUpdateInputSchema=partial(ExtensionCategoryCreateInputSchema);var ExtensionCategorySchema=object({id:string(),metadata:OptionalExtensionJsonSchema,name:optional(string()),parentCategoryId:optional(nullable(string())),slug:string(),status:optional(string())});var ExtensionProductImageSchema=object({rank:optional(nullable(FiniteNumberSchema)),url:string()});var ExtensionProductOptionInputSchema=strictObject({rank:optional(nullable(FiniteNumberSchema)),title:string()});var ExtensionProductOptionSchema=object({id:string(),productId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),title:string()});var ExtensionProductOptionValueInputSchema=strictObject({colorHex:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),value:string()});var ExtensionProductOptionValueSchema=object({colorHex:optional(nullable(string())),id:string(),optionId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),value:string()});var ExtensionProductVariantOptionValueSchema=object({id:string(),optionId:optional(string()),optionValueId:optional(string()),productId:optional(string()),variantId:optional(string())});var ExtensionProductAttributeInputSchema=strictObject({isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:string(),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"])))});var ExtensionProductAttributeSchema=object({id:string(),isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:string(),productId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"])))});var ExtensionProductAttributeValueInputSchema=strictObject({attributeId:string(),productId:optional(nullable(string())),valueBoolean:optional(nullable(boolean())),valueNumber:optional(nullable(union([FiniteNumberSchema,string()]))),valueText:optional(nullable(string())),variantId:optional(nullable(string()))});var ExtensionProductAttributeValueSchema=object({attributeId:optional(string()),id:string(),productId:optional(nullable(string())),valueBoolean:optional(nullable(boolean())),valueNumber:optional(nullable(union([FiniteNumberSchema,string()]))),valueText:optional(nullable(string())),variantId:optional(nullable(string()))});var ExtensionCatalogBatchImageSchema=strictObject({rank:optional(nullable(FiniteNumberSchema)),url:string()});var ExtensionCatalogBatchAttributeSchema=strictObject({isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"]))),value:union([boolean(),FiniteNumberSchema,string()])});var ExtensionCatalogBatchOptionSchema=strictObject({colorHex:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),title:optional(nullable(string())),value:string()});var ExtensionCatalogBatchPriceSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(nullable(FiniteNumberSchema)),costAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(nullable(string()))});var ExtensionCatalogBatchPriceListPriceSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(nullable(FiniteNumberSchema)),costAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(nullable(string())),key:string(),title:optional(nullable(string()))});var ExtensionCatalogBatchInventorySchema=strictObject({sku:optional(nullable(string())),stockLocationCode:string(),stockLocationName:optional(nullable(string())),stockedQuantity:FiniteNumberSchema,storeId:optional(nullable(string()))});var ExtensionCatalogBatchVariantSchema=strictObject({attributes:optional(array(ExtensionCatalogBatchAttributeSchema)),externalSku:string(),inventory:optional(array(ExtensionCatalogBatchInventorySchema)),isActive:optional(nullable(boolean())),manageInventory:optional(nullable(boolean())),metadata:optional(nullable(record(string(),ExtensionJsonSchema))),options:optional(record(string(),ExtensionCatalogBatchOptionSchema)),prices:optional(strictObject({base:optional(nullable(ExtensionCatalogBatchPriceSchema)),lists:optional(array(ExtensionCatalogBatchPriceListPriceSchema))})),title:optional(nullable(string()))});var ExtensionCatalogBatchProductSchema=strictObject({attributes:optional(array(ExtensionCatalogBatchAttributeSchema)),categoryId:optional(nullable(string())),description:optional(nullable(string())),images:optional(array(ExtensionCatalogBatchImageSchema)),metadata:optional(nullable(record(string(),ExtensionJsonSchema))),slug:string(),status:optional(nullable(string())),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string(),variants:array(ExtensionCatalogBatchVariantSchema)});var ExtensionCatalogBatchInputSchema=strictObject({products:array(ExtensionCatalogBatchProductSchema),source:string(),storeId:optional(nullable(string()))});var ExtensionCatalogBatchErrorSchema=strictObject({chunkIndex:nullable(FiniteNumberSchema),error:string(),index:FiniteNumberSchema,slug:string()});var ExtensionCatalogBatchResultSchema=strictObject({attributesUpserted:FiniteNumberSchema,chunksProcessed:FiniteNumberSchema,errors:array(ExtensionCatalogBatchErrorSchema),imagesAdded:FiniteNumberSchema,inventorySynced:FiniteNumberSchema,priceListPricesSet:FiniteNumberSchema,priceListsUpserted:FiniteNumberSchema,pricesSet:FiniteNumberSchema,productsCreated:FiniteNumberSchema,productsUpdated:FiniteNumberSchema,rowsProcessed:FiniteNumberSchema,variantOptionValuesLinked:FiniteNumberSchema,variantsCreated:FiniteNumberSchema,variantsUpdated:FiniteNumberSchema});var ExtensionProductCreateInputSchema=strictObject({categoryId:optional(nullable(string())),description:optional(nullable(string())),metadata:OptionalExtensionJsonSchema,slug:string(),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string()});var ExtensionProductUpdateInputSchema=strictObject({categoryId:optional(nullable(string())),description:optional(nullable(string())),id:string(),metadata:OptionalExtensionJsonSchema,slug:optional(string()),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:optional(string())});var ExtensionProductSchema=object({attributes:optional(nullable(array(ExtensionJsonSchema))),categoryId:optional(nullable(string())),description:optional(nullable(string())),id:string(),images:optional(array(ExtensionProductImageSchema)),metadata:OptionalExtensionJsonSchema,options:optional(nullable(array(ExtensionJsonSchema))),slug:string(),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string(),updatedAt:optional(string())});var ExtensionVariantCreateInputSchema=strictObject({externalSku:string(),isActive:optional(boolean()),manageInventory:optional(boolean()),metadata:OptionalExtensionJsonSchema,title:string()});var ExtensionVariantUpdateInputSchema=partial(ExtensionVariantCreateInputSchema);var ExtensionVariantSchema=object({attributeValues:optional(nullable(array(ExtensionJsonSchema))),externalSku:optional(nullable(string())),id:string(),inventoryItems:optional(nullable(array(ExtensionJsonSchema))),isActive:optional(nullable(boolean())),manageInventory:optional(nullable(boolean())),metadata:OptionalExtensionJsonSchema,optionValueLinks:optional(nullable(array(ExtensionJsonSchema))),priceListPrices:optional(nullable(array(ExtensionJsonSchema))),prices:optional(nullable(array(ExtensionJsonSchema))),productId:string(),title:optional(nullable(string())),updatedAt:optional(string())});var ExtensionFileContentSchema=custom((value)=>typeof value==="string"||value instanceof Uint8Array||value instanceof ArrayBuffer||value instanceof Blob,"Expected string, Uint8Array, ArrayBuffer, or Blob");var ExtensionFileCreateInputSchema=strictObject({access:optional(picklist(["private","public"])),content:ExtensionFileContentSchema,filename:string(),mimeType:string()});var ExtensionFileSchema=object({access:optional(picklist(["private","public"])),createdAt:optional(string()),filename:optional(string()),id:string(),mimeType:optional(nullable(string())),size:optional(nullable(FiniteNumberSchema)),updatedAt:optional(string()),url:optional(nullable(string()))});var ExtensionNotificationProviderDataSchema=strictObject({messageThreadId:optional(string()),parseMode:optional(picklist(["HTML","MarkdownV2"])),providerId:optional(string())});var ExtensionNotificationSendInputSchema=strictObject({channel:picklist(["telegram"]),content:strictObject({text:pipe(string(),minLength(1))}),data:optional(record(string(),ExtensionJsonSchema)),idempotencyKey:optional(string()),providerData:optional(ExtensionNotificationProviderDataSchema),to:pipe(string(),minLength(1))});var ExtensionNotificationSchema=object({channel:picklist(["telegram"]),createdAt:optional(string()),externalId:optional(string()),id:string(),idempotencyKey:optional(string()),providerData:optional(nullable(record(string(),ExtensionJsonSchema))),status:picklist(["failure","pending","success"]),to:string(),updatedAt:optional(string())});var ExtensionInventoryItemEnrollLevelInputSchema=strictObject({lastSyncedAt:optional(string()),metadata:OptionalExtensionJsonSchema,sourceSystem:optional(string()),stockLocationId:string(),stockedQuantity:FiniteNumberSchema});var ExtensionInventoryItemEnrollInputSchema=strictObject({inventoryLevels:optional(array(ExtensionInventoryItemEnrollLevelInputSchema)),isManaged:optional(boolean()),metadata:OptionalExtensionJsonSchema,sku:string(),storeId:string(),variantId:string()});var ExtensionInventoryItemSchema=object({code:optional(nullable(string())),id:string(),metadata:OptionalExtensionJsonSchema,sku:optional(nullable(string())),storeId:optional(string()),variantId:optional(string())});var ExtensionStockLocationCreateInputSchema=strictObject({code:string(),isEnabled:optional(boolean()),metadata:OptionalExtensionJsonSchema,name:string(),storeId:string(),type:optional(string())});var ExtensionStockLocationUpdateInputSchema=strictObject({code:optional(string()),id:string(),isEnabled:optional(boolean()),metadata:OptionalExtensionJsonSchema,name:optional(string()),storeId:optional(string()),type:optional(string())});var ExtensionStockLocationSchema=object({code:optional(nullable(string())),id:string(),isEnabled:optional(nullable(boolean())),metadata:OptionalExtensionJsonSchema,name:optional(string()),storeId:optional(string()),type:optional(string())});var ExtensionStockLevelSyncInputSchema=strictObject({inventoryItemId:string(),lastSyncedAt:optional(string()),metadata:OptionalExtensionJsonSchema,sourceSystem:optional(string()),stockLocationId:string(),stockedQuantity:FiniteNumberSchema});var ExtensionStockLevelSchema=object({id:optional(string()),inventoryItemId:optional(string()),stockLocationId:optional(string()),stockedQuantity:optional(FiniteNumberSchema)});var ExtensionPriceListCreateInputSchema=strictObject({automaticallyApplies:optional(boolean()),metadata:OptionalExtensionJsonSchema,priority:optional(FiniteNumberSchema),status:optional(string()),storeId:string(),title:string(),type:optional(string())});var ExtensionPriceListUpdateInputSchema=strictObject({automaticallyApplies:optional(boolean()),id:string(),metadata:OptionalExtensionJsonSchema,priority:optional(FiniteNumberSchema),status:optional(string()),title:optional(string()),type:optional(string())});var ExtensionPriceListSchema=object({automaticallyApplies:optional(nullable(boolean())),id:string(),metadata:OptionalExtensionJsonSchema,priority:optional(nullable(FiniteNumberSchema)),status:optional(string()),storeId:optional(string()),title:optional(string()),type:optional(string())});var ExtensionPriceListPriceCreateInputSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(FiniteNumberSchema),currencyCode:string(),metadata:OptionalExtensionJsonSchema,priceListId:string(),variantId:string()});var ExtensionPriceListPriceUpdateInputSchema=strictObject({amount:optional(FiniteNumberSchema),compareAtAmount:optional(FiniteNumberSchema),currencyCode:optional(string()),id:string(),metadata:OptionalExtensionJsonSchema,priceListId:optional(string()),variantId:optional(string())});var ExtensionPriceListPriceSchema=object({amount:optional(nullable(FiniteNumberSchema)),compareAtAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(string()),id:string(),metadata:OptionalExtensionJsonSchema,priceListId:optional(string()),variantId:optional(string())});var ExtensionBasePriceSetInputSchema=strictObject({amount:FiniteNumberSchema,atTime:optional(string()),compareAtAmount:optional(FiniteNumberSchema),costAmount:optional(FiniteNumberSchema),currencyCode:string(),taxIncluded:optional(boolean()),variantId:string()});var ExtensionPriceSchema=object({amount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(string()),id:string(),variantId:optional(string())});function parseJsonText(input){return parse(JsonTextSchema,input)}function toExtensionJson(value,seen=new WeakSet,depth=0){if(value===null||typeof value==="boolean"||typeof value==="string"){return value}if(typeof value==="number"){return Number.isFinite(value)?value:null}if(typeof value==="bigint"){return value.toString()}if(value===undefined||typeof value==="function"||typeof value==="symbol"){return null}if(value instanceof Date){return Number.isFinite(value.getTime())?value.toISOString():null}if(value instanceof Uint8Array){return Array.from(value)}if(value instanceof ArrayBuffer){return Array.from(new Uint8Array(value))}if(typeof value==="object"){if(seen.has(value)){return null}seen.add(value);if(depth>50){return"[Truncated]"}if(Array.isArray(value)){return value.map((entry)=>toExtensionJson(entry,seen,depth+1))}const output={};for(const[key,entry]of Object.entries(value)){if(entry!==undefined&&typeof entry!=="function"&&typeof entry!=="symbol"){output[key]=toExtensionJson(entry,seen,depth+1)}}return output}return null}function isExtensionJson(value){if(value===null){return true}switch(typeof value){case"boolean":case"string":return true;case"number":return Number.isFinite(value);case"object":if(Array.isArray(value)){return value.every(isExtensionJson)}if(!isPlainRecord(value)){return false}return Object.values(value).every(isExtensionJson);default:return false}}function isPlainRecord(value){if(!value||typeof value!=="object"||Array.isArray(value)){return false}const prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function isExtensionSerializableValue(value,seen=new Set){if(value===undefined||value===null){return true}switch(typeof value){case"boolean":case"string":return true;case"number":return Number.isFinite(value);case"object":{if(value instanceof Date){return Number.isFinite(value.getTime())}if(value instanceof Uint8Array||value instanceof ArrayBuffer){return true}if(seen.has(value)){return false}seen.add(value);if(Array.isArray(value)){return value.every((entry)=>isExtensionSerializableValue(entry,seen))}const prototype=Object.getPrototypeOf(value);if(prototype!==Object.prototype&&prototype!==null){return false}return Object.values(value).every((entry)=>isExtensionSerializableValue(entry,seen))}default:return false}}var AI_BOT_EXTENSION_NAME="ai-bot";var AI_BOT_VERSION="0.0.10-alpha.15";var DEFAULT_MODEL="gpt-4.1-mini";var DEFAULT_OPENAI_BASE_URL="https://api.openai.com/v1";var DEFAULT_ANTHROPIC_BASE_URL="https://api.anthropic.com/v1";var DEFAULT_MAX_COMMANDS=8;var RUN_HISTORY_PREFIX="ai-bot.runs.";var LAST_RUN_KEY="ai-bot.last-run";var MAX_EFFECT_RESULT_CHARS=8000;var MAX_MODEL_CONTEXT_CHARS=12000;var COMMANDS=[{command:"product.list",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u0441 \u043D\u0435\u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u043C \u0437\u0430\u043F\u0440\u043E\u0441\u043E\u043C \u0447\u0442\u0435\u043D\u0438\u044F.",mutates:false},{command:"product.retrieve",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043E\u0434\u0438\u043D \u0442\u043E\u0432\u0430\u0440 \u043F\u043E id.",mutates:false},{command:"product.retrieveVariantByExternalSku",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0432\u0430\u0440\u0438\u0430\u043D\u0442 \u043F\u043E \u0432\u043D\u0435\u0448\u043D\u0435\u043C\u0443 SKU.",mutates:false},{command:"product.listVariants",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043E\u0432 \u0434\u043B\u044F id \u0442\u043E\u0432\u0430\u0440\u0430.",mutates:false},{command:"product.listCategories",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0439 \u0442\u043E\u0432\u0430\u0440\u043E\u0432.",mutates:false},{command:"price.listPriceList",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u043F\u0440\u0430\u0439\u0441-\u043B\u0438\u0441\u0442\u043E\u0432.",mutates:false},{command:"price.listPriceListPrice",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u0446\u0435\u043D \u043F\u0440\u0430\u0439\u0441-\u043B\u0438\u0441\u0442\u043E\u0432.",mutates:false},{command:"stockLocation.listStockLocation",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u0441\u043A\u043B\u0430\u0434\u043E\u0432.",mutates:false},{command:"stockLocation.retrieveStockLocation",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043E\u0434\u0438\u043D \u0441\u043A\u043B\u0430\u0434 \u043F\u043E id.",mutates:false},{command:"notification.listNotifications",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0439.",mutates:false},{command:"notification.retrieveNotification",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043E\u0434\u043D\u043E \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0435 \u043F\u043E id.",mutates:false},{command:"file.list",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u0444\u0430\u0439\u043B\u043E\u0432.",mutates:false},{command:"file.retrieve",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043C\u0435\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0435 \u0444\u0430\u0439\u043B\u0430 \u043F\u043E id.",mutates:false},{command:"storage.db.get",description:"\u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C \u043E\u0434\u043D\u0443 \u0437\u0430\u043F\u0438\u0441\u044C \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u043F\u043E \u043A\u043B\u044E\u0447\u0443.",mutates:false},{command:"storage.db.list",description:"\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u0437\u0430\u043F\u0438\u0441\u0435\u0439 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.",mutates:false},{command:"storage.cache.get",description:"\u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C \u043E\u0434\u043D\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043A\u0435\u0448\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u043F\u043E \u043A\u043B\u044E\u0447\u0443.",mutates:false},{command:"product.create",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0434\u0438\u043D \u0438\u043B\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0442\u043E\u0432\u0430\u0440\u043E\u0432.",mutates:true},{command:"product.update",description:"\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u043E\u0434\u0438\u043D \u0438\u043B\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0442\u043E\u0432\u0430\u0440\u043E\u0432.",mutates:true},{command:"product.createCategory",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044E \u0442\u043E\u0432\u0430\u0440\u043E\u0432.",mutates:true},{command:"product.updateCategory",description:"\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044E \u0442\u043E\u0432\u0430\u0440\u043E\u0432.",mutates:true},{command:"product.createVariant",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0432\u0430\u0440\u0438\u0430\u043D\u0442 \u0442\u043E\u0432\u0430\u0440\u0430.",mutates:true},{command:"product.updateVariant",description:"\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0432\u0430\u0440\u0438\u0430\u043D\u0442 \u0442\u043E\u0432\u0430\u0440\u0430.",mutates:true},{command:"product.addImage",description:"\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C URL \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u043A \u0442\u043E\u0432\u0430\u0440\u0443.",mutates:true},{command:"product.upsertOption",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u043B\u0438 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u043E\u043F\u0446\u0438\u044E \u0442\u043E\u0432\u0430\u0440\u0430.",mutates:true},{command:"product.upsertOptionValue",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u043B\u0438 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043E\u043F\u0446\u0438\u0438 \u0442\u043E\u0432\u0430\u0440\u0430.",mutates:true},{command:"product.linkVariantOptionValue",description:"\u0421\u0432\u044F\u0437\u0430\u0442\u044C \u0432\u0430\u0440\u0438\u0430\u043D\u0442 \u0441\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u043C \u043E\u043F\u0446\u0438\u0438.",mutates:true},{command:"product.upsertAttribute",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u043B\u0438 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0442\u043E\u0432\u0430\u0440\u0430.",mutates:true},{command:"product.upsertAttributeValue",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u043B\u0438 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u0442\u043E\u0432\u0430\u0440\u0430.",mutates:true},{command:"price.createPriceList",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0434\u0438\u043D \u0438\u043B\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u0430\u0439\u0441-\u043B\u0438\u0441\u0442\u043E\u0432.",mutates:true},{command:"price.updatePriceList",description:"\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u043E\u0434\u0438\u043D \u0438\u043B\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u0430\u0439\u0441-\u043B\u0438\u0441\u0442\u043E\u0432.",mutates:true},{command:"price.createPriceListPrice",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0434\u043D\u0443 \u0438\u043B\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0446\u0435\u043D \u043F\u0440\u0430\u0439\u0441-\u043B\u0438\u0441\u0442\u0430.",mutates:true},{command:"price.updatePriceListPrice",description:"\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u043E\u0434\u043D\u0443 \u0438\u043B\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0446\u0435\u043D \u043F\u0440\u0430\u0439\u0441-\u043B\u0438\u0441\u0442\u0430.",mutates:true},{command:"price.setBasePrice",description:"\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0431\u0430\u0437\u043E\u0432\u0443\u044E \u0446\u0435\u043D\u0443 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430.",mutates:true},{command:"stockLocation.createStockLocation",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0441\u043A\u043B\u0430\u0434.",mutates:true},{command:"stockLocation.updateStockLocation",description:"\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0441\u043A\u043B\u0430\u0434.",mutates:true},{command:"stockLocation.upsertStockLocation",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u043B\u0438 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0441\u043A\u043B\u0430\u0434.",mutates:true},{command:"inventory.enrollVariantInStore",description:"\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432\u0430\u0440\u0438\u0430\u043D\u0442 \u0432 \u043E\u0441\u0442\u0430\u0442\u043A\u0430\u0445 \u043C\u0430\u0433\u0430\u0437\u0438\u043D\u0430.",mutates:true},{command:"inventory.syncStockLevel",description:"\u0421\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043E\u0441\u0442\u0430\u0442\u043E\u043A.",mutates:true},{command:"notification.createNotifications",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0434\u043D\u043E \u0438\u043B\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0439.",mutates:true},{command:"file.create",description:"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0444\u0430\u0439\u043B \u0438\u0437 \u0441\u0442\u0440\u043E\u043A\u043E\u0432\u043E\u0433\u043E \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043E.",mutates:true},{command:"file.delete",description:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043E\u0434\u0438\u043D \u0438\u043B\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0444\u0430\u0439\u043B\u043E\u0432 \u043F\u043E id.",mutates:true},{command:"storage.db.set",description:"\u0417\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u0437\u0430\u043F\u0438\u0441\u044C \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.",mutates:true},{command:"storage.db.delete",description:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0437\u0430\u043F\u0438\u0441\u0438 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.",mutates:true},{command:"storage.cache.set",description:"\u0417\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043A\u0435\u0448\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.",mutates:true},{command:"storage.cache.delete",description:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u043A\u0435\u0448\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.",mutates:true}];var COMMAND_BY_NAME=new Map(COMMANDS.map((command)=>[command.command,command]));var COMMAND_CATALOG_TEXT=COMMANDS.map((entry)=>`- ${entry.command} (${entry.mutates?"\u043C\u0443\u0442\u0430\u0446\u0438\u044F":"\u0447\u0442\u0435\u043D\u0438\u0435"}): ${entry.description}`).join(`
|
|
3
|
+
`);var AI_BOT_PERMISSIONS=["extension-storage:read","extension-storage:write","network:https://*/*","operation:file.create","operation:file.delete","operation:file.list","operation:file.retrieve","operation:inventory.enrollVariantInStore","operation:inventory.syncStockLevel","operation:notification.createNotifications","operation:notification.listNotifications","operation:notification.retrieveNotification","operation:price.createPriceList","operation:price.createPriceListPrice","operation:price.listPriceList","operation:price.listPriceListPrice","operation:price.setBasePrice","operation:price.updatePriceList","operation:price.updatePriceListPrice","operation:product.addImage","operation:product.create","operation:product.createCategory","operation:product.createVariant","operation:product.linkVariantOptionValue","operation:product.list","operation:product.listCategories","operation:product.listVariants","operation:product.retrieve","operation:product.retrieveVariantByExternalSku","operation:product.update","operation:product.updateCategory","operation:product.updateVariant","operation:product.upsertAttribute","operation:product.upsertAttributeValue","operation:product.upsertOption","operation:product.upsertOptionValue","operation:stockLocation.createStockLocation","operation:stockLocation.listStockLocation","operation:stockLocation.retrieveStockLocation","operation:stockLocation.updateStockLocation","operation:stockLocation.upsertStockLocation"];var DEFAULT_SYSTEM_PROMPT=["\u0412\u044B - \u0438\u0441\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C Brand Map AI Bot.","\u0412\u044B \u0440\u0435\u0448\u0430\u0435\u0442\u0435, \u043A\u0430\u043A\u0438\u0435 \u0438\u043C\u0435\u043D\u043D\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u043D\u0443\u0436\u043D\u043E \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0434\u043B\u044F \u0437\u0430\u0434\u0430\u0447\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F.","\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0439\u0442\u0435 \u0442\u043E\u043B\u044C\u043A\u043E JSON. \u041D\u0435 \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0439\u0442\u0435 shell-\u043A\u043E\u043C\u0430\u043D\u0434\u044B. \u041D\u0435 \u043F\u0440\u0438\u0434\u0443\u043C\u044B\u0432\u0430\u0439\u0442\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u044B.","\u041A\u0430\u0436\u0434\u0430\u044F \u043A\u043E\u043C\u0430\u043D\u0434\u0430 \u0434\u043E\u043B\u0436\u043D\u0430 \u0438\u043C\u0435\u0442\u044C \u0442\u0430\u043A\u043E\u0439 \u0444\u043E\u0440\u043C\u0430\u0442:",'{"commands":[{"id":"short-id","command":"product.list","args":[{"limit":5}],"reason":"\u0437\u0430\u0447\u0435\u043C \u044D\u0442\u043E \u043D\u0443\u0436\u043D\u043E"}]}',"\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043F\u0443\u0441\u0442\u043E\u0439 \u043C\u0430\u0441\u0441\u0438\u0432 commands, \u0435\u0441\u043B\u0438 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043D\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F.","\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u044B:",COMMAND_CATALOG_TEXT].join(`
|
|
4
4
|
|
|
5
|
-
`);var BRAND_MAP_DEVELOPER_URL="https://brand-map.ru";var EXTENSION_LOGO={alt:"AI Bot icon",src:"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5NiA5NiI+PHJlY3Qgd2lkdGg9Ijk2IiBoZWlnaHQ9Ijk2IiByeD0iMjAiIGZpbGw9IiMxMjE4MjYiLz48cGF0aCBkPSJNMjQgNDBjMC05Ljk0IDguMDYtMTggMTgtMThoMTJjOS45NCAwIDE4IDguMDYgMTggMTh2MThjMCA2LjYzLTUuMzcgMTItMTIgMTJIMzZjLTYuNjMgMC0xMi01LjM3LTEyLTEyVjQwWiIgZmlsbD0iIzJERDRCRiIvPjxwYXRoIGQ9Ik0zMiA0MmMwLTUuNTIgNC40OC0xMCAxMC0xMGgxMmM1LjUyIDAgMTAgNC40OCAxMCAxMHYxMmMwIDQuNDItMy41OCA4LTggOEg0MGMtNC40MiAwLTgtMy41OC04LThWNDJaIiBmaWxsPSIjRjhGQUZDIi8+PGNpcmNsZSBjeD0iNDIiIGN5PSI0OCIgcj0iNCIgZmlsbD0iIzEyMTgyNiIvPjxjaXJjbGUgY3g9IjU0IiBjeT0iNDgiIHI9IjQiIGZpbGw9IiMxMjE4MjYiLz48cGF0aCBkPSJNNDIgNjBoMTIiIHN0cm9rZT0iIzEyMTgyNiIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48cGF0aCBkPSJNNDggMTh2LTZNMjcgMjVsLTQtNE02OSAyNWw0LTRNMjYgNzZsLTUgNU03MCA3Nmw1IDUiIHN0cm9rZT0iI0E3OEJGQSIgc3Ryb2tlLXdpZHRoPSI1IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4="};function createAiBotExtension(options={}){const settings=readSettings(options);return extension({config:[{defaultValue:"openai",key:"aiProvider",label:"AI Provider",options:[{label:"OpenAI",value:"openai"},{label:"OpenAI Compatible",value:"openai-compatible"},{label:"Anthropic",value:"anthropic"}],type:"select"},{key:"apiToken",label:"AI Provider API Token",required:true,secret:true,type:"string"},{defaultValue:DEFAULT_OPENAI_BASE_URL,key:"apiBaseUrl",label:"AI API Base URL",type:"url"},{defaultValue:DEFAULT_MODEL,key:"model",label:"Model",type:"string"},{defaultValue:DEFAULT_MAX_COMMANDS,key:"maxCommands",label:"Max Commands",type:"number"},{defaultValue:false,description:"Allows the harness to execute write commands when workflow input also allows it.",key:"allowMutations",label:"Allow Mutations",type:"boolean"},{defaultValue:false,description:"Runs read commands but skips write commands.",key:"dryRun",label:"Dry Run",type:"boolean"},{defaultValue:DEFAULT_SYSTEM_PROMPT,key:"systemPrompt",label:"System Prompt",type:"string"}],description:"Runs a small AI harness as a Temporal workflow over approved Brand Map extension commands.",displayName:"AI Bot",developerUrl:BRAND_MAP_DEVELOPER_URL,logo:EXTENSION_LOGO,name:AI_BOT_EXTENSION_NAME,publisher:"Brand Map",permissions:AI_BOT_PERMISSIONS,callbacks:[callback("health",()=>({ok:true,service:AI_BOT_EXTENSION_NAME,workflow:"run-harness"})),callback("last-run",async({storage})=>{const record2=await storage.db.get(LAST_RUN_KEY);return{run:record2?.value??null}})],version:AI_BOT_VERSION,workflows:[temporalWorkflow("run-harness",async({brandMap,invocation,log,storage})=>{const input=readHarnessInput(invocation.input,settings);const startedAt=new Date().toISOString();const runId=`ai_bot_${invocation.invocationId}`;log.info("AI Bot Temporal workflow started",{allowMutations:input.allowMutations,dryRun:input.dryRun,invocationId:invocation.invocationId,runId});const result=await runHarness({brandMap,input,log,runId,settings,startedAt,storage}).catch(async(error)=>{const message=error instanceof Error?error.message:String(error);const failed={allowMutations:input.allowMutations,commands:[],dryRun:input.dryRun,effects:[],finishedAt:new Date().toISOString(),model:settings.model,planText:"",provider:settings.aiProvider,runId,startedAt,status:"failed",summary:{message,status:"failed"},task:input.task};await persistRun(storage,failed);return failed});log.info("AI Bot Temporal workflow completed",{commandCount:result.commands.length,effectCount:result.effects.length,invocationId:invocation.invocationId,runId,status:result.status});return result})]})}async function runHarness(input){if(!input.settings.apiToken){throw new Error("AI Bot requires apiToken in extension config.")}const planText=await callAiModel(input.settings,[{content:buildPlanningPrompt(input.input),role:"user"}]);const plannedCommands=normalizePlan(parseJsonObject(planText),input.input.maxCommands);const effects=[];for(const plannedCommand of plannedCommands){effects.push(await executePlannedCommand({brandMap:input.brandMap,command:plannedCommand,input:input.input,storage:input.storage}))}const summary=await createFinalSummary({effects,planText,settings:input.settings,task:input.input.task});const result={allowMutations:input.input.allowMutations,commands:plannedCommands,dryRun:input.input.dryRun,effects,finishedAt:new Date().toISOString(),model:input.settings.model,planText,provider:input.settings.aiProvider,runId:input.runId,startedAt:input.startedAt,status:effects.some((effect)=>effect.status==="error")?"failed":"completed",summary,task:input.input.task};await persistRun(input.storage,result);return result}async function createFinalSummary(input){const status=input.effects.some((effect)=>effect.status==="error")?"completed-with-errors":"completed";try{const summaryText=await callAiModel(input.settings,[{content:buildSummaryPrompt({effects:input.effects,planText:input.planText,task:input.task}),role:"user"}]);return toExtensionJson2(parseJsonObject(summaryText,{message:summaryText,status}))}catch(error){return{errors:[error instanceof Error?error.message:String(error)],status:"summary-failed",summary:"Commands ran, but the final AI summary request failed."}}}async function executePlannedCommand(input){const startedAt=new Date().toISOString();const definition=COMMAND_BY_NAME.get(input.command.command);const base={args:input.command.args,command:input.command.command,finishedAt:startedAt,id:input.command.id,reason:input.command.reason,startedAt};if(!definition){return{...base,skippedReason:"Unsupported command.",status:"skipped"}}if(input.input.allowedCommands&&!input.input.allowedCommands.has(input.command.command)){return{...base,skippedReason:"Command was not listed in workflow input allowedCommands.",status:"skipped"}}if(definition.mutates&&input.input.dryRun){return{...base,skippedReason:"Dry run is enabled.",status:"skipped"}}if(definition.mutates&&!input.input.allowMutations){return{...base,skippedReason:"Mutation commands are disabled.",status:"skipped"}}try{const result=await dispatchCommand(input.brandMap,input.storage,input.command);return{...base,finishedAt:new Date().toISOString(),result:compactResult(result),status:"ok"}}catch(error){return{...base,error:error instanceof Error?error.message:String(error),finishedAt:new Date().toISOString(),status:"error"}}}async function dispatchCommand(brandMap,storage,command){const args=command.args;switch(command.command){case"product.list":return await brandMap.product.list(args[0]);case"product.retrieve":return await brandMap.product.retrieve(readStringArg(args,0),args[1]);case"product.retrieveVariantByExternalSku":return await brandMap.product.retrieveVariantByExternalSku(readStringArg(args,0));case"product.listVariants":return await brandMap.product.listVariants(readStringArg(args,0));case"product.listCategories":return await brandMap.product.listCategories(args[0]);case"product.create":return await brandMap.product.create(args[0]);case"product.update":return await brandMap.product.update(args[0]);case"product.createCategory":return await brandMap.product.createCategory(args[0]);case"product.updateCategory":return await brandMap.product.updateCategory(readStringArg(args,0),args[1]);case"product.createVariant":return await brandMap.product.createVariant(readStringArg(args,0),args[1]);case"product.updateVariant":return await brandMap.product.updateVariant(readStringArg(args,0),args[1]);case"product.addImage":return await brandMap.product.addImage(readStringArg(args,0),readStringArg(args,1),readOptionalNumberArg(args,2));case"product.upsertOption":return await brandMap.product.upsertOption(readStringArg(args,0),args[1]);case"product.upsertOptionValue":return await brandMap.product.upsertOptionValue(readStringArg(args,0),args[1]);case"product.linkVariantOptionValue":return await brandMap.product.linkVariantOptionValue(readStringArg(args,0),readStringArg(args,1));case"product.upsertAttribute":return await brandMap.product.upsertAttribute(readStringArg(args,0),args[1]);case"product.upsertAttributeValue":return await brandMap.product.upsertAttributeValue(args[0]);case"price.listPriceList":return await brandMap.price.listPriceList(args[0]);case"price.listPriceListPrice":return await brandMap.price.listPriceListPrice(args[0]);case"price.createPriceList":return await brandMap.price.createPriceList(args[0]);case"price.updatePriceList":return await brandMap.price.updatePriceList(args[0]);case"price.createPriceListPrice":return await brandMap.price.createPriceListPrice(args[0]);case"price.updatePriceListPrice":return await brandMap.price.updatePriceListPrice(args[0]);case"price.setBasePrice":return await brandMap.price.setBasePrice(args[0]);case"stockLocation.listStockLocation":return await brandMap.stockLocation.listStockLocation(args[0]);case"stockLocation.retrieveStockLocation":return await brandMap.stockLocation.retrieveStockLocation(readStringArg(args,0),args[1]);case"stockLocation.createStockLocation":return await brandMap.stockLocation.createStockLocation(args[0]);case"stockLocation.updateStockLocation":return await brandMap.stockLocation.updateStockLocation(args[0]);case"stockLocation.upsertStockLocation":return await brandMap.stockLocation.upsertStockLocation(args[0]);case"inventory.enrollVariantInStore":return await brandMap.inventory.enrollVariantInStore(args[0]);case"inventory.syncStockLevel":return await brandMap.inventory.syncStockLevel(args[0]);case"notification.createNotifications":return await brandMap.notification.createNotifications(args[0]);case"notification.listNotifications":return await brandMap.notification.listNotifications(args[0]);case"notification.retrieveNotification":return await brandMap.notification.retrieveNotification(readStringArg(args,0),args[1]);case"file.create":return await brandMap.file.create(args[0]);case"file.delete":return await brandMap.file.delete(args[0]);case"file.list":return await brandMap.file.list(args[0]);case"file.retrieve":return await brandMap.file.retrieve(readStringArg(args,0),args[1]);case"storage.db.get":return await storage.db.get(readStringArg(args,0));case"storage.db.list":return await storage.db.list(args[0]);case"storage.db.set":return await storage.db.set(args[0]);case"storage.db.delete":return await storage.db.delete(args[0]);case"storage.cache.get":return await storage.cache.get(readStringArg(args,0));case"storage.cache.set":return await storage.cache.set(args[0]);case"storage.cache.delete":return await storage.cache.delete(args[0]);default:throw new Error(`Unsupported command "${command.command}"`)}}async function callAiModel(settings,messages){assertAiBaseUrl(settings.apiBaseUrl);if(settings.aiProvider==="anthropic"){return await callAnthropic(settings,messages)}return await callOpenAiCompatible(settings,messages)}async function callOpenAiCompatible(settings,messages){const response=await settings.fetchImplementation(`${settings.apiBaseUrl}/chat/completions`,{body:JSON.stringify({messages:[{content:settings.systemPrompt,role:"system"},...messages],model:settings.model,response_format:{type:"json_object"},temperature:0.1}),headers:{authorization:`Bearer ${settings.apiToken}`,"content-type":"application/json"},method:"POST"});const payload=await readAiResponse(response);const content=readPath(payload,["choices",0,"message","content"]);if(typeof content!=="string"){throw new Error("AI provider response did not include choices[0].message.content.")}return content}async function callAnthropic(settings,messages){const response=await settings.fetchImplementation(`${settings.apiBaseUrl}/messages`,{body:JSON.stringify({max_tokens:2000,messages,model:settings.model,system:settings.systemPrompt,temperature:0.1}),headers:{"anthropic-version":"2023-06-01","content-type":"application/json","x-api-key":settings.apiToken??""},method:"POST"});const payload=await readAiResponse(response);const blocks=readPath(payload,["content"]);if(!Array.isArray(blocks)){throw new Error("AI provider response did not include content blocks.")}return blocks.map((block)=>isRecord(block)&&typeof block.text==="string"?block.text:"").join(`
|
|
6
|
-
`).trim()}async function readAiResponse(response){const text=await response.text();const payload=parseJsonObject(text,{message:text});if(!response.ok){const message=readAiErrorMessage(payload)??`AI provider request failed with status ${response.status}.`;throw new Error(message)}return payload}function buildPlanningPrompt(input){return truncateText(JSON.stringify({context:input.context,instructions:["Pick the minimum command sequence needed.","Use read commands before mutation commands when identifiers are unknown.","Mutation commands are only useful when allowMutations is true and dryRun is false.","Return only JSON with a commands array."],runtime:{allowMutations:input.allowMutations,allowedCommands:input.allowedCommands?Array.from(input.allowedCommands):null,dryRun:input.dryRun,maxCommands:input.maxCommands},task:input.task},null,2),MAX_MODEL_CONTEXT_CHARS)}function buildSummaryPrompt(input){return truncateText(JSON.stringify({effects:input.effects,instructions:["Summarize what happened for the user.","Mention commands that were skipped or failed.","Return only JSON with keys summary, status, actions, skipped, errors, nextSteps."],planText:input.planText,task:input.task},null,2),MAX_MODEL_CONTEXT_CHARS)}function normalizePlan(input,maxCommands){if(!isRecord(input)||!Array.isArray(input.commands)){throw new Error("AI
|
|
5
|
+
`);var BRAND_MAP_DEVELOPER_URL="https://brand-map.ru";var EXTENSION_LOGO={alt:"\u0418\u043A\u043E\u043D\u043A\u0430 AI-\u0431\u043E\u0442\u0430",src:"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5NiA5NiI+PHJlY3Qgd2lkdGg9Ijk2IiBoZWlnaHQ9Ijk2IiByeD0iMjAiIGZpbGw9IiMxMjE4MjYiLz48cGF0aCBkPSJNMjQgNDBjMC05Ljk0IDguMDYtMTggMTgtMThoMTJjOS45NCAwIDE4IDguMDYgMTggMTh2MThjMCA2LjYzLTUuMzcgMTItMTIgMTJIMzZjLTYuNjMgMC0xMi01LjM3LTEyLTEyVjQwWiIgZmlsbD0iIzJERDRCRiIvPjxwYXRoIGQ9Ik0zMiA0MmMwLTUuNTIgNC40OC0xMCAxMC0xMGgxMmM1LjUyIDAgMTAgNC40OCAxMCAxMHYxMmMwIDQuNDItMy41OCA4LTggOEg0MGMtNC40MiAwLTgtMy41OC04LThWNDJaIiBmaWxsPSIjRjhGQUZDIi8+PGNpcmNsZSBjeD0iNDIiIGN5PSI0OCIgcj0iNCIgZmlsbD0iIzEyMTgyNiIvPjxjaXJjbGUgY3g9IjU0IiBjeT0iNDgiIHI9IjQiIGZpbGw9IiMxMjE4MjYiLz48cGF0aCBkPSJNNDIgNjBoMTIiIHN0cm9rZT0iIzEyMTgyNiIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48cGF0aCBkPSJNNDggMTh2LTZNMjcgMjVsLTQtNE02OSAyNWw0LTRNMjYgNzZsLTUgNU03MCA3Nmw1IDUiIHN0cm9rZT0iI0E3OEJGQSIgc3Ryb2tlLXdpZHRoPSI1IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4="};function createAiBotExtension(options={}){const settings=readSettings(options);return extension({config:[{defaultValue:"openai",key:"aiProvider",label:"AI-\u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440",options:[{label:"OpenAI",value:"openai"},{label:"OpenAI-\u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u044B\u0439",value:"openai-compatible"},{label:"Anthropic",value:"anthropic"}],type:"select"},{key:"apiToken",label:"API-\u0442\u043E\u043A\u0435\u043D AI-\u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u0430",required:true,secret:true,type:"string"},{defaultValue:DEFAULT_OPENAI_BASE_URL,key:"apiBaseUrl",label:"\u0411\u0430\u0437\u043E\u0432\u044B\u0439 URL API AI",type:"url"},{defaultValue:DEFAULT_MODEL,key:"model",label:"\u041C\u043E\u0434\u0435\u043B\u044C",type:"string"},{defaultValue:DEFAULT_MAX_COMMANDS,key:"maxCommands",label:"\u041C\u0430\u043A\u0441\u0438\u043C\u0443\u043C \u043A\u043E\u043C\u0430\u043D\u0434",type:"number"},{defaultValue:false,description:"\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044E \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u0442\u044C \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u0437\u0430\u043F\u0438\u0441\u0438, \u0435\u0441\u043B\u0438 \u0432\u0445\u043E\u0434\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 \u0442\u043E\u0436\u0435 \u044D\u0442\u043E \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044E\u0442.",key:"allowMutations",label:"\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044C \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F",type:"boolean"},{defaultValue:false,description:"\u0412\u044B\u043F\u043E\u043B\u043D\u044F\u0435\u0442 \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u0447\u0442\u0435\u043D\u0438\u044F, \u043D\u043E \u043F\u0440\u043E\u043F\u0443\u0441\u043A\u0430\u0435\u0442 \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u0437\u0430\u043F\u0438\u0441\u0438.",key:"dryRun",label:"\u041F\u0440\u043E\u0431\u043D\u044B\u0439 \u0437\u0430\u043F\u0443\u0441\u043A",type:"boolean"},{defaultValue:DEFAULT_SYSTEM_PROMPT,key:"systemPrompt",label:"\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439 \u043F\u0440\u043E\u043C\u043F\u0442",type:"string"}],description:"\u0417\u0430\u043F\u0443\u0441\u043A\u0430\u0435\u0442 \u043D\u0435\u0431\u043E\u043B\u044C\u0448\u043E\u0439 AI-\u0438\u0441\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C \u043A\u0430\u043A Temporal-\u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u043F\u043E\u0432\u0435\u0440\u0445 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u043D\u044B\u0445 \u043A\u043E\u043C\u0430\u043D\u0434 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F Brand Map.",displayName:"AI-\u0431\u043E\u0442",developerUrl:BRAND_MAP_DEVELOPER_URL,logo:EXTENSION_LOGO,name:AI_BOT_EXTENSION_NAME,publisher:"Brand Map",permissions:AI_BOT_PERMISSIONS,callbacks:[callback("health",()=>({ok:true,service:AI_BOT_EXTENSION_NAME,workflow:"run-harness"})),callback("last-run",async({storage})=>{const record2=await storage.db.get(LAST_RUN_KEY);return{run:record2?.value??null}})],version:AI_BOT_VERSION,workflows:[temporalWorkflow("run-harness",async({brandMap,invocation,log,storage})=>{const input=readHarnessInput(invocation.input,settings);const startedAt=new Date().toISOString();const runId=`ai_bot_${invocation.invocationId}`;log.info("Temporal-\u043F\u0440\u043E\u0446\u0435\u0441\u0441 AI-\u0431\u043E\u0442\u0430 \u043D\u0430\u0447\u0430\u043B\u0441\u044F",{allowMutations:input.allowMutations,dryRun:input.dryRun,invocationId:invocation.invocationId,runId});const result=await runHarness({brandMap,input,log,runId,settings,startedAt,storage}).catch(async(error)=>{const message=error instanceof Error?error.message:String(error);const failed={allowMutations:input.allowMutations,commands:[],dryRun:input.dryRun,effects:[],finishedAt:new Date().toISOString(),model:settings.model,planText:"",provider:settings.aiProvider,runId,startedAt,status:"failed",summary:{message,status:"failed"},task:input.task};await persistRun(storage,failed);return failed});log.info("Temporal-\u043F\u0440\u043E\u0446\u0435\u0441\u0441 AI-\u0431\u043E\u0442\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D",{commandCount:result.commands.length,effectCount:result.effects.length,invocationId:invocation.invocationId,runId,status:result.status});return result})]})}async function runHarness(input){if(!input.settings.apiToken){throw new Error("AI-\u0431\u043E\u0442\u0443 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F apiToken \u0432 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.")}const planText=await callAiModel(input.settings,[{content:buildPlanningPrompt(input.input),role:"user"}]);const plannedCommands=normalizePlan(parseJsonObject(planText),input.input.maxCommands);const effects=[];for(const plannedCommand of plannedCommands){effects.push(await executePlannedCommand({brandMap:input.brandMap,command:plannedCommand,input:input.input,storage:input.storage}))}const summary=await createFinalSummary({effects,planText,settings:input.settings,task:input.input.task});const result={allowMutations:input.input.allowMutations,commands:plannedCommands,dryRun:input.input.dryRun,effects,finishedAt:new Date().toISOString(),model:input.settings.model,planText,provider:input.settings.aiProvider,runId:input.runId,startedAt:input.startedAt,status:effects.some((effect)=>effect.status==="error")?"failed":"completed",summary,task:input.input.task};await persistRun(input.storage,result);return result}async function createFinalSummary(input){const status=input.effects.some((effect)=>effect.status==="error")?"completed-with-errors":"completed";try{const summaryText=await callAiModel(input.settings,[{content:buildSummaryPrompt({effects:input.effects,planText:input.planText,task:input.task}),role:"user"}]);return toExtensionJson2(parseJsonObject(summaryText,{message:summaryText,status}))}catch(error){return{errors:[error instanceof Error?error.message:String(error)],status:"summary-failed",summary:"\u041A\u043E\u043C\u0430\u043D\u0434\u044B \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u044B, \u043D\u043E \u0444\u0438\u043D\u0430\u043B\u044C\u043D\u044B\u0439 \u0437\u0430\u043F\u0440\u043E\u0441 AI-\u0441\u0432\u043E\u0434\u043A\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0441\u044F \u043E\u0448\u0438\u0431\u043A\u043E\u0439."}}}async function executePlannedCommand(input){const startedAt=new Date().toISOString();const definition=COMMAND_BY_NAME.get(input.command.command);const base={args:input.command.args,command:input.command.command,finishedAt:startedAt,id:input.command.id,reason:input.command.reason,startedAt};if(!definition){return{...base,skippedReason:"\u041D\u0435\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u0430\u044F \u043A\u043E\u043C\u0430\u043D\u0434\u0430.",status:"skipped"}}if(input.input.allowedCommands&&!input.input.allowedCommands.has(input.command.command)){return{...base,skippedReason:"\u041A\u043E\u043C\u0430\u043D\u0434\u044B \u043D\u0435\u0442 \u0432\u043E \u0432\u0445\u043E\u0434\u043D\u043E\u043C allowedCommands workflow.",status:"skipped"}}if(definition.mutates&&input.input.dryRun){return{...base,skippedReason:"\u0412\u043A\u043B\u044E\u0447\u0435\u043D \u043F\u0440\u043E\u0431\u043D\u044B\u0439 \u0437\u0430\u043F\u0443\u0441\u043A.",status:"skipped"}}if(definition.mutates&&!input.input.allowMutations){return{...base,skippedReason:"\u041A\u043E\u043C\u0430\u043D\u0434\u044B \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043E\u0442\u043A\u043B\u044E\u0447\u0435\u043D\u044B.",status:"skipped"}}try{const result=await dispatchCommand(input.brandMap,input.storage,input.command);return{...base,finishedAt:new Date().toISOString(),result:compactResult(result),status:"ok"}}catch(error){return{...base,error:error instanceof Error?error.message:String(error),finishedAt:new Date().toISOString(),status:"error"}}}async function dispatchCommand(brandMap,storage,command){const args=command.args;switch(command.command){case"product.list":return await brandMap.product.list(args[0]);case"product.retrieve":return await brandMap.product.retrieve(readStringArg(args,0),args[1]);case"product.retrieveVariantByExternalSku":return await brandMap.product.retrieveVariantByExternalSku(readStringArg(args,0));case"product.listVariants":return await brandMap.product.listVariants(readStringArg(args,0));case"product.listCategories":return await brandMap.product.listCategories(args[0]);case"product.create":return await brandMap.product.create(args[0]);case"product.update":return await brandMap.product.update(args[0]);case"product.createCategory":return await brandMap.product.createCategory(args[0]);case"product.updateCategory":return await brandMap.product.updateCategory(readStringArg(args,0),args[1]);case"product.createVariant":return await brandMap.product.createVariant(readStringArg(args,0),args[1]);case"product.updateVariant":return await brandMap.product.updateVariant(readStringArg(args,0),args[1]);case"product.addImage":return await brandMap.product.addImage(readStringArg(args,0),readStringArg(args,1),readOptionalNumberArg(args,2));case"product.upsertOption":return await brandMap.product.upsertOption(readStringArg(args,0),args[1]);case"product.upsertOptionValue":return await brandMap.product.upsertOptionValue(readStringArg(args,0),args[1]);case"product.linkVariantOptionValue":return await brandMap.product.linkVariantOptionValue(readStringArg(args,0),readStringArg(args,1));case"product.upsertAttribute":return await brandMap.product.upsertAttribute(readStringArg(args,0),args[1]);case"product.upsertAttributeValue":return await brandMap.product.upsertAttributeValue(args[0]);case"price.listPriceList":return await brandMap.price.listPriceList(args[0]);case"price.listPriceListPrice":return await brandMap.price.listPriceListPrice(args[0]);case"price.createPriceList":return await brandMap.price.createPriceList(args[0]);case"price.updatePriceList":return await brandMap.price.updatePriceList(args[0]);case"price.createPriceListPrice":return await brandMap.price.createPriceListPrice(args[0]);case"price.updatePriceListPrice":return await brandMap.price.updatePriceListPrice(args[0]);case"price.setBasePrice":return await brandMap.price.setBasePrice(args[0]);case"stockLocation.listStockLocation":return await brandMap.stockLocation.listStockLocation(args[0]);case"stockLocation.retrieveStockLocation":return await brandMap.stockLocation.retrieveStockLocation(readStringArg(args,0),args[1]);case"stockLocation.createStockLocation":return await brandMap.stockLocation.createStockLocation(args[0]);case"stockLocation.updateStockLocation":return await brandMap.stockLocation.updateStockLocation(args[0]);case"stockLocation.upsertStockLocation":return await brandMap.stockLocation.upsertStockLocation(args[0]);case"inventory.enrollVariantInStore":return await brandMap.inventory.enrollVariantInStore(args[0]);case"inventory.syncStockLevel":return await brandMap.inventory.syncStockLevel(args[0]);case"notification.createNotifications":return await brandMap.notification.createNotifications(args[0]);case"notification.listNotifications":return await brandMap.notification.listNotifications(args[0]);case"notification.retrieveNotification":return await brandMap.notification.retrieveNotification(readStringArg(args,0),args[1]);case"file.create":return await brandMap.file.create(args[0]);case"file.delete":return await brandMap.file.delete(args[0]);case"file.list":return await brandMap.file.list(args[0]);case"file.retrieve":return await brandMap.file.retrieve(readStringArg(args,0),args[1]);case"storage.db.get":return await storage.db.get(readStringArg(args,0));case"storage.db.list":return await storage.db.list(args[0]);case"storage.db.set":return await storage.db.set(args[0]);case"storage.db.delete":return await storage.db.delete(args[0]);case"storage.cache.get":return await storage.cache.get(readStringArg(args,0));case"storage.cache.set":return await storage.cache.set(args[0]);case"storage.cache.delete":return await storage.cache.delete(args[0]);default:throw new Error(`\u041D\u0435\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u0430\u044F \u043A\u043E\u043C\u0430\u043D\u0434\u0430 "${command.command}"`)}}async function callAiModel(settings,messages){assertAiBaseUrl(settings.apiBaseUrl);if(settings.aiProvider==="anthropic"){return await callAnthropic(settings,messages)}return await callOpenAiCompatible(settings,messages)}async function callOpenAiCompatible(settings,messages){const response=await settings.fetchImplementation(`${settings.apiBaseUrl}/chat/completions`,{body:JSON.stringify({messages:[{content:settings.systemPrompt,role:"system"},...messages],model:settings.model,response_format:{type:"json_object"},temperature:0.1}),headers:{authorization:`Bearer ${settings.apiToken}`,"content-type":"application/json"},method:"POST"});const payload=await readAiResponse(response);const content=readPath(payload,["choices",0,"message","content"]);if(typeof content!=="string"){throw new Error("\u041E\u0442\u0432\u0435\u0442 AI-\u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u043D\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 choices[0].message.content.")}return content}async function callAnthropic(settings,messages){const response=await settings.fetchImplementation(`${settings.apiBaseUrl}/messages`,{body:JSON.stringify({max_tokens:2000,messages,model:settings.model,system:settings.systemPrompt,temperature:0.1}),headers:{"anthropic-version":"2023-06-01","content-type":"application/json","x-api-key":settings.apiToken??""},method:"POST"});const payload=await readAiResponse(response);const blocks=readPath(payload,["content"]);if(!Array.isArray(blocks)){throw new Error("\u041E\u0442\u0432\u0435\u0442 AI-\u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u043D\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 content-\u0431\u043B\u043E\u043A\u0438.")}return blocks.map((block)=>isRecord(block)&&typeof block.text==="string"?block.text:"").join(`
|
|
6
|
+
`).trim()}async function readAiResponse(response){const text=await response.text();const payload=parseJsonObject(text,{message:text});if(!response.ok){const message=readAiErrorMessage(payload)??`AI provider request failed with status ${response.status}.`;throw new Error(message)}return payload}function buildPlanningPrompt(input){return truncateText(JSON.stringify({context:input.context,instructions:["Pick the minimum command sequence needed.","Use read commands before mutation commands when identifiers are unknown.","Mutation commands are only useful when allowMutations is true and dryRun is false.","Return only JSON with a commands array."],runtime:{allowMutations:input.allowMutations,allowedCommands:input.allowedCommands?Array.from(input.allowedCommands):null,dryRun:input.dryRun,maxCommands:input.maxCommands},task:input.task},null,2),MAX_MODEL_CONTEXT_CHARS)}function buildSummaryPrompt(input){return truncateText(JSON.stringify({effects:input.effects,instructions:["Summarize what happened for the user.","Mention commands that were skipped or failed.","Return only JSON with keys summary, status, actions, skipped, errors, nextSteps."],planText:input.planText,task:input.task},null,2),MAX_MODEL_CONTEXT_CHARS)}function normalizePlan(input,maxCommands){if(!isRecord(input)||!Array.isArray(input.commands)){throw new Error("AI-\u043F\u043B\u0430\u043D \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C JSON-\u043E\u0431\u044A\u0435\u043A\u0442\u043E\u043C \u0441 \u043C\u0430\u0441\u0441\u0438\u0432\u043E\u043C commands.")}return input.commands.slice(0,maxCommands).map((entry,index)=>{if(!isRecord(entry)||typeof entry.command!=="string"){throw new Error(`\u041A\u043E\u043C\u0430\u043D\u0434\u0430 AI-\u043F\u043B\u0430\u043D\u0430 \u0441 \u0438\u043D\u0434\u0435\u043A\u0441\u043E\u043C ${index} \u0434\u043E\u043B\u0436\u043D\u0430 \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C command.`)}return{args:readJsonArray(entry.args),command:entry.command,id:typeof entry.id==="string"&&entry.id.trim()?entry.id:`cmd-${index+1}`,reason:typeof entry.reason==="string"?entry.reason:null}})}function readHarnessInput(input,settings){const value=isRecord(input)?input:{};const task=readStringField(value,"task")??readStringField(value,"prompt");if(!task){throw new Error("\u0412\u0445\u043E\u0434\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 workflow AI-\u0431\u043E\u0442\u0430 \u0442\u0440\u0435\u0431\u0443\u044E\u0442 task.")}return{allowMutations:settings.allowMutations&&readBooleanField(value,"allowMutations",false),allowedCommands:readAllowedCommands(value.allowedCommands),context:toExtensionJson2(value.context??null),dryRun:readBooleanField(value,"dryRun",settings.dryRun),maxCommands:clampInteger(readNumberField(value,"maxCommands")??settings.maxCommands,1,25),task}}function readSettings(options){const aiProvider=readProvider(options.aiProvider);const configuredApiBaseUrl=stringOption(options.apiBaseUrl);const apiBaseUrl=aiProvider==="anthropic"&&(!configuredApiBaseUrl||configuredApiBaseUrl===DEFAULT_OPENAI_BASE_URL)?DEFAULT_ANTHROPIC_BASE_URL:configuredApiBaseUrl??(aiProvider==="anthropic"?DEFAULT_ANTHROPIC_BASE_URL:DEFAULT_OPENAI_BASE_URL);return{aiProvider,allowMutations:booleanOption(options.allowMutations)??false,apiBaseUrl:apiBaseUrl.replace(/\/+$/,""),apiToken:stringOption(options.apiToken),dryRun:booleanOption(options.dryRun)??false,fetchImplementation:options.fetchImplementation??fetch,maxCommands:clampInteger(numberOption(options.maxCommands)??DEFAULT_MAX_COMMANDS,1,25),model:stringOption(options.model)??DEFAULT_MODEL,systemPrompt:stringOption(options.systemPrompt)??DEFAULT_SYSTEM_PROMPT}}async function persistRun(storage,result){const value=toExtensionJson2(result);await storage.db.set({key:`${RUN_HISTORY_PREFIX}${result.runId}`,value});await storage.db.set({key:LAST_RUN_KEY,value})}function parseJsonObject(text,fallback){if(typeof text!=="string"){return text}const trimmed=stripJsonFence(text.trim());try{return parseJsonText(trimmed)}catch{const objectMatch=/\{[\s\S]*\}/.exec(trimmed);if(objectMatch){try{return parseJsonText(objectMatch[0])}catch{return fallback??text}}return fallback??text}}function stripJsonFence(text){return text.replace(/^```(?:json)?\s*/u,"").replace(/\s*```$/u,"").trim()}function readAiErrorMessage(payload){if(!isRecord(payload)){return null}const error=payload.error;if(typeof error==="string"){return error}if(isRecord(error)&&typeof error.message==="string"){return error.message}return null}function compactResult(value){const json=toExtensionJson2(value);const text=JSON.stringify(json);if(text.length<=MAX_EFFECT_RESULT_CHARS){return json}return{truncated:true,value:text.slice(0,MAX_EFFECT_RESULT_CHARS)}}function toExtensionJson2(value,depth=0){if(value===null||typeof value==="boolean"||typeof value==="string"){return value}if(typeof value==="number"){return Number.isFinite(value)?value:null}if(value===undefined){return null}if(value instanceof Date){return value.toISOString()}if(depth>6){return"[Truncated]"}if(Array.isArray(value)){return value.slice(0,100).map((entry)=>toExtensionJson2(entry,depth+1))}if(typeof value==="object"){const output={};for(const[key,entry]of Object.entries(value).slice(0,100)){if(typeof entry!=="function"&&typeof entry!=="symbol"){output[key]=toExtensionJson2(entry,depth+1)}}return output}return String(value)}function readJsonArray(value){if(!Array.isArray(value)){return[]}return value.map((entry)=>toExtensionJson2(entry))}function readAllowedCommands(value){if(!Array.isArray(value)){return null}return new Set(value.filter((entry)=>typeof entry==="string"))}function readStringArg(args,index){const value=args[index];if(typeof value!=="string"||!value.trim()){throw new Error(`\u0410\u0440\u0433\u0443\u043C\u0435\u043D\u0442 \u043A\u043E\u043C\u0430\u043D\u0434\u044B ${index} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435\u043F\u0443\u0441\u0442\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u043E\u0439.`)}return value}function readOptionalNumberArg(args,index){const value=args[index];if(value===undefined||value===null){return}if(typeof value!=="number"||!Number.isFinite(value)){throw new Error(`\u0410\u0440\u0433\u0443\u043C\u0435\u043D\u0442 \u043A\u043E\u043C\u0430\u043D\u0434\u044B ${index} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0447\u0438\u0441\u043B\u043E\u043C.`)}return value}function readProvider(value){return value==="anthropic"||value==="openai-compatible"||value==="openai"?value:"openai"}function stringOption(value){return typeof value==="string"&&value.trim()?value.trim():null}function booleanOption(value){return typeof value==="boolean"?value:null}function numberOption(value){return typeof value==="number"&&Number.isFinite(value)?value:null}function readStringField(value,key){return stringOption(value[key])}function readBooleanField(value,key,defaultValue){return booleanOption(value[key])??defaultValue}function readNumberField(value,key){return numberOption(value[key])}function clampInteger(value,min,max){return Math.max(min,Math.min(max,Math.trunc(value)))}function isRecord(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function readPath(value,path){let current=value;for(const segment of path){if(typeof segment==="number"){if(!Array.isArray(current)){return}current=current[segment];continue}if(!isRecord(current)){return}current=current[segment]}return current}function assertAiBaseUrl(value){const url=new URL(value);const isLocalHttp=url.protocol==="http:"&&(url.hostname==="localhost"||url.hostname==="127.0.0.1");if(url.protocol!=="https:"&&!isLocalHttp){throw new Error("\u0411\u0430\u0437\u043E\u0432\u044B\u0439 URL API AI \u0434\u043E\u043B\u0436\u0435\u043D \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C https, \u043A\u0440\u043E\u043C\u0435 localhost URL \u0434\u043B\u044F \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u043A\u0438.")}}function truncateText(value,maxLength){if(value.length<=maxLength){return value}return`${value.slice(0,maxLength)}
|
|
7
7
|
[truncated]`}var extension_default=createAiBotExtension;var bundledExtension={packageName:"@brand-map/ai-bot-extension"};var exports_default=extension_default;export{exports_default as default,createAiBotExtension,bundledExtension};
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
{
|
|
4
4
|
"defaultValue": "openai",
|
|
5
5
|
"key": "aiProvider",
|
|
6
|
-
"label": "AI
|
|
6
|
+
"label": "AI-провайдер",
|
|
7
7
|
"options": [
|
|
8
8
|
{
|
|
9
9
|
"label": "OpenAI",
|
|
10
10
|
"value": "openai"
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
|
-
"label": "OpenAI
|
|
13
|
+
"label": "OpenAI-совместимый",
|
|
14
14
|
"value": "openai-compatible"
|
|
15
15
|
},
|
|
16
16
|
{
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"key": "apiToken",
|
|
25
|
-
"label": "
|
|
25
|
+
"label": "API-токен AI-провайдера",
|
|
26
26
|
"required": true,
|
|
27
27
|
"secret": true,
|
|
28
28
|
"type": "string"
|
|
@@ -30,50 +30,50 @@
|
|
|
30
30
|
{
|
|
31
31
|
"defaultValue": "https://api.openai.com/v1",
|
|
32
32
|
"key": "apiBaseUrl",
|
|
33
|
-
"label": "
|
|
33
|
+
"label": "Базовый URL API AI",
|
|
34
34
|
"type": "url"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"defaultValue": "gpt-4.1-mini",
|
|
38
38
|
"key": "model",
|
|
39
|
-
"label": "
|
|
39
|
+
"label": "Модель",
|
|
40
40
|
"type": "string"
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"defaultValue": 8,
|
|
44
44
|
"key": "maxCommands",
|
|
45
|
-
"label": "
|
|
45
|
+
"label": "Максимум команд",
|
|
46
46
|
"type": "number"
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
"defaultValue": false,
|
|
50
|
-
"description": "
|
|
50
|
+
"description": "Разрешает исполнителю выполнять команды записи, если входные данные процесса тоже это разрешают.",
|
|
51
51
|
"key": "allowMutations",
|
|
52
|
-
"label": "
|
|
52
|
+
"label": "Разрешить изменения",
|
|
53
53
|
"type": "boolean"
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
"defaultValue": false,
|
|
57
|
-
"description": "
|
|
57
|
+
"description": "Выполняет команды чтения, но пропускает команды записи.",
|
|
58
58
|
"key": "dryRun",
|
|
59
|
-
"label": "
|
|
59
|
+
"label": "Пробный запуск",
|
|
60
60
|
"type": "boolean"
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
|
-
"defaultValue": "
|
|
63
|
+
"defaultValue": "Вы - исполнитель Brand Map AI Bot.\n\nВы решаете, какие именно команды расширения нужно запустить для задачи пользователя.\n\nВозвращайте только JSON. Не возвращайте shell-команды. Не придумывайте команды.\n\nКаждая команда должна иметь такой формат:\n\n{\"commands\":[{\"id\":\"short-id\",\"command\":\"product.list\",\"args\":[{\"limit\":5}],\"reason\":\"зачем это нужно\"}]}\n\nИспользуйте пустой массив commands, если безопасное действие не требуется.\n\nДоступные команды:\n\n- product.list (чтение): Получить список товаров с необязательным запросом чтения.\n- product.retrieve (чтение): Получить один товар по id.\n- product.retrieveVariantByExternalSku (чтение): Получить вариант по внешнему SKU.\n- product.listVariants (чтение): Получить список вариантов для id товара.\n- product.listCategories (чтение): Получить список категорий товаров.\n- price.listPriceList (чтение): Получить список прайс-листов.\n- price.listPriceListPrice (чтение): Получить список цен прайс-листов.\n- stockLocation.listStockLocation (чтение): Получить список складов.\n- stockLocation.retrieveStockLocation (чтение): Получить один склад по id.\n- notification.listNotifications (чтение): Получить список уведомлений.\n- notification.retrieveNotification (чтение): Получить одно уведомление по id.\n- file.list (чтение): Получить список файлов.\n- file.retrieve (чтение): Получить метаданные файла по id.\n- storage.db.get (чтение): Прочитать одну запись хранилища расширения по ключу.\n- storage.db.list (чтение): Получить список записей хранилища расширения.\n- storage.cache.get (чтение): Прочитать одно значение кеша расширения по ключу.\n- product.create (мутация): Создать один или несколько товаров.\n- product.update (мутация): Обновить один или несколько товаров.\n- product.createCategory (мутация): Создать категорию товаров.\n- product.updateCategory (мутация): Обновить категорию товаров.\n- product.createVariant (мутация): Создать вариант товара.\n- product.updateVariant (мутация): Обновить вариант товара.\n- product.addImage (мутация): Добавить URL изображения к товару.\n- product.upsertOption (мутация): Создать или обновить опцию товара.\n- product.upsertOptionValue (мутация): Создать или обновить значение опции товара.\n- product.linkVariantOptionValue (мутация): Связать вариант со значением опции.\n- product.upsertAttribute (мутация): Создать или обновить атрибут товара.\n- product.upsertAttributeValue (мутация): Создать или обновить значение атрибута товара.\n- price.createPriceList (мутация): Создать один или несколько прайс-листов.\n- price.updatePriceList (мутация): Обновить один или несколько прайс-листов.\n- price.createPriceListPrice (мутация): Создать одну или несколько цен прайс-листа.\n- price.updatePriceListPrice (мутация): Обновить одну или несколько цен прайс-листа.\n- price.setBasePrice (мутация): Установить базовую цену варианта.\n- stockLocation.createStockLocation (мутация): Создать склад.\n- stockLocation.updateStockLocation (мутация): Обновить склад.\n- stockLocation.upsertStockLocation (мутация): Создать или обновить склад.\n- inventory.enrollVariantInStore (мутация): Зарегистрировать вариант в остатках магазина.\n- inventory.syncStockLevel (мутация): Синхронизировать остаток.\n- notification.createNotifications (мутация): Создать одно или несколько уведомлений.\n- file.create (мутация): Создать файл из строкового содержимого.\n- file.delete (мутация): Удалить один или несколько файлов по id.\n- storage.db.set (мутация): Записать запись хранилища расширения.\n- storage.db.delete (мутация): Удалить записи хранилища расширения.\n- storage.cache.set (мутация): Записать значение кеша расширения.\n- storage.cache.delete (мутация): Удалить значения кеша расширения.",
|
|
64
64
|
"key": "systemPrompt",
|
|
65
|
-
"label": "
|
|
65
|
+
"label": "Системный промпт",
|
|
66
66
|
"type": "string"
|
|
67
67
|
}
|
|
68
68
|
],
|
|
69
|
-
"description": "
|
|
69
|
+
"description": "Запускает небольшой AI-исполнитель как Temporal-процесс поверх разрешенных команд расширения Brand Map.",
|
|
70
70
|
"developerUrl": "https://brand-map.ru",
|
|
71
|
-
"displayName": "AI
|
|
71
|
+
"displayName": "AI-бот",
|
|
72
72
|
"eventHandlers": [],
|
|
73
73
|
"hooks": [],
|
|
74
74
|
"jobs": [],
|
|
75
75
|
"logo": {
|
|
76
|
-
"alt": "AI
|
|
76
|
+
"alt": "Иконка AI-бота",
|
|
77
77
|
"src": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5NiA5NiI+PHJlY3Qgd2lkdGg9Ijk2IiBoZWlnaHQ9Ijk2IiByeD0iMjAiIGZpbGw9IiMxMjE4MjYiLz48cGF0aCBkPSJNMjQgNDBjMC05Ljk0IDguMDYtMTggMTgtMThoMTJjOS45NCAwIDE4IDguMDYgMTggMTh2MThjMCA2LjYzLTUuMzcgMTItMTIgMTJIMzZjLTYuNjMgMC0xMi01LjM3LTEyLTEyVjQwWiIgZmlsbD0iIzJERDRCRiIvPjxwYXRoIGQ9Ik0zMiA0MmMwLTUuNTIgNC40OC0xMCAxMC0xMGgxMmM1LjUyIDAgMTAgNC40OCAxMCAxMHYxMmMwIDQuNDItMy41OCA4LTggOEg0MGMtNC40MiAwLTgtMy41OC04LThWNDJaIiBmaWxsPSIjRjhGQUZDIi8+PGNpcmNsZSBjeD0iNDIiIGN5PSI0OCIgcj0iNCIgZmlsbD0iIzEyMTgyNiIvPjxjaXJjbGUgY3g9IjU0IiBjeT0iNDgiIHI9IjQiIGZpbGw9IiMxMjE4MjYiLz48cGF0aCBkPSJNNDIgNjBoMTIiIHN0cm9rZT0iIzEyMTgyNiIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48cGF0aCBkPSJNNDggMTh2LTZNMjcgMjVsLTQtNE02OSAyNWw0LTRNMjYgNzZsLTUgNU03MCA3Nmw1IDUiIHN0cm9rZT0iI0E3OEJGQSIgc3Ryb2tlLXdpZHRoPSI1IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4="
|
|
78
78
|
},
|
|
79
79
|
"name": "ai-bot",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"name": "last-run"
|
|
132
132
|
}
|
|
133
133
|
],
|
|
134
|
-
"version": "0.0.10-alpha.
|
|
134
|
+
"version": "0.0.10-alpha.15",
|
|
135
135
|
"workflows": [
|
|
136
136
|
{
|
|
137
137
|
"name": "run-harness"
|
package/docs/README.md
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
# AI
|
|
1
|
+
# AI-бот
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Расширение AI-бота запускает одобренный исполнитель команд как Temporal-процесс. Оно отправляет пользовательскую задачу и контекст настроенному AI-провайдеру, выполняет только команды из каталога команд расширения и сохраняет последний запуск в хранилище расширения.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Что Делает
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
7
|
+
- Вызывает настроенного AI-провайдера.
|
|
8
|
+
- Требует, чтобы модель возвращала JSON-планы команд.
|
|
9
|
+
- Выполняет одобренные операции чтения и записи Brand Map через runtime расширений.
|
|
10
|
+
- Поддерживает пробный режим только для чтения.
|
|
11
|
+
- Требует разрешения мутаций и в конфигурации установки, и во входных данных workflow перед выполнением команд записи.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Конфигурация
|
|
14
14
|
|
|
15
|
-
- `aiProvider`: AI
|
|
16
|
-
- `apiToken`:
|
|
17
|
-
- `apiBaseUrl`:
|
|
18
|
-
- `model`:
|
|
19
|
-
- `maxCommands`:
|
|
20
|
-
- `allowMutations`:
|
|
21
|
-
- `dryRun`:
|
|
22
|
-
- `systemPrompt`:
|
|
15
|
+
- `aiProvider`: режим AI-провайдера.
|
|
16
|
+
- `apiToken`: API-токен провайдера.
|
|
17
|
+
- `apiBaseUrl`: базовый URL API провайдера.
|
|
18
|
+
- `model`: имя модели.
|
|
19
|
+
- `maxCommands`: максимальное число команд за запуск.
|
|
20
|
+
- `allowMutations`: переключатель разрешения записи на уровне установки.
|
|
21
|
+
- `dryRun`: пропускает команды записи.
|
|
22
|
+
- `systemPrompt`: промпт планирования команд.
|
|
23
23
|
|
|
24
|
-
## Workflow
|
|
24
|
+
## Входные Данные Workflow
|
|
25
25
|
|
|
26
26
|
```json
|
|
27
27
|
{
|
|
28
|
-
"task": "
|
|
28
|
+
"task": "Проверь первые пять товаров и кратко опиши, где нет миниатюр.",
|
|
29
29
|
"context": {
|
|
30
30
|
"storeId": "store_1"
|
|
31
31
|
},
|
|
@@ -35,6 +35,6 @@ The AI Bot extension runs an approved command harness as a Temporal workflow. It
|
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
##
|
|
38
|
+
## Модель Безопасности
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Расширение не запускает shell-команды. Оно выполняет только команды, объявленные в каталоге команд, а команды записи требуют явных флагов мутаций.
|
package/docs/SUMMARY.md
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Сводка
|
|
2
2
|
|
|
3
|
-
- [
|
|
3
|
+
- [Обзор](./README.md)
|