@brand-map/ai-bot-extension 0.0.10-alpha.10 → 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 ADDED
@@ -0,0 +1,33 @@
1
+ # Расширение AI-бота
2
+
3
+ Официальное расширение Brand Map, которое запускает небольшой исполнитель AI-команд как Temporal-процесс `run-harness`.
4
+
5
+ Процесс:
6
+
7
+ 1. Отправляет пользовательскую задачу, переданный контекст и системный промпт исполнителя настроенному AI-провайдеру.
8
+ 2. Ожидает от модели точные JSON-команды.
9
+ 3. Выполняет поддерживаемые команды расширений Brand Map и команды хранилища.
10
+ 4. Отправляет накопленные эффекты команд обратно модели для финальной JSON-сводки.
11
+ 5. Сохраняет последний запуск в хранилище расширения и возвращает сводку вызывающей стороне.
12
+
13
+ Команды мутаций требуют одновременно `allowMutations: true` в конфигурации установки и `allowMutations: true` во входных данных workflow. `dryRun: true` выполняет чтения, но пропускает записи.
14
+
15
+ Пример входных данных workflow:
16
+
17
+ ```json
18
+ {
19
+ "task": "Проверь первые пять товаров и кратко опиши, где нет миниатюр.",
20
+ "context": {
21
+ "storeId": "store_1"
22
+ },
23
+ "dryRun": false,
24
+ "allowMutations": false,
25
+ "maxCommands": 5
26
+ }
27
+ ```
28
+
29
+ Расширение не запускает shell-команды. Оно выполняет явный каталог команд, объявленный в системном промпте, через публичные API runtime расширений Brand Map.
30
+
31
+ ## Лицензия
32
+
33
+ UNLICENSED. Этот пакет является проприетарным ПО Brand Map и публикуется только для авторизованного использования в runtime расширений Brand Map. Лицензия с открытым исходным кодом не предоставляется.
@@ -0,0 +1,18 @@
1
+ var __create=Object.create;var __getProtoOf=Object.getPrototypeOf;var __defProp=Object.defineProperty;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;function __accessProp(key){return this[key]}var __toESMCache_node;var __toESMCache_esm;var __toESM=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node??=new WeakMap:__toESMCache_esm??=new WeakMap;var cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create(__getProtoOf(mod)):{};const to=isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target;for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:__accessProp.bind(mod,key),enumerable:true});if(canCache)cache.set(mod,to);return to};var __commonJS=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports);var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true,configurable:true,set:__exportSetter.bind(all,name)})};var __esm=(fn,res)=>()=>(fn&&(res=fn(fn=0)),res);var require_react_development=__commonJS((exports,module)=>{(function(){function defineDeprecationWarning(methodName,info){Object.defineProperty(Component.prototype,methodName,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",info[0],info[1])}})}function getIteratorFn(maybeIterable){if(maybeIterable===null||typeof maybeIterable!=="object")return null;maybeIterable=MAYBE_ITERATOR_SYMBOL&&maybeIterable[MAYBE_ITERATOR_SYMBOL]||maybeIterable["@@iterator"];return typeof maybeIterable==="function"?maybeIterable:null}function warnNoop(publicInstance,callerName){publicInstance=(publicInstance=publicInstance.constructor)&&(publicInstance.displayName||publicInstance.name)||"ReactClass";var warningKey=publicInstance+"."+callerName;didWarnStateUpdateForUnmountedComponent[warningKey]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",callerName,publicInstance),didWarnStateUpdateForUnmountedComponent[warningKey]=true)}function Component(props,context,updater){this.props=props;this.context=context;this.refs=emptyObject;this.updater=updater||ReactNoopUpdateQueue}function ComponentDummy(){}function PureComponent(props,context,updater){this.props=props;this.context=context;this.refs=emptyObject;this.updater=updater||ReactNoopUpdateQueue}function noop(){}function testStringCoercion(value){return""+value}function checkKeyStringCoercion(value){try{testStringCoercion(value);var JSCompiler_inline_result=false}catch(e){JSCompiler_inline_result=true}if(JSCompiler_inline_result){JSCompiler_inline_result=console;var JSCompiler_temp_const=JSCompiler_inline_result.error;var JSCompiler_inline_result$jscomp$0=typeof Symbol==="function"&&Symbol.toStringTag&&value[Symbol.toStringTag]||value.constructor.name||"Object";JSCompiler_temp_const.call(JSCompiler_inline_result,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",JSCompiler_inline_result$jscomp$0);return testStringCoercion(value)}}function getComponentNameFromType(type){if(type==null)return null;if(typeof type==="function")return type.$$typeof===REACT_CLIENT_REFERENCE?null:type.displayName||type.name||null;if(typeof type==="string")return type;switch(type){case REACT_FRAGMENT_TYPE:return"Fragment";case REACT_PROFILER_TYPE:return"Profiler";case REACT_STRICT_MODE_TYPE:return"StrictMode";case REACT_SUSPENSE_TYPE:return"Suspense";case REACT_SUSPENSE_LIST_TYPE:return"SuspenseList";case REACT_ACTIVITY_TYPE:return"Activity"}if(typeof type==="object")switch(typeof type.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),type.$$typeof){case REACT_PORTAL_TYPE:return"Portal";case REACT_CONTEXT_TYPE:return type.displayName||"Context";case REACT_CONSUMER_TYPE:return(type._context.displayName||"Context")+".Consumer";case REACT_FORWARD_REF_TYPE:var innerType=type.render;type=type.displayName;type||(type=innerType.displayName||innerType.name||"",type=type!==""?"ForwardRef("+type+")":"ForwardRef");return type;case REACT_MEMO_TYPE:return innerType=type.displayName||null,innerType!==null?innerType:getComponentNameFromType(type.type)||"Memo";case REACT_LAZY_TYPE:innerType=type._payload;type=type._init;try{return getComponentNameFromType(type(innerType))}catch(x){}}return null}function getTaskName(type){if(type===REACT_FRAGMENT_TYPE)return"<>";if(typeof type==="object"&&type!==null&&type.$$typeof===REACT_LAZY_TYPE)return"<...>";try{var name=getComponentNameFromType(type);return name?"<"+name+">":"<...>"}catch(x){return"<...>"}}function getOwner(){var dispatcher=ReactSharedInternals.A;return dispatcher===null?null:dispatcher.getOwner()}function UnknownOwner(){return Error("react-stack-top-frame")}function hasValidKey(config){if(hasOwnProperty.call(config,"key")){var getter=Object.getOwnPropertyDescriptor(config,"key").get;if(getter&&getter.isReactWarning)return false}return config.key!==undefined}function defineKeyPropWarningGetter(props,displayName){function warnAboutAccessingKey(){specialPropKeyWarningShown||(specialPropKeyWarningShown=true,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",displayName))}warnAboutAccessingKey.isReactWarning=true;Object.defineProperty(props,"key",{get:warnAboutAccessingKey,configurable:true})}function elementRefGetterWithDeprecationWarning(){var componentName=getComponentNameFromType(this.type);didWarnAboutElementRef[componentName]||(didWarnAboutElementRef[componentName]=true,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."));componentName=this.props.ref;return componentName!==undefined?componentName:null}function ReactElement(type,key,props,owner,debugStack,debugTask){var refProp=props.ref;type={$$typeof:REACT_ELEMENT_TYPE,type,key,props,_owner:owner};(refProp!==undefined?refProp:null)!==null?Object.defineProperty(type,"ref",{enumerable:false,get:elementRefGetterWithDeprecationWarning}):Object.defineProperty(type,"ref",{enumerable:false,value:null});type._store={};Object.defineProperty(type._store,"validated",{configurable:false,enumerable:false,writable:true,value:0});Object.defineProperty(type,"_debugInfo",{configurable:false,enumerable:false,writable:true,value:null});Object.defineProperty(type,"_debugStack",{configurable:false,enumerable:false,writable:true,value:debugStack});Object.defineProperty(type,"_debugTask",{configurable:false,enumerable:false,writable:true,value:debugTask});Object.freeze&&(Object.freeze(type.props),Object.freeze(type));return type}function cloneAndReplaceKey(oldElement,newKey){newKey=ReactElement(oldElement.type,newKey,oldElement.props,oldElement._owner,oldElement._debugStack,oldElement._debugTask);oldElement._store&&(newKey._store.validated=oldElement._store.validated);return newKey}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}function escape(key){var escaperLookup={"=":"=0",":":"=2"};return"$"+key.replace(/[=:]/g,function(match){return escaperLookup[match]})}function getElementKey(element,index){return typeof element==="object"&&element!==null&&element.key!=null?(checkKeyStringCoercion(element.key),escape(""+element.key)):index.toString(36)}function resolveThenable(thenable){switch(thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason;default:switch(typeof thenable.status==="string"?thenable.then(noop,noop):(thenable.status="pending",thenable.then(function(fulfilledValue){thenable.status==="pending"&&(thenable.status="fulfilled",thenable.value=fulfilledValue)},function(error){thenable.status==="pending"&&(thenable.status="rejected",thenable.reason=error)})),thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason}}throw thenable}function mapIntoArray(children,array,escapedPrefix,nameSoFar,callback){var type=typeof children;if(type==="undefined"||type==="boolean")children=null;var invokeCallback=false;if(children===null)invokeCallback=true;else switch(type){case"bigint":case"string":case"number":invokeCallback=true;break;case"object":switch(children.$$typeof){case REACT_ELEMENT_TYPE:case REACT_PORTAL_TYPE:invokeCallback=true;break;case REACT_LAZY_TYPE:return invokeCallback=children._init,mapIntoArray(invokeCallback(children._payload),array,escapedPrefix,nameSoFar,callback)}}if(invokeCallback){invokeCallback=children;callback=callback(invokeCallback);var childKey=nameSoFar===""?"."+getElementKey(invokeCallback,0):nameSoFar;isArrayImpl(callback)?(escapedPrefix="",childKey!=null&&(escapedPrefix=childKey.replace(userProvidedKeyEscapeRegex,"$&/")+"/"),mapIntoArray(callback,array,escapedPrefix,"",function(c){return c})):callback!=null&&(isValidElement(callback)&&(callback.key!=null&&(invokeCallback&&invokeCallback.key===callback.key||checkKeyStringCoercion(callback.key)),escapedPrefix=cloneAndReplaceKey(callback,escapedPrefix+(callback.key==null||invokeCallback&&invokeCallback.key===callback.key?"":(""+callback.key).replace(userProvidedKeyEscapeRegex,"$&/")+"/")+childKey),nameSoFar!==""&&invokeCallback!=null&&isValidElement(invokeCallback)&&invokeCallback.key==null&&invokeCallback._store&&!invokeCallback._store.validated&&(escapedPrefix._store.validated=2),callback=escapedPrefix),array.push(callback));return 1}invokeCallback=0;childKey=nameSoFar===""?".":nameSoFar+":";if(isArrayImpl(children))for(var i=0;i<children.length;i++)nameSoFar=children[i],type=childKey+getElementKey(nameSoFar,i),invokeCallback+=mapIntoArray(nameSoFar,array,escapedPrefix,type,callback);else if(i=getIteratorFn(children),typeof i==="function")for(i===children.entries&&(didWarnAboutMaps||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),didWarnAboutMaps=true),children=i.call(children),i=0;!(nameSoFar=children.next()).done;)nameSoFar=nameSoFar.value,type=childKey+getElementKey(nameSoFar,i++),invokeCallback+=mapIntoArray(nameSoFar,array,escapedPrefix,type,callback);else if(type==="object"){if(typeof children.then==="function")return mapIntoArray(resolveThenable(children),array,escapedPrefix,nameSoFar,callback);array=String(children);throw Error("Objects are not valid as a React child (found: "+(array==="[object Object]"?"object with keys {"+Object.keys(children).join(", ")+"}":array)+"). If you meant to render a collection of children, use an array instead.")}return invokeCallback}function mapChildren(children,func,context){if(children==null)return children;var result=[],count=0;mapIntoArray(children,result,"","",function(child){return func.call(context,child,count++)});return result}function lazyInitializer(payload){if(payload._status===-1){var ioInfo=payload._ioInfo;ioInfo!=null&&(ioInfo.start=ioInfo.end=performance.now());ioInfo=payload._result;var thenable=ioInfo();thenable.then(function(moduleObject){if(payload._status===0||payload._status===-1){payload._status=1;payload._result=moduleObject;var _ioInfo=payload._ioInfo;_ioInfo!=null&&(_ioInfo.end=performance.now());thenable.status===undefined&&(thenable.status="fulfilled",thenable.value=moduleObject)}},function(error){if(payload._status===0||payload._status===-1){payload._status=2;payload._result=error;var _ioInfo2=payload._ioInfo;_ioInfo2!=null&&(_ioInfo2.end=performance.now());thenable.status===undefined&&(thenable.status="rejected",thenable.reason=error)}});ioInfo=payload._ioInfo;if(ioInfo!=null){ioInfo.value=thenable;var displayName=thenable.displayName;typeof displayName==="string"&&(ioInfo.name=displayName)}payload._status===-1&&(payload._status=0,payload._result=thenable)}if(payload._status===1)return ioInfo=payload._result,ioInfo===undefined&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
2
+
3
+ Your code should look like:
4
+ const MyComponent = lazy(() => import('./MyComponent'))
5
+
6
+ Did you accidentally put curly braces around the import?`,ioInfo),"default"in ioInfo||console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
7
+
8
+ Your code should look like:
9
+ const MyComponent = lazy(() => import('./MyComponent'))`,ioInfo),ioInfo.default;throw payload._result}function resolveDispatcher(){var dispatcher=ReactSharedInternals.H;dispatcher===null&&console.error(`Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
10
+ 1. You might have mismatching versions of React and the renderer (such as React DOM)
11
+ 2. You might be breaking the Rules of Hooks
12
+ 3. You might have more than one copy of React in the same app
13
+ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.`);return dispatcher}function releaseAsyncTransition(){ReactSharedInternals.asyncTransitions--}function enqueueTask(task){if(enqueueTaskImpl===null)try{var requireString=("require"+Math.random()).slice(0,7);enqueueTaskImpl=(module&&module[requireString]).call(module,"timers").setImmediate}catch(_err){enqueueTaskImpl=function(callback){didWarnAboutMessageChannel===false&&(didWarnAboutMessageChannel=true,typeof MessageChannel==="undefined"&&console.error("This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning."));var channel=new MessageChannel;channel.port1.onmessage=callback;channel.port2.postMessage(undefined)}}return enqueueTaskImpl(task)}function aggregateErrors(errors){return 1<errors.length&&typeof AggregateError==="function"?new AggregateError(errors):errors[0]}function popActScope(prevActQueue,prevActScopeDepth){prevActScopeDepth!==actScopeDepth-1&&console.error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");actScopeDepth=prevActScopeDepth}function recursivelyFlushAsyncActWork(returnValue,resolve,reject){var queue=ReactSharedInternals.actQueue;if(queue!==null)if(queue.length!==0)try{flushActQueue(queue);enqueueTask(function(){return recursivelyFlushAsyncActWork(returnValue,resolve,reject)});return}catch(error){ReactSharedInternals.thrownErrors.push(error)}else ReactSharedInternals.actQueue=null;0<ReactSharedInternals.thrownErrors.length?(queue=aggregateErrors(ReactSharedInternals.thrownErrors),ReactSharedInternals.thrownErrors.length=0,reject(queue)):resolve(returnValue)}function flushActQueue(queue){if(!isFlushing){isFlushing=true;var i=0;try{for(;i<queue.length;i++){var callback=queue[i];do{ReactSharedInternals.didUsePromise=false;var continuation=callback(false);if(continuation!==null){if(ReactSharedInternals.didUsePromise){queue[i]=callback;queue.splice(0,i);return}callback=continuation}else break}while(1)}queue.length=0}catch(error){queue.splice(0,i+1),ReactSharedInternals.thrownErrors.push(error)}finally{isFlushing=false}}}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!=="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart==="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());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"),MAYBE_ITERATOR_SYMBOL=Symbol.iterator,didWarnStateUpdateForUnmountedComponent={},ReactNoopUpdateQueue={isMounted:function(){return false},enqueueForceUpdate:function(publicInstance){warnNoop(publicInstance,"forceUpdate")},enqueueReplaceState:function(publicInstance){warnNoop(publicInstance,"replaceState")},enqueueSetState:function(publicInstance){warnNoop(publicInstance,"setState")}},assign=Object.assign,emptyObject={};Object.freeze(emptyObject);Component.prototype.isReactComponent={};Component.prototype.setState=function(partialState,callback){if(typeof partialState!=="object"&&typeof partialState!=="function"&&partialState!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,partialState,callback,"setState")};Component.prototype.forceUpdate=function(callback){this.updater.enqueueForceUpdate(this,callback,"forceUpdate")};var deprecatedAPIs={isMounted:["isMounted","Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."],replaceState:["replaceState","Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."]};for(fnName in deprecatedAPIs)deprecatedAPIs.hasOwnProperty(fnName)&&defineDeprecationWarning(fnName,deprecatedAPIs[fnName]);ComponentDummy.prototype=Component.prototype;deprecatedAPIs=PureComponent.prototype=new ComponentDummy;deprecatedAPIs.constructor=PureComponent;assign(deprecatedAPIs,Component.prototype);deprecatedAPIs.isPureReactComponent=true;var isArrayImpl=Array.isArray,REACT_CLIENT_REFERENCE=Symbol.for("react.client.reference"),ReactSharedInternals={H:null,A:null,T:null,S:null,actQueue:null,asyncTransitions:0,isBatchingLegacy:false,didScheduleLegacyUpdate:false,didUsePromise:false,thrownErrors:[],getCurrentStack:null,recentlyCreatedOwnerStacks:0},hasOwnProperty=Object.prototype.hasOwnProperty,createTask=console.createTask?console.createTask:function(){return null};deprecatedAPIs={react_stack_bottom_frame:function(callStackForError){return callStackForError()}};var specialPropKeyWarningShown,didWarnAboutOldJSXRuntime;var didWarnAboutElementRef={};var unknownOwnerDebugStack=deprecatedAPIs.react_stack_bottom_frame.bind(deprecatedAPIs,UnknownOwner)();var unknownOwnerDebugTask=createTask(getTaskName(UnknownOwner));var didWarnAboutMaps=false,userProvidedKeyEscapeRegex=/\/+/g,reportGlobalError=typeof reportError==="function"?reportError:function(error){if(typeof window==="object"&&typeof window.ErrorEvent==="function"){var event=new window.ErrorEvent("error",{bubbles:true,cancelable:true,message:typeof error==="object"&&error!==null&&typeof error.message==="string"?String(error.message):String(error),error});if(!window.dispatchEvent(event))return}else if(typeof process==="object"&&typeof process.emit==="function"){process.emit("uncaughtException",error);return}console.error(error)},didWarnAboutMessageChannel=false,enqueueTaskImpl=null,actScopeDepth=0,didWarnNoAwaitAct=false,isFlushing=false,queueSeveralMicrotasks=typeof queueMicrotask==="function"?function(callback){queueMicrotask(function(){return queueMicrotask(callback)})}:enqueueTask;deprecatedAPIs=Object.freeze({__proto__:null,c:function(size){return resolveDispatcher().useMemoCache(size)}});var fnName={map:mapChildren,forEach:function(children,forEachFunc,forEachContext){mapChildren(children,function(){forEachFunc.apply(this,arguments)},forEachContext)},count:function(children){var n=0;mapChildren(children,function(){n++});return n},toArray:function(children){return mapChildren(children,function(child){return child})||[]},only:function(children){if(!isValidElement(children))throw Error("React.Children.only expected to receive a single React element child.");return children}};exports.Activity=REACT_ACTIVITY_TYPE;exports.Children=fnName;exports.Component=Component;exports.Fragment=REACT_FRAGMENT_TYPE;exports.Profiler=REACT_PROFILER_TYPE;exports.PureComponent=PureComponent;exports.StrictMode=REACT_STRICT_MODE_TYPE;exports.Suspense=REACT_SUSPENSE_TYPE;exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=ReactSharedInternals;exports.__COMPILER_RUNTIME=deprecatedAPIs;exports.act=function(callback){var prevActQueue=ReactSharedInternals.actQueue,prevActScopeDepth=actScopeDepth;actScopeDepth++;var queue=ReactSharedInternals.actQueue=prevActQueue!==null?prevActQueue:[],didAwaitActCall=false;try{var result=callback()}catch(error){ReactSharedInternals.thrownErrors.push(error)}if(0<ReactSharedInternals.thrownErrors.length)throw popActScope(prevActQueue,prevActScopeDepth),callback=aggregateErrors(ReactSharedInternals.thrownErrors),ReactSharedInternals.thrownErrors.length=0,callback;if(result!==null&&typeof result==="object"&&typeof result.then==="function"){var thenable=result;queueSeveralMicrotasks(function(){didAwaitActCall||didWarnNoAwaitAct||(didWarnNoAwaitAct=true,console.error("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"))});return{then:function(resolve,reject){didAwaitActCall=true;thenable.then(function(returnValue){popActScope(prevActQueue,prevActScopeDepth);if(prevActScopeDepth===0){try{flushActQueue(queue),enqueueTask(function(){return recursivelyFlushAsyncActWork(returnValue,resolve,reject)})}catch(error$0){ReactSharedInternals.thrownErrors.push(error$0)}if(0<ReactSharedInternals.thrownErrors.length){var _thrownError=aggregateErrors(ReactSharedInternals.thrownErrors);ReactSharedInternals.thrownErrors.length=0;reject(_thrownError)}}else resolve(returnValue)},function(error){popActScope(prevActQueue,prevActScopeDepth);0<ReactSharedInternals.thrownErrors.length?(error=aggregateErrors(ReactSharedInternals.thrownErrors),ReactSharedInternals.thrownErrors.length=0,reject(error)):reject(error)})}}}var returnValue$jscomp$0=result;popActScope(prevActQueue,prevActScopeDepth);prevActScopeDepth===0&&(flushActQueue(queue),queue.length!==0&&queueSeveralMicrotasks(function(){didAwaitActCall||didWarnNoAwaitAct||(didWarnNoAwaitAct=true,console.error("A component suspended inside an `act` scope, but the `act` call was not awaited. When testing React components that depend on asynchronous data, you must await the result:\n\nawait act(() => ...)"))}),ReactSharedInternals.actQueue=null);if(0<ReactSharedInternals.thrownErrors.length)throw callback=aggregateErrors(ReactSharedInternals.thrownErrors),ReactSharedInternals.thrownErrors.length=0,callback;return{then:function(resolve,reject){didAwaitActCall=true;prevActScopeDepth===0?(ReactSharedInternals.actQueue=queue,enqueueTask(function(){return recursivelyFlushAsyncActWork(returnValue$jscomp$0,resolve,reject)})):resolve(returnValue$jscomp$0)}}};exports.cache=function(fn){return function(){return fn.apply(null,arguments)}};exports.cacheSignal=function(){return null};exports.captureOwnerStack=function(){var getCurrentStack=ReactSharedInternals.getCurrentStack;return getCurrentStack===null?null:getCurrentStack()};exports.cloneElement=function(element,config,children){if(element===null||element===undefined)throw Error("The argument must be a React element, but you passed "+element+".");var props=assign({},element.props),key=element.key,owner=element._owner;if(config!=null){var JSCompiler_inline_result;a:{if(hasOwnProperty.call(config,"ref")&&(JSCompiler_inline_result=Object.getOwnPropertyDescriptor(config,"ref").get)&&JSCompiler_inline_result.isReactWarning){JSCompiler_inline_result=false;break a}JSCompiler_inline_result=config.ref!==undefined}JSCompiler_inline_result&&(owner=getOwner());hasValidKey(config)&&(checkKeyStringCoercion(config.key),key=""+config.key);for(propName in config)!hasOwnProperty.call(config,propName)||propName==="key"||propName==="__self"||propName==="__source"||propName==="ref"&&config.ref===undefined||(props[propName]=config[propName])}var propName=arguments.length-2;if(propName===1)props.children=children;else if(1<propName){JSCompiler_inline_result=Array(propName);for(var i=0;i<propName;i++)JSCompiler_inline_result[i]=arguments[i+2];props.children=JSCompiler_inline_result}props=ReactElement(element.type,key,props,owner,element._debugStack,element._debugTask);for(key=2;key<arguments.length;key++)validateChildKeys(arguments[key]);return props};exports.createContext=function(defaultValue){defaultValue={$$typeof:REACT_CONTEXT_TYPE,_currentValue:defaultValue,_currentValue2:defaultValue,_threadCount:0,Provider:null,Consumer:null};defaultValue.Provider=defaultValue;defaultValue.Consumer={$$typeof:REACT_CONSUMER_TYPE,_context:defaultValue};defaultValue._currentRenderer=null;defaultValue._currentRenderer2=null;return defaultValue};exports.createElement=function(type,config,children){for(var i=2;i<arguments.length;i++)validateChildKeys(arguments[i]);i={};var key=null;if(config!=null)for(propName in didWarnAboutOldJSXRuntime||!("__self"in config)||"key"in config||(didWarnAboutOldJSXRuntime=true,console.warn("Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform")),hasValidKey(config)&&(checkKeyStringCoercion(config.key),key=""+config.key),config)hasOwnProperty.call(config,propName)&&propName!=="key"&&propName!=="__self"&&propName!=="__source"&&(i[propName]=config[propName]);var childrenLength=arguments.length-2;if(childrenLength===1)i.children=children;else if(1<childrenLength){for(var childArray=Array(childrenLength),_i=0;_i<childrenLength;_i++)childArray[_i]=arguments[_i+2];Object.freeze&&Object.freeze(childArray);i.children=childArray}if(type&&type.defaultProps)for(propName in childrenLength=type.defaultProps,childrenLength)i[propName]===undefined&&(i[propName]=childrenLength[propName]);key&&defineKeyPropWarningGetter(i,typeof type==="function"?type.displayName||type.name||"Unknown":type);var propName=1e4>ReactSharedInternals.recentlyCreatedOwnerStacks++;return ReactElement(type,key,i,getOwner(),propName?Error("react-stack-top-frame"):unknownOwnerDebugStack,propName?createTask(getTaskName(type)):unknownOwnerDebugTask)};exports.createRef=function(){var refObject={current:null};Object.seal(refObject);return refObject};exports.forwardRef=function(render){render!=null&&render.$$typeof===REACT_MEMO_TYPE?console.error("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."):typeof render!=="function"?console.error("forwardRef requires a render function but was given %s.",render===null?"null":typeof render):render.length!==0&&render.length!==2&&console.error("forwardRef render functions accept exactly two parameters: props and ref. %s",render.length===1?"Did you forget to use the ref parameter?":"Any additional parameter will be undefined.");render!=null&&render.defaultProps!=null&&console.error("forwardRef render functions do not support defaultProps. Did you accidentally pass a React component?");var elementType={$$typeof:REACT_FORWARD_REF_TYPE,render},ownName;Object.defineProperty(elementType,"displayName",{enumerable:false,configurable:true,get:function(){return ownName},set:function(name){ownName=name;render.name||render.displayName||(Object.defineProperty(render,"name",{value:name}),render.displayName=name)}});return elementType};exports.isValidElement=isValidElement;exports.lazy=function(ctor){ctor={_status:-1,_result:ctor};var lazyType={$$typeof:REACT_LAZY_TYPE,_payload:ctor,_init:lazyInitializer},ioInfo={name:"lazy",start:-1,end:-1,value:null,owner:null,debugStack:Error("react-stack-top-frame"),debugTask:console.createTask?console.createTask("lazy()"):null};ctor._ioInfo=ioInfo;lazyType._debugInfo=[{awaited:ioInfo}];return lazyType};exports.memo=function(type,compare){type==null&&console.error("memo: The first argument must be a component. Instead received: %s",type===null?"null":typeof type);compare={$$typeof:REACT_MEMO_TYPE,type,compare:compare===undefined?null:compare};var ownName;Object.defineProperty(compare,"displayName",{enumerable:false,configurable:true,get:function(){return ownName},set:function(name){ownName=name;type.name||type.displayName||(Object.defineProperty(type,"name",{value:name}),type.displayName=name)}});return compare};exports.startTransition=function(scope){var prevTransition=ReactSharedInternals.T,currentTransition={};currentTransition._updatedFibers=new Set;ReactSharedInternals.T=currentTransition;try{var returnValue=scope(),onStartTransitionFinish=ReactSharedInternals.S;onStartTransitionFinish!==null&&onStartTransitionFinish(currentTransition,returnValue);typeof returnValue==="object"&&returnValue!==null&&typeof returnValue.then==="function"&&(ReactSharedInternals.asyncTransitions++,returnValue.then(releaseAsyncTransition,releaseAsyncTransition),returnValue.then(noop,reportGlobalError))}catch(error){reportGlobalError(error)}finally{prevTransition===null&&currentTransition._updatedFibers&&(scope=currentTransition._updatedFibers.size,currentTransition._updatedFibers.clear(),10<scope&&console.warn("Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table.")),prevTransition!==null&&currentTransition.types!==null&&(prevTransition.types!==null&&prevTransition.types!==currentTransition.types&&console.error("We expected inner Transitions to have transferred the outer types set and that you cannot add to the outer Transition while inside the inner.This is a bug in React."),prevTransition.types=currentTransition.types),ReactSharedInternals.T=prevTransition}};exports.unstable_useCacheRefresh=function(){return resolveDispatcher().useCacheRefresh()};exports.use=function(usable){return resolveDispatcher().use(usable)};exports.useActionState=function(action,initialState,permalink){return resolveDispatcher().useActionState(action,initialState,permalink)};exports.useCallback=function(callback,deps){return resolveDispatcher().useCallback(callback,deps)};exports.useContext=function(Context){var dispatcher=resolveDispatcher();Context.$$typeof===REACT_CONSUMER_TYPE&&console.error("Calling useContext(Context.Consumer) is not supported and will cause bugs. Did you mean to call useContext(Context) instead?");return dispatcher.useContext(Context)};exports.useDebugValue=function(value,formatterFn){return resolveDispatcher().useDebugValue(value,formatterFn)};exports.useDeferredValue=function(value,initialValue){return resolveDispatcher().useDeferredValue(value,initialValue)};exports.useEffect=function(create,deps){create==null&&console.warn("React Hook useEffect requires an effect callback. Did you forget to pass a callback to the hook?");return resolveDispatcher().useEffect(create,deps)};exports.useEffectEvent=function(callback){return resolveDispatcher().useEffectEvent(callback)};exports.useId=function(){return resolveDispatcher().useId()};exports.useImperativeHandle=function(ref,create,deps){return resolveDispatcher().useImperativeHandle(ref,create,deps)};exports.useInsertionEffect=function(create,deps){create==null&&console.warn("React Hook useInsertionEffect requires an effect callback. Did you forget to pass a callback to the hook?");return resolveDispatcher().useInsertionEffect(create,deps)};exports.useLayoutEffect=function(create,deps){create==null&&console.warn("React Hook useLayoutEffect requires an effect callback. Did you forget to pass a callback to the hook?");return resolveDispatcher().useLayoutEffect(create,deps)};exports.useMemo=function(create,deps){return resolveDispatcher().useMemo(create,deps)};exports.useOptimistic=function(passthrough,reducer){return resolveDispatcher().useOptimistic(passthrough,reducer)};exports.useReducer=function(reducer,initialArg,init){return resolveDispatcher().useReducer(reducer,initialArg,init)};exports.useRef=function(initialValue){return resolveDispatcher().useRef(initialValue)};exports.useState=function(initialState){return resolveDispatcher().useState(initialState)};exports.useSyncExternalStore=function(subscribe,getSnapshot,getServerSnapshot){return resolveDispatcher().useSyncExternalStore(subscribe,getSnapshot,getServerSnapshot)};exports.useTransition=function(){return resolveDispatcher().useTransition()};exports.version="19.2.6";typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!=="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop==="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())})()});var require_react=__commonJS((exports,module)=>{var react_development=__toESM(require_react_development());if(false){}else{module.exports=react_development}});function useAdmin(){const api=import_react.useContext(AdminHostApiContext);if(!api){throw new Error("useAdmin must be used inside an admin extension host.")}return api}function defineAdminExtension(extension){return extension}var import_react,AdminHostApiContext,AdminHostApiProvider;var init_dist=__esm(()=>{import_react=__toESM(require_react(),1);AdminHostApiContext=import_react.createContext(null);AdminHostApiContext.displayName="AdminHostApiContext";AdminHostApiProvider=AdminHostApiContext.Provider});var require_react_jsx_dev_runtime_development=__commonJS((exports)=>{var React=__toESM(require_react());(function(){function getComponentNameFromType(type){if(type==null)return null;if(typeof type==="function")return type.$$typeof===REACT_CLIENT_REFERENCE?null:type.displayName||type.name||null;if(typeof type==="string")return type;switch(type){case REACT_FRAGMENT_TYPE:return"Fragment";case REACT_PROFILER_TYPE:return"Profiler";case REACT_STRICT_MODE_TYPE:return"StrictMode";case REACT_SUSPENSE_TYPE:return"Suspense";case REACT_SUSPENSE_LIST_TYPE:return"SuspenseList";case REACT_ACTIVITY_TYPE:return"Activity"}if(typeof type==="object")switch(typeof type.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),type.$$typeof){case REACT_PORTAL_TYPE:return"Portal";case REACT_CONTEXT_TYPE:return type.displayName||"Context";case REACT_CONSUMER_TYPE:return(type._context.displayName||"Context")+".Consumer";case REACT_FORWARD_REF_TYPE:var innerType=type.render;type=type.displayName;type||(type=innerType.displayName||innerType.name||"",type=type!==""?"ForwardRef("+type+")":"ForwardRef");return type;case REACT_MEMO_TYPE:return innerType=type.displayName||null,innerType!==null?innerType:getComponentNameFromType(type.type)||"Memo";case REACT_LAZY_TYPE:innerType=type._payload;type=type._init;try{return getComponentNameFromType(type(innerType))}catch(x){}}return null}function testStringCoercion(value){return""+value}function checkKeyStringCoercion(value){try{testStringCoercion(value);var JSCompiler_inline_result=false}catch(e){JSCompiler_inline_result=true}if(JSCompiler_inline_result){JSCompiler_inline_result=console;var JSCompiler_temp_const=JSCompiler_inline_result.error;var JSCompiler_inline_result$jscomp$0=typeof Symbol==="function"&&Symbol.toStringTag&&value[Symbol.toStringTag]||value.constructor.name||"Object";JSCompiler_temp_const.call(JSCompiler_inline_result,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",JSCompiler_inline_result$jscomp$0);return testStringCoercion(value)}}function getTaskName(type){if(type===REACT_FRAGMENT_TYPE)return"<>";if(typeof type==="object"&&type!==null&&type.$$typeof===REACT_LAZY_TYPE)return"<...>";try{var name=getComponentNameFromType(type);return name?"<"+name+">":"<...>"}catch(x){return"<...>"}}function getOwner(){var dispatcher=ReactSharedInternals.A;return dispatcher===null?null:dispatcher.getOwner()}function UnknownOwner(){return Error("react-stack-top-frame")}function hasValidKey(config){if(hasOwnProperty.call(config,"key")){var getter=Object.getOwnPropertyDescriptor(config,"key").get;if(getter&&getter.isReactWarning)return false}return config.key!==undefined}function defineKeyPropWarningGetter(props,displayName){function warnAboutAccessingKey(){specialPropKeyWarningShown||(specialPropKeyWarningShown=true,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",displayName))}warnAboutAccessingKey.isReactWarning=true;Object.defineProperty(props,"key",{get:warnAboutAccessingKey,configurable:true})}function elementRefGetterWithDeprecationWarning(){var componentName=getComponentNameFromType(this.type);didWarnAboutElementRef[componentName]||(didWarnAboutElementRef[componentName]=true,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."));componentName=this.props.ref;return componentName!==undefined?componentName:null}function ReactElement(type,key,props,owner,debugStack,debugTask){var refProp=props.ref;type={$$typeof:REACT_ELEMENT_TYPE,type,key,props,_owner:owner};(refProp!==undefined?refProp:null)!==null?Object.defineProperty(type,"ref",{enumerable:false,get:elementRefGetterWithDeprecationWarning}):Object.defineProperty(type,"ref",{enumerable:false,value:null});type._store={};Object.defineProperty(type._store,"validated",{configurable:false,enumerable:false,writable:true,value:0});Object.defineProperty(type,"_debugInfo",{configurable:false,enumerable:false,writable:true,value:null});Object.defineProperty(type,"_debugStack",{configurable:false,enumerable:false,writable:true,value:debugStack});Object.defineProperty(type,"_debugTask",{configurable:false,enumerable:false,writable:true,value:debugTask});Object.freeze&&(Object.freeze(type.props),Object.freeze(type));return type}function jsxDEVImpl(type,config,maybeKey,isStaticChildren,debugStack,debugTask){var children=config.children;if(children!==undefined)if(isStaticChildren)if(isArrayImpl(children)){for(isStaticChildren=0;isStaticChildren<children.length;isStaticChildren++)validateChildKeys(children[isStaticChildren]);Object.freeze&&Object.freeze(children)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else validateChildKeys(children);if(hasOwnProperty.call(config,"key")){children=getComponentNameFromType(type);var keys=Object.keys(config).filter(function(k){return k!=="key"});isStaticChildren=0<keys.length?"{key: someKey, "+keys.join(": ..., ")+": ...}":"{key: someKey}";didWarnAboutKeySpread[children+isStaticChildren]||(keys=0<keys.length?"{"+keys.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
14
+ let props = %s;
15
+ <%s {...props} />
16
+ React keys must be passed directly to JSX without using spread:
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??"текущий магазин",[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,docs:input.docs,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 AI_BOT_EXTENSION_NAME="ai-bot";var AI_BOT_VERSION="0.0.10-alpha.9";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=["You are the Brand Map AI Bot harness.","You decide which exact extension commands should run for the user's task.","Return only JSON. Do not return shell commands. Do not invent commands.","Every command must use this shape:",'{"commands":[{"id":"short-id","command":"product.list","args":[{"limit":5}],"reason":"why this is needed"}]}',"Use an empty commands array when no safe action is needed.","Available commands:",COMMAND_CATALOG_TEXT].join(`
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 record=await storage.db.get(LAST_RUN_KEY);return{run:record?.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 toExtensionJson(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 plan must be a JSON object with a commands array.")}return input.commands.slice(0,maxCommands).map((entry,index)=>{if(!isRecord(entry)||typeof entry.command!=="string"){throw new Error(`AI plan command at index ${index} must include 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("AI Bot workflow input requires task.")}return{allowMutations:settings.allowMutations&&readBooleanField(value,"allowMutations",false),allowedCommands:readAllowedCommands(value.allowedCommands),context:toExtensionJson(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=toExtensionJson(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 JSON.parse(trimmed)}catch{const objectMatch=/\{[\s\S]*\}/.exec(trimmed);if(objectMatch){try{return JSON.parse(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=toExtensionJson(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 toExtensionJson(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)=>toExtensionJson(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]=toExtensionJson(entry,depth+1)}}return output}return String(value)}function readJsonArray(value){if(!Array.isArray(value)){return[]}return value.map((entry)=>toExtensionJson(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(`Command argument ${index} must be a non-empty string.`)}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(`Command argument ${index} must be a number.`)}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("AI API Base URL must use https, except localhost development URLs.")}}function truncateText(value,maxLength){if(value.length<=maxLength){return value}return`${value.slice(0,maxLength)}
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 Provider",
6
+ "label": "AI-провайдер",
7
7
  "options": [
8
8
  {
9
9
  "label": "OpenAI",
10
10
  "value": "openai"
11
11
  },
12
12
  {
13
- "label": "OpenAI Compatible",
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": "AI Provider API Token",
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": "AI API Base URL",
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": "Model",
39
+ "label": "Модель",
40
40
  "type": "string"
41
41
  },
42
42
  {
43
43
  "defaultValue": 8,
44
44
  "key": "maxCommands",
45
- "label": "Max Commands",
45
+ "label": "Максимум команд",
46
46
  "type": "number"
47
47
  },
48
48
  {
49
49
  "defaultValue": false,
50
- "description": "Allows the harness to execute write commands when workflow input also allows it.",
50
+ "description": "Разрешает исполнителю выполнять команды записи, если входные данные процесса тоже это разрешают.",
51
51
  "key": "allowMutations",
52
- "label": "Allow Mutations",
52
+ "label": "Разрешить изменения",
53
53
  "type": "boolean"
54
54
  },
55
55
  {
56
56
  "defaultValue": false,
57
- "description": "Runs read commands but skips write commands.",
57
+ "description": "Выполняет команды чтения, но пропускает команды записи.",
58
58
  "key": "dryRun",
59
- "label": "Dry Run",
59
+ "label": "Пробный запуск",
60
60
  "type": "boolean"
61
61
  },
62
62
  {
63
- "defaultValue": "You are the Brand Map AI Bot harness.\n\nYou decide which exact extension commands should run for the user's task.\n\nReturn only JSON. Do not return shell commands. Do not invent commands.\n\nEvery command must use this shape:\n\n{\"commands\":[{\"id\":\"short-id\",\"command\":\"product.list\",\"args\":[{\"limit\":5}],\"reason\":\"why this is needed\"}]}\n\nUse an empty commands array when no safe action is needed.\n\nAvailable commands:\n\n- product.list (read): List products with an optional read query.\n- product.retrieve (read): Retrieve one product by id.\n- product.retrieveVariantByExternalSku (read): Retrieve a variant by external SKU.\n- product.listVariants (read): List variants for a product id.\n- product.listCategories (read): List product categories.\n- price.listPriceList (read): List price lists.\n- price.listPriceListPrice (read): List price list prices.\n- stockLocation.listStockLocation (read): List stock locations.\n- stockLocation.retrieveStockLocation (read): Retrieve one stock location by id.\n- notification.listNotifications (read): List notifications.\n- notification.retrieveNotification (read): Retrieve one notification by id.\n- file.list (read): List files.\n- file.retrieve (read): Retrieve file metadata by id.\n- storage.db.get (read): Read one extension storage record by key.\n- storage.db.list (read): List extension storage records.\n- storage.cache.get (read): Read one extension cache value by key.\n- product.create (mutation): Create one or more products.\n- product.update (mutation): Update one or more products.\n- product.createCategory (mutation): Create a product category.\n- product.updateCategory (mutation): Update a product category.\n- product.createVariant (mutation): Create a product variant.\n- product.updateVariant (mutation): Update a product variant.\n- product.addImage (mutation): Add an image URL to a product.\n- product.upsertOption (mutation): Create or update a product option.\n- product.upsertOptionValue (mutation): Create or update a product option value.\n- product.linkVariantOptionValue (mutation): Link a variant to an option value.\n- product.upsertAttribute (mutation): Create or update a product attribute.\n- product.upsertAttributeValue (mutation): Create or update a product attribute value.\n- price.createPriceList (mutation): Create one or more price lists.\n- price.updatePriceList (mutation): Update one or more price lists.\n- price.createPriceListPrice (mutation): Create one or more price list prices.\n- price.updatePriceListPrice (mutation): Update one or more price list prices.\n- price.setBasePrice (mutation): Set a variant base price.\n- stockLocation.createStockLocation (mutation): Create a stock location.\n- stockLocation.updateStockLocation (mutation): Update a stock location.\n- stockLocation.upsertStockLocation (mutation): Create or update a stock location.\n- inventory.enrollVariantInStore (mutation): Enroll a variant in store inventory.\n- inventory.syncStockLevel (mutation): Sync a stock level.\n- notification.createNotifications (mutation): Create one or more notifications.\n- file.create (mutation): Create a file from string content.\n- file.delete (mutation): Delete one or more files by id.\n- storage.db.set (mutation): Write an extension storage record.\n- storage.db.delete (mutation): Delete extension storage records.\n- storage.cache.set (mutation): Write an extension cache value.\n- storage.cache.delete (mutation): Delete extension cache values.",
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": "System Prompt",
65
+ "label": "Системный промпт",
66
66
  "type": "string"
67
67
  }
68
68
  ],
69
- "description": "Runs a small AI harness as a Temporal workflow over approved Brand Map extension commands.",
69
+ "description": "Запускает небольшой AI-исполнитель как Temporal-процесс поверх разрешенных команд расширения Brand Map.",
70
70
  "developerUrl": "https://brand-map.ru",
71
- "displayName": "AI Bot",
71
+ "displayName": "AI-бот",
72
72
  "eventHandlers": [],
73
73
  "hooks": [],
74
74
  "jobs": [],
75
75
  "logo": {
76
- "alt": "AI Bot icon",
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.10",
134
+ "version": "0.0.10-alpha.15",
135
135
  "workflows": [
136
136
  {
137
137
  "name": "run-harness"
package/docs/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # AI-бот
2
+
3
+ Расширение AI-бота запускает одобренный исполнитель команд как Temporal-процесс. Оно отправляет пользовательскую задачу и контекст настроенному AI-провайдеру, выполняет только команды из каталога команд расширения и сохраняет последний запуск в хранилище расширения.
4
+
5
+ ## Что Делает
6
+
7
+ - Вызывает настроенного AI-провайдера.
8
+ - Требует, чтобы модель возвращала JSON-планы команд.
9
+ - Выполняет одобренные операции чтения и записи Brand Map через runtime расширений.
10
+ - Поддерживает пробный режим только для чтения.
11
+ - Требует разрешения мутаций и в конфигурации установки, и во входных данных workflow перед выполнением команд записи.
12
+
13
+ ## Конфигурация
14
+
15
+ - `aiProvider`: режим AI-провайдера.
16
+ - `apiToken`: API-токен провайдера.
17
+ - `apiBaseUrl`: базовый URL API провайдера.
18
+ - `model`: имя модели.
19
+ - `maxCommands`: максимальное число команд за запуск.
20
+ - `allowMutations`: переключатель разрешения записи на уровне установки.
21
+ - `dryRun`: пропускает команды записи.
22
+ - `systemPrompt`: промпт планирования команд.
23
+
24
+ ## Входные Данные Workflow
25
+
26
+ ```json
27
+ {
28
+ "task": "Проверь первые пять товаров и кратко опиши, где нет миниатюр.",
29
+ "context": {
30
+ "storeId": "store_1"
31
+ },
32
+ "dryRun": false,
33
+ "allowMutations": false,
34
+ "maxCommands": 5
35
+ }
36
+ ```
37
+
38
+ ## Модель Безопасности
39
+
40
+ Расширение не запускает shell-команды. Оно выполняет только команды, объявленные в каталоге команд, а команды записи требуют явных флагов мутаций.
@@ -0,0 +1,3 @@
1
+ # Сводка
2
+
3
+ - [Обзор](./README.md)
package/package.json CHANGED
@@ -1,25 +1,34 @@
1
1
  {
2
2
  "name": "@brand-map/ai-bot-extension",
3
- "version": "0.0.10-alpha.10",
3
+ "version": "0.0.10-alpha.15",
4
+ "license": "UNLICENSED",
4
5
  "type": "module",
5
6
  "exports": {
6
7
  ".": "./dist/extension.js",
8
+ "./admin": "./dist/admin/index.js",
7
9
  "./entrypoint": "./dist/extension.js",
8
10
  "./manifest": "./dist/extension.manifest.json",
9
11
  "./package.json": "./package.json"
10
12
  },
11
13
  "files": [
12
- "dist"
14
+ "dist",
15
+ "docs",
16
+ "README.md"
13
17
  ],
14
18
  "publishConfig": {
15
19
  "registry": "https://registry.npmjs.org"
16
20
  },
17
21
  "dependencies": {
22
+ "@brand-map/admin-extension-sdk": "0.0.10-alpha.7",
18
23
  "@brand-map/extension-sdk": "0.0.10-alpha.7"
19
24
  },
20
25
  "brandMap": {
21
26
  "extension": {
27
+ "admin": "./admin",
22
28
  "entrypoint": "./entrypoint",
29
+ "manifest": "./manifest",
30
+ "name": "ai-bot",
31
+ "official": true,
23
32
  "runtimeGrants": [
24
33
  "extension-storage:read",
25
34
  "extension-storage:write",
@@ -63,9 +72,6 @@
63
72
  "operation:stockLocation.updateStockLocation",
64
73
  "operation:stockLocation.upsertStockLocation"
65
74
  ],
66
- "manifest": "./manifest",
67
- "name": "ai-bot",
68
- "official": true,
69
75
  "source": "bundled"
70
76
  }
71
77
  }