@brand-map/ai-bot-extension 0.0.10-alpha.10 → 0.0.10-alpha.12
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 +35 -0
- package/dist/admin/index.js +18 -0
- package/dist/extension.js +3 -3
- package/dist/extension.manifest.json +1 -1
- package/docs/README.md +40 -0
- package/docs/SUMMARY.md +3 -0
- package/package.json +11 -5
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# AI Bot Extension
|
|
2
|
+
|
|
3
|
+
First-party Brand Map extension that runs a small AI harness as the `run-harness` Temporal workflow.
|
|
4
|
+
|
|
5
|
+
The workflow:
|
|
6
|
+
|
|
7
|
+
1. Sends the user task, provided context, and harness system prompt to the configured AI provider.
|
|
8
|
+
2. Expects exact JSON commands from the model.
|
|
9
|
+
3. Executes supported Brand Map extension commands and storage commands.
|
|
10
|
+
4. Sends the accumulated command effects back to the model for a final JSON summary.
|
|
11
|
+
5. Stores the latest run in extension storage and returns the summary payload to the caller.
|
|
12
|
+
|
|
13
|
+
Mutation commands require both installation config `allowMutations: true` and workflow input
|
|
14
|
+
`allowMutations: true`. `dryRun: true` runs reads but skips writes.
|
|
15
|
+
|
|
16
|
+
Example workflow input:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"task": "Check the first five products and summarize missing thumbnails.",
|
|
21
|
+
"context": {
|
|
22
|
+
"storeId": "store_1"
|
|
23
|
+
},
|
|
24
|
+
"dryRun": false,
|
|
25
|
+
"allowMutations": false,
|
|
26
|
+
"maxCommands": 5
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The extension does not run shell commands. It executes the explicit command catalog declared in the
|
|
31
|
+
system prompt through the public Brand Map extension runtime APIs.
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
UNLICENSED. This package is proprietary Brand Map software published for authorized Brand Map extension runtime use. No open-source license is granted.
|
|
@@ -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&¤tTransition._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&¤tTransition.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??"current store",[props.storeId]);function sendMessage(event){event.preventDefault();const text=draft.trim();if(!text){return}setDraft("");admin.toast.info("AI Bot demo reply generated.");setMessages((current)=>[...current,{id:`user-${Date.now()}`,role:"user",text},{id:`assistant-${Date.now()}`,role:"assistant",text:`Demo mode for ${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:"Message AI Bot",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:"Send"},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:"Ask me what to inspect in this store."}]});init_dist();var admin_default=defineAdminExtension({id:"ai-bot",name:"AI Bot",version:"0.0.10-alpha.12",description:"Demo chat widget for the AI Bot extension.",permissions:[],widgets:[{component:()=>Promise.resolve().then(() => (init_chat_widget(),exports_chat_widget)),icon:"message-circle",id:"chat",label:"AI Bot",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(`
|
|
2
|
+
function extension(input){return{callbacks:input.callbacks??[],eventHandlers:input.eventHandlers??[],hooks:input.hooks??[],jobs:input.jobs??[],manifest:{callbacks:(input.callbacks??[]).map((handler)=>({action:handler.action,name:handler.name})),config:input.config,description:input.description,developerUrl:input.developerUrl,displayName:input.displayName,eventHandlers:(input.eventHandlers??[]).map((handler)=>({event:handler.event,name:handler.name})),hooks:(input.hooks??[]).map((hook)=>({event:hook.event,name:hook.name})),jobs:(input.jobs??[]).map((job)=>({name:job.name,overlap:job.overlap,schedule:job.schedule,timezone:job.timezone})),logo:input.logo,name:input.name,permissions:input.permissions??[],publisher:input.publisher,version:input.version,workflows:(input.workflows??[]).map((workflow)=>({name:workflow.name}))},start:input.start,stop:input.stop,workflows:input.workflows??[]}}function callback(name,options,handler){const resolvedHandler=typeof options==="function"?options:handler;if(!resolvedHandler){throw new Error(`Extension callback "${name}" requires a handler`)}return{action:typeof options==="function"?name:options.action??name,handler:resolvedHandler,name}}function temporalWorkflow(name,handler){return{handler,name}}var store$4;var DEFAULT_CONFIG={lang:undefined,message:undefined,abortEarly:undefined,abortPipeEarly:undefined};function getGlobalConfig(config$1){if(!config$1&&!store$4)return DEFAULT_CONFIG;return{lang:config$1?.lang??store$4?.lang,message:config$1?.message,abortEarly:config$1?.abortEarly??store$4?.abortEarly,abortPipeEarly:config$1?.abortPipeEarly??store$4?.abortPipeEarly}}var store$3;function getGlobalMessage(lang){return store$3?.get(lang)}var store$2;function getSchemaMessage(lang){return store$2?.get(lang)}var store$1;function getSpecificMessage(reference,lang){return store$1?.get(reference)?.get(lang)}function _stringify(input){const type=typeof input;if(type==="string")return`"${input}"`;if(type==="number"||type==="bigint"||type==="boolean")return`${input}`;if(type==="object"||type==="function")return(input&&Object.getPrototypeOf(input)?.constructor?.name)??"null";return type}function _addIssue(context,label,dataset,config$1,other){const input=other&&"input"in other?other.input:dataset.value;const expected=other?.expected??context.expects??null;const received=other?.received??_stringify(input);const issue={kind:context.kind,type:context.type,input,expected,received,message:`Invalid ${label}: ${expected?`Expected ${expected} but r`:"R"}eceived ${received}`,requirement:context.requirement,path:other?.path,issues:other?.issues,lang:config$1.lang,abortEarly:config$1.abortEarly,abortPipeEarly:config$1.abortPipeEarly};const isSchema=context.kind==="schema";const message$1=other?.message??context.message??getSpecificMessage(context.reference,issue.lang)??(isSchema?getSchemaMessage(issue.lang):null)??config$1.message??getGlobalMessage(issue.lang);if(message$1!==undefined)issue.message=typeof message$1==="function"?message$1(issue):message$1;if(isSchema)dataset.typed=false;if(dataset.issues)dataset.issues.push(issue);else dataset.issues=[issue]}var _standardCache=new WeakMap;function _getStandardProps(context){let cached=_standardCache.get(context);if(!cached){cached={version:1,vendor:"valibot",validate(value$1){return context["~run"]({value:value$1},getGlobalConfig())}};_standardCache.set(context,cached)}return cached}function _isValidObjectKey(object$1,key){return Object.prototype.hasOwnProperty.call(object$1,key)&&key!=="__proto__"&&key!=="prototype"&&key!=="constructor"}function _joinExpects(values$1,separator){const list=[...new Set(values$1)];if(list.length>1)return`(${list.join(` ${separator} `)})`;return list[0]??"never"}var ValiError=class extends Error{constructor(issues){super(issues[0].message);this.name="ValiError";this.issues=issues}};function finite(message$1){return{kind:"validation",type:"finite",reference:finite,async:false,expects:null,requirement:Number.isFinite,message:message$1,"~run"(dataset,config$1){if(dataset.typed&&!this.requirement(dataset.value))_addIssue(this,"finite",dataset,config$1);return dataset}}}function minLength(requirement,message$1){return{kind:"validation",type:"min_length",reference:minLength,async:false,expects:`>=${requirement}`,requirement,message:message$1,"~run"(dataset,config$1){if(dataset.typed&&dataset.value.length<this.requirement)_addIssue(this,"length",dataset,config$1,{received:`${dataset.value.length}`});return dataset}}}function parseJson(config$1,message$1){return{kind:"transformation",type:"parse_json",reference:parseJson,config:config$1,message:message$1,async:false,"~run"(dataset,config$2){try{dataset.value=JSON.parse(dataset.value,this.config?.reviver)}catch(error){if(error instanceof Error){_addIssue(this,"JSON",dataset,config$2,{received:`"${error.message}"`});dataset.typed=false}else throw error}return dataset}}}function rawTransform(action){return{kind:"transformation",type:"raw_transform",reference:rawTransform,async:false,"~run"(dataset,config$1){const output=action({dataset,config:config$1,addIssue:(info)=>_addIssue(this,info?.label??"input",dataset,config$1,info),NEVER:null});if(dataset.issues)dataset.typed=false;else dataset.value=output;return dataset}}}function transform(operation){return{kind:"transformation",type:"transform",reference:transform,async:false,operation,"~run"(dataset){dataset.value=this.operation(dataset.value);return dataset}}}function trim(){return{kind:"transformation",type:"trim",reference:trim,async:false,"~run"(dataset){dataset.value=dataset.value.trim();return dataset}}}function getFallback(schema,dataset,config$1){return typeof schema.fallback==="function"?schema.fallback(dataset,config$1):schema.fallback}function getDefault(schema,dataset,config$1){return typeof schema.default==="function"?schema.default(dataset,config$1):schema.default}function array(item,message$1){return{kind:"schema",type:"array",reference:array,expects:"Array",async:false,item,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(Array.isArray(input)){dataset.typed=true;dataset.value=[];for(let key=0;key<input.length;key++){const value$1=input[key];const itemDataset=this.item["~run"]({value:value$1},config$1);if(itemDataset.issues){const pathItem={type:"array",origin:"value",input,key,value:value$1};for(const issue of itemDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=itemDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!itemDataset.typed)dataset.typed=false;dataset.value.push(itemDataset.value)}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function boolean(message$1){return{kind:"schema",type:"boolean",reference:boolean,expects:"boolean",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="boolean")dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function custom(check$1,message$1){return{kind:"schema",type:"custom",reference:custom,expects:"unknown",async:false,check:check$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(this.check(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function nullable(wrapped,default_){return{kind:"schema",type:"nullable",reference:nullable,expects:`(${wrapped.expects} | null)`,async:false,wrapped,default:default_,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(dataset.value===null){if(this.default!==undefined)dataset.value=getDefault(this,dataset,config$1);if(dataset.value===null){dataset.typed=true;return dataset}}return this.wrapped["~run"](dataset,config$1)}}}function number(message$1){return{kind:"schema",type:"number",reference:number,expects:"number",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="number"&&!isNaN(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function object(entries$1,message$1){return{kind:"schema",type:"object",reference:object,expects:"Object",async:false,entries:entries$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const key in this.entries){const valueSchema=this.entries[key];if(key in input||(valueSchema.type==="exact_optional"||valueSchema.type==="optional"||valueSchema.type==="nullish")&&valueSchema.default!==undefined){const value$1=key in input?input[key]:getDefault(valueSchema);const valueDataset=valueSchema["~run"]({value:value$1},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key,value:value$1};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!valueDataset.typed)dataset.typed=false;dataset.value[key]=valueDataset.value}else if(valueSchema.fallback!==undefined)dataset.value[key]=getFallback(valueSchema);else if(valueSchema.type!=="exact_optional"&&valueSchema.type!=="optional"&&valueSchema.type!=="nullish"){_addIssue(this,"key",dataset,config$1,{input:undefined,expected:`"${key}"`,path:[{type:"object",origin:"key",input,key,value:input[key]}]});if(config$1.abortEarly)break}}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function optional(wrapped,default_){return{kind:"schema",type:"optional",reference:optional,expects:`(${wrapped.expects} | undefined)`,async:false,wrapped,default:default_,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(dataset.value===undefined){if(this.default!==undefined)dataset.value=getDefault(this,dataset,config$1);if(dataset.value===undefined){dataset.typed=true;return dataset}}return this.wrapped["~run"](dataset,config$1)}}}function picklist(options,message$1){return{kind:"schema",type:"picklist",reference:picklist,expects:_joinExpects(options.map(_stringify),"|"),async:false,options,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(this.options.includes(dataset.value))dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function record(key,value$1,message$1){return{kind:"schema",type:"record",reference:record,expects:"Object",async:false,key,value:value$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const entryKey in input)if(_isValidObjectKey(input,entryKey)){const entryValue=input[entryKey];const keyDataset=this.key["~run"]({value:entryKey},config$1);if(keyDataset.issues){const pathItem={type:"object",origin:"key",input,key:entryKey,value:entryValue};for(const issue of keyDataset.issues){issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=keyDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}const valueDataset=this.value["~run"]({value:entryValue},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key:entryKey,value:entryValue};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!keyDataset.typed||!valueDataset.typed)dataset.typed=false;if(keyDataset.typed)dataset.value[keyDataset.value]=valueDataset.value}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function strictObject(entries$1,message$1){return{kind:"schema",type:"strict_object",reference:strictObject,expects:"Object",async:false,entries:entries$1,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){const input=dataset.value;if(input&&typeof input==="object"){dataset.typed=true;dataset.value={};for(const key in this.entries){const valueSchema=this.entries[key];if(key in input||(valueSchema.type==="exact_optional"||valueSchema.type==="optional"||valueSchema.type==="nullish")&&valueSchema.default!==undefined){const value$1=key in input?input[key]:getDefault(valueSchema);const valueDataset=valueSchema["~run"]({value:value$1},config$1);if(valueDataset.issues){const pathItem={type:"object",origin:"value",input,key,value:value$1};for(const issue of valueDataset.issues){if(issue.path)issue.path.unshift(pathItem);else issue.path=[pathItem];dataset.issues?.push(issue)}if(!dataset.issues)dataset.issues=valueDataset.issues;if(config$1.abortEarly){dataset.typed=false;break}}if(!valueDataset.typed)dataset.typed=false;dataset.value[key]=valueDataset.value}else if(valueSchema.fallback!==undefined)dataset.value[key]=getFallback(valueSchema);else if(valueSchema.type!=="exact_optional"&&valueSchema.type!=="optional"&&valueSchema.type!=="nullish"){_addIssue(this,"key",dataset,config$1,{input:undefined,expected:`"${key}"`,path:[{type:"object",origin:"key",input,key,value:input[key]}]});if(config$1.abortEarly)break}}if(!dataset.issues||!config$1.abortEarly){for(const key in input)if(!(key in this.entries)){_addIssue(this,"key",dataset,config$1,{input:key,expected:"never",path:[{type:"object",origin:"key",input,key,value:input[key]}]});break}}}else _addIssue(this,"type",dataset,config$1);return dataset}}}function string(message$1){return{kind:"schema",type:"string",reference:string,expects:"string",async:false,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){if(typeof dataset.value==="string")dataset.typed=true;else _addIssue(this,"type",dataset,config$1);return dataset}}}function _subIssues(datasets){let issues;if(datasets)for(const dataset of datasets)if(issues)for(const issue of dataset.issues)issues.push(issue);else issues=dataset.issues;return issues}function union(options,message$1){return{kind:"schema",type:"union",reference:union,expects:_joinExpects(options.map((option)=>option.expects),"|"),async:false,options,message:message$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){let validDataset;let typedDatasets;let untypedDatasets;for(const schema of this.options){const optionDataset=schema["~run"]({value:dataset.value},config$1);if(optionDataset.typed)if(optionDataset.issues)if(typedDatasets)typedDatasets.push(optionDataset);else typedDatasets=[optionDataset];else{validDataset=optionDataset;break}else if(untypedDatasets)untypedDatasets.push(optionDataset);else untypedDatasets=[optionDataset]}if(validDataset)return validDataset;if(typedDatasets){if(typedDatasets.length===1)return typedDatasets[0];_addIssue(this,"type",dataset,config$1,{issues:_subIssues(typedDatasets)});dataset.typed=true}else if(untypedDatasets?.length===1)return untypedDatasets[0];else _addIssue(this,"type",dataset,config$1,{issues:_subIssues(untypedDatasets)});return dataset}}}function unknown(){return{kind:"schema",type:"unknown",reference:unknown,expects:"unknown",async:false,get "~standard"(){return _getStandardProps(this)},"~run"(dataset){dataset.typed=true;return dataset}}}function parse(schema,input,config$1){const dataset=schema["~run"]({value:input},getGlobalConfig(config$1));if(dataset.issues)throw new ValiError(dataset.issues);return dataset.value}function partial(schema,keys){const entries$1={};for(const key in schema.entries)entries$1[key]=!keys||keys.includes(key)?optional(schema.entries[key]):schema.entries[key];return{...schema,entries:entries$1,get "~standard"(){return _getStandardProps(this)}}}function pipe(...pipe$1){return{...pipe$1[0],pipe:pipe$1,get "~standard"(){return _getStandardProps(this)},"~run"(dataset,config$1){for(const item of pipe$1)if(item.kind!=="metadata"){if(dataset.issues&&(item.kind==="schema"||item.kind==="transformation")){dataset.typed=false;break}if(!dataset.issues||!config$1.abortEarly&&!config$1.abortPipeEarly)dataset=item["~run"](dataset,config$1)}return dataset}}}var ExtensionJsonSchema=custom(isExtensionJson,"Expected JSON-compatible value");var ExtensionSerializableValueSchema=custom(isExtensionSerializableValue,"Expected extension RPC-serializable value");var ExtensionOperationArgumentsSchema=array(ExtensionSerializableValueSchema);var OptionalExtensionJsonSchema=optional(nullable(ExtensionJsonSchema));var FiniteNumberSchema=pipe(number(),finite());var NonEmptyTrimmedStringSchema=pipe(string(),trim(),minLength(1));var StringFromScalarSchema=pipe(union([string(),FiniteNumberSchema,boolean()]),transform((value)=>String(value)));var NonEmptyStringFromScalarSchema=pipe(StringFromScalarSchema,trim(),minLength(1));var ExtensionJsonTransformSchema=pipe(unknown(),rawTransform((context)=>{try{return toExtensionJson(context.dataset.value)}catch(error){context.addIssue({message:error instanceof Error?error.message:"Expected JSON-compatible value"});return context.NEVER}}));var JsonTextSchema=pipe(string(),parseJson(),ExtensionJsonTransformSchema);var JsonRecordSchema=pipe(ExtensionJsonTransformSchema,rawTransform((context)=>{const value=context.dataset.value;if(!isPlainRecord(value)){context.addIssue({message:"Expected JSON object"});return context.NEVER}return value}));var JsonArraySchema=pipe(ExtensionJsonTransformSchema,rawTransform((context)=>{const value=context.dataset.value;if(!Array.isArray(value)){context.addIssue({message:"Expected JSON array"});return context.NEVER}return value}));var ExtensionReadQuerySchema=strictObject({joins:optional(ExtensionJsonSchema),limit:optional(FiniteNumberSchema),offset:optional(FiniteNumberSchema),order:optional(ExtensionJsonSchema),where:optional(ExtensionJsonSchema)});var ExtensionPermissionSchema=pipe(string(),minLength(1));var ExtensionConfigOptionSchema=object({label:pipe(string(),minLength(1)),value:pipe(string(),minLength(1))});var ExtensionConfigFieldSchema=object({defaultValue:optional(unknown()),description:optional(string()),key:pipe(string(),minLength(1)),label:pipe(string(),minLength(1)),options:optional(array(ExtensionConfigOptionSchema)),required:optional(boolean()),secret:optional(boolean()),type:picklist(["boolean","multi-select","number","select","string","url"])});var ExtensionLogoSchema=object({alt:optional(string()),src:pipe(string(),minLength(1))});var ExtensionHttpMethodSchema=picklist(["DELETE","GET","PATCH","POST","PUT"]);var ExtensionInvocationKindSchema=picklist(["callback","event","job","hook","workflow"]);var ExtensionCallbackSchema=object({action:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionEventHandlerSchema=object({event:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionJobOverlapPolicySchema=picklist(["ALLOW_ALL","BUFFER_ALL","BUFFER_ONE","CANCEL_OTHER","SKIP","TERMINATE_OTHER"]);var ExtensionJobSchema=object({name:pipe(string(),minLength(1)),overlap:optional(ExtensionJobOverlapPolicySchema),schedule:pipe(string(),minLength(1)),timezone:optional(string())});var ExtensionLifecycleHookSchema=object({event:pipe(string(),minLength(1)),name:pipe(string(),minLength(1))});var ExtensionTemporalWorkflowSchema=object({name:pipe(string(),minLength(1))});var ExtensionManifestSchema=object({config:optional(array(ExtensionConfigFieldSchema)),description:optional(string()),developerUrl:optional(pipe(string(),minLength(1))),displayName:optional(pipe(string(),minLength(1))),eventHandlers:optional(array(ExtensionEventHandlerSchema)),hooks:optional(array(ExtensionLifecycleHookSchema)),jobs:optional(array(ExtensionJobSchema)),logo:optional(ExtensionLogoSchema),name:pipe(string(),minLength(1)),permissions:optional(array(ExtensionPermissionSchema)),publisher:optional(pipe(string(),minLength(1))),callbacks:optional(array(ExtensionCallbackSchema)),version:pipe(string(),minLength(1)),workflows:optional(array(ExtensionTemporalWorkflowSchema))});var ExtensionCategoryCreateInputSchema=strictObject({metadata:OptionalExtensionJsonSchema,name:string(),parentCategoryId:optional(nullable(string())),slug:string(),status:optional(string())});var ExtensionCategoryUpdateInputSchema=partial(ExtensionCategoryCreateInputSchema);var ExtensionCategorySchema=object({id:string(),metadata:OptionalExtensionJsonSchema,name:optional(string()),parentCategoryId:optional(nullable(string())),slug:string(),status:optional(string())});var ExtensionProductImageSchema=object({rank:optional(nullable(FiniteNumberSchema)),url:string()});var ExtensionProductOptionInputSchema=strictObject({rank:optional(nullable(FiniteNumberSchema)),title:string()});var ExtensionProductOptionSchema=object({id:string(),productId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),title:string()});var ExtensionProductOptionValueInputSchema=strictObject({colorHex:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),value:string()});var ExtensionProductOptionValueSchema=object({colorHex:optional(nullable(string())),id:string(),optionId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),value:string()});var ExtensionProductVariantOptionValueSchema=object({id:string(),optionId:optional(string()),optionValueId:optional(string()),productId:optional(string()),variantId:optional(string())});var ExtensionProductAttributeInputSchema=strictObject({isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:string(),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"])))});var ExtensionProductAttributeSchema=object({id:string(),isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:string(),productId:optional(string()),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"])))});var ExtensionProductAttributeValueInputSchema=strictObject({attributeId:string(),productId:optional(nullable(string())),valueBoolean:optional(nullable(boolean())),valueNumber:optional(nullable(union([FiniteNumberSchema,string()]))),valueText:optional(nullable(string())),variantId:optional(nullable(string()))});var ExtensionProductAttributeValueSchema=object({attributeId:optional(string()),id:string(),productId:optional(nullable(string())),valueBoolean:optional(nullable(boolean())),valueNumber:optional(nullable(union([FiniteNumberSchema,string()]))),valueText:optional(nullable(string())),variantId:optional(nullable(string()))});var ExtensionCatalogBatchImageSchema=strictObject({rank:optional(nullable(FiniteNumberSchema)),url:string()});var ExtensionCatalogBatchAttributeSchema=strictObject({isFilterable:optional(nullable(boolean())),isSearchable:optional(nullable(boolean())),key:string(),label:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),type:optional(nullable(picklist(["string","number","boolean","enum","color"]))),value:union([boolean(),FiniteNumberSchema,string()])});var ExtensionCatalogBatchOptionSchema=strictObject({colorHex:optional(nullable(string())),rank:optional(nullable(FiniteNumberSchema)),title:optional(nullable(string())),value:string()});var ExtensionCatalogBatchPriceSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(nullable(FiniteNumberSchema)),costAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(nullable(string()))});var ExtensionCatalogBatchPriceListPriceSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(nullable(FiniteNumberSchema)),costAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(nullable(string())),key:string(),title:optional(nullable(string()))});var ExtensionCatalogBatchInventorySchema=strictObject({sku:optional(nullable(string())),stockLocationCode:string(),stockLocationName:optional(nullable(string())),stockedQuantity:FiniteNumberSchema,storeId:optional(nullable(string()))});var ExtensionCatalogBatchVariantSchema=strictObject({attributes:optional(array(ExtensionCatalogBatchAttributeSchema)),externalSku:string(),inventory:optional(array(ExtensionCatalogBatchInventorySchema)),isActive:optional(nullable(boolean())),manageInventory:optional(nullable(boolean())),metadata:optional(nullable(record(string(),ExtensionJsonSchema))),options:optional(record(string(),ExtensionCatalogBatchOptionSchema)),prices:optional(strictObject({base:optional(nullable(ExtensionCatalogBatchPriceSchema)),lists:optional(array(ExtensionCatalogBatchPriceListPriceSchema))})),title:optional(nullable(string()))});var ExtensionCatalogBatchProductSchema=strictObject({attributes:optional(array(ExtensionCatalogBatchAttributeSchema)),categoryId:optional(nullable(string())),description:optional(nullable(string())),images:optional(array(ExtensionCatalogBatchImageSchema)),metadata:optional(nullable(record(string(),ExtensionJsonSchema))),slug:string(),status:optional(nullable(string())),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string(),variants:array(ExtensionCatalogBatchVariantSchema)});var ExtensionCatalogBatchInputSchema=strictObject({products:array(ExtensionCatalogBatchProductSchema),source:string(),storeId:optional(nullable(string()))});var ExtensionCatalogBatchErrorSchema=strictObject({chunkIndex:nullable(FiniteNumberSchema),error:string(),index:FiniteNumberSchema,slug:string()});var ExtensionCatalogBatchResultSchema=strictObject({attributesUpserted:FiniteNumberSchema,chunksProcessed:FiniteNumberSchema,errors:array(ExtensionCatalogBatchErrorSchema),imagesAdded:FiniteNumberSchema,inventorySynced:FiniteNumberSchema,priceListPricesSet:FiniteNumberSchema,priceListsUpserted:FiniteNumberSchema,pricesSet:FiniteNumberSchema,productsCreated:FiniteNumberSchema,productsUpdated:FiniteNumberSchema,rowsProcessed:FiniteNumberSchema,variantOptionValuesLinked:FiniteNumberSchema,variantsCreated:FiniteNumberSchema,variantsUpdated:FiniteNumberSchema});var ExtensionProductCreateInputSchema=strictObject({categoryId:optional(nullable(string())),description:optional(nullable(string())),metadata:OptionalExtensionJsonSchema,slug:string(),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string()});var ExtensionProductUpdateInputSchema=strictObject({categoryId:optional(nullable(string())),description:optional(nullable(string())),id:string(),metadata:OptionalExtensionJsonSchema,slug:optional(string()),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:optional(string())});var ExtensionProductSchema=object({attributes:optional(nullable(array(ExtensionJsonSchema))),categoryId:optional(nullable(string())),description:optional(nullable(string())),id:string(),images:optional(array(ExtensionProductImageSchema)),metadata:OptionalExtensionJsonSchema,options:optional(nullable(array(ExtensionJsonSchema))),slug:string(),status:optional(string()),subtitle:optional(nullable(string())),thumbnail:optional(nullable(string())),title:string(),updatedAt:optional(string())});var ExtensionVariantCreateInputSchema=strictObject({externalSku:string(),isActive:optional(boolean()),manageInventory:optional(boolean()),metadata:OptionalExtensionJsonSchema,title:string()});var ExtensionVariantUpdateInputSchema=partial(ExtensionVariantCreateInputSchema);var ExtensionVariantSchema=object({attributeValues:optional(nullable(array(ExtensionJsonSchema))),externalSku:optional(nullable(string())),id:string(),inventoryItems:optional(nullable(array(ExtensionJsonSchema))),isActive:optional(nullable(boolean())),manageInventory:optional(nullable(boolean())),metadata:OptionalExtensionJsonSchema,optionValueLinks:optional(nullable(array(ExtensionJsonSchema))),priceListPrices:optional(nullable(array(ExtensionJsonSchema))),prices:optional(nullable(array(ExtensionJsonSchema))),productId:string(),title:optional(nullable(string())),updatedAt:optional(string())});var ExtensionFileContentSchema=custom((value)=>typeof value==="string"||value instanceof Uint8Array||value instanceof ArrayBuffer||value instanceof Blob,"Expected string, Uint8Array, ArrayBuffer, or Blob");var ExtensionFileCreateInputSchema=strictObject({access:optional(picklist(["private","public"])),content:ExtensionFileContentSchema,filename:string(),mimeType:string()});var ExtensionFileSchema=object({access:optional(picklist(["private","public"])),createdAt:optional(string()),filename:optional(string()),id:string(),mimeType:optional(nullable(string())),size:optional(nullable(FiniteNumberSchema)),updatedAt:optional(string()),url:optional(nullable(string()))});var ExtensionNotificationProviderDataSchema=strictObject({messageThreadId:optional(string()),parseMode:optional(picklist(["HTML","MarkdownV2"])),providerId:optional(string())});var ExtensionNotificationSendInputSchema=strictObject({channel:picklist(["telegram"]),content:strictObject({text:pipe(string(),minLength(1))}),data:optional(record(string(),ExtensionJsonSchema)),idempotencyKey:optional(string()),providerData:optional(ExtensionNotificationProviderDataSchema),to:pipe(string(),minLength(1))});var ExtensionNotificationSchema=object({channel:picklist(["telegram"]),createdAt:optional(string()),externalId:optional(string()),id:string(),idempotencyKey:optional(string()),providerData:optional(nullable(record(string(),ExtensionJsonSchema))),status:picklist(["failure","pending","success"]),to:string(),updatedAt:optional(string())});var ExtensionInventoryItemEnrollLevelInputSchema=strictObject({lastSyncedAt:optional(string()),metadata:OptionalExtensionJsonSchema,sourceSystem:optional(string()),stockLocationId:string(),stockedQuantity:FiniteNumberSchema});var ExtensionInventoryItemEnrollInputSchema=strictObject({inventoryLevels:optional(array(ExtensionInventoryItemEnrollLevelInputSchema)),isManaged:optional(boolean()),metadata:OptionalExtensionJsonSchema,sku:string(),storeId:string(),variantId:string()});var ExtensionInventoryItemSchema=object({code:optional(nullable(string())),id:string(),metadata:OptionalExtensionJsonSchema,sku:optional(nullable(string())),storeId:optional(string()),variantId:optional(string())});var ExtensionStockLocationCreateInputSchema=strictObject({code:string(),isEnabled:optional(boolean()),metadata:OptionalExtensionJsonSchema,name:string(),storeId:string(),type:optional(string())});var ExtensionStockLocationUpdateInputSchema=strictObject({code:optional(string()),id:string(),isEnabled:optional(boolean()),metadata:OptionalExtensionJsonSchema,name:optional(string()),storeId:optional(string()),type:optional(string())});var ExtensionStockLocationSchema=object({code:optional(nullable(string())),id:string(),isEnabled:optional(nullable(boolean())),metadata:OptionalExtensionJsonSchema,name:optional(string()),storeId:optional(string()),type:optional(string())});var ExtensionStockLevelSyncInputSchema=strictObject({inventoryItemId:string(),lastSyncedAt:optional(string()),metadata:OptionalExtensionJsonSchema,sourceSystem:optional(string()),stockLocationId:string(),stockedQuantity:FiniteNumberSchema});var ExtensionStockLevelSchema=object({id:optional(string()),inventoryItemId:optional(string()),stockLocationId:optional(string()),stockedQuantity:optional(FiniteNumberSchema)});var ExtensionPriceListCreateInputSchema=strictObject({automaticallyApplies:optional(boolean()),metadata:OptionalExtensionJsonSchema,priority:optional(FiniteNumberSchema),status:optional(string()),storeId:string(),title:string(),type:optional(string())});var ExtensionPriceListUpdateInputSchema=strictObject({automaticallyApplies:optional(boolean()),id:string(),metadata:OptionalExtensionJsonSchema,priority:optional(FiniteNumberSchema),status:optional(string()),title:optional(string()),type:optional(string())});var ExtensionPriceListSchema=object({automaticallyApplies:optional(nullable(boolean())),id:string(),metadata:OptionalExtensionJsonSchema,priority:optional(nullable(FiniteNumberSchema)),status:optional(string()),storeId:optional(string()),title:optional(string()),type:optional(string())});var ExtensionPriceListPriceCreateInputSchema=strictObject({amount:FiniteNumberSchema,compareAtAmount:optional(FiniteNumberSchema),currencyCode:string(),metadata:OptionalExtensionJsonSchema,priceListId:string(),variantId:string()});var ExtensionPriceListPriceUpdateInputSchema=strictObject({amount:optional(FiniteNumberSchema),compareAtAmount:optional(FiniteNumberSchema),currencyCode:optional(string()),id:string(),metadata:OptionalExtensionJsonSchema,priceListId:optional(string()),variantId:optional(string())});var ExtensionPriceListPriceSchema=object({amount:optional(nullable(FiniteNumberSchema)),compareAtAmount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(string()),id:string(),metadata:OptionalExtensionJsonSchema,priceListId:optional(string()),variantId:optional(string())});var ExtensionBasePriceSetInputSchema=strictObject({amount:FiniteNumberSchema,atTime:optional(string()),compareAtAmount:optional(FiniteNumberSchema),costAmount:optional(FiniteNumberSchema),currencyCode:string(),taxIncluded:optional(boolean()),variantId:string()});var ExtensionPriceSchema=object({amount:optional(nullable(FiniteNumberSchema)),currencyCode:optional(string()),id:string(),variantId:optional(string())});function parseJsonText(input){return parse(JsonTextSchema,input)}function toExtensionJson(value,seen=new WeakSet,depth=0){if(value===null||typeof value==="boolean"||typeof value==="string"){return value}if(typeof value==="number"){return Number.isFinite(value)?value:null}if(typeof value==="bigint"){return value.toString()}if(value===undefined||typeof value==="function"||typeof value==="symbol"){return null}if(value instanceof Date){return Number.isFinite(value.getTime())?value.toISOString():null}if(value instanceof Uint8Array){return Array.from(value)}if(value instanceof ArrayBuffer){return Array.from(new Uint8Array(value))}if(typeof value==="object"){if(seen.has(value)){return null}seen.add(value);if(depth>50){return"[Truncated]"}if(Array.isArray(value)){return value.map((entry)=>toExtensionJson(entry,seen,depth+1))}const output={};for(const[key,entry]of Object.entries(value)){if(entry!==undefined&&typeof entry!=="function"&&typeof entry!=="symbol"){output[key]=toExtensionJson(entry,seen,depth+1)}}return output}return null}function isExtensionJson(value){if(value===null){return true}switch(typeof value){case"boolean":case"string":return true;case"number":return Number.isFinite(value);case"object":if(Array.isArray(value)){return value.every(isExtensionJson)}if(!isPlainRecord(value)){return false}return Object.values(value).every(isExtensionJson);default:return false}}function isPlainRecord(value){if(!value||typeof value!=="object"||Array.isArray(value)){return false}const prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function isExtensionSerializableValue(value,seen=new Set){if(value===undefined||value===null){return true}switch(typeof value){case"boolean":case"string":return true;case"number":return Number.isFinite(value);case"object":{if(value instanceof Date){return Number.isFinite(value.getTime())}if(value instanceof Uint8Array||value instanceof ArrayBuffer){return true}if(seen.has(value)){return false}seen.add(value);if(Array.isArray(value)){return value.every((entry)=>isExtensionSerializableValue(entry,seen))}const prototype=Object.getPrototypeOf(value);if(prototype!==Object.prototype&&prototype!==null){return false}return Object.values(value).every((entry)=>isExtensionSerializableValue(entry,seen))}default:return false}}var AI_BOT_EXTENSION_NAME="ai-bot";var AI_BOT_VERSION="0.0.10-alpha.12";var DEFAULT_MODEL="gpt-4.1-mini";var DEFAULT_OPENAI_BASE_URL="https://api.openai.com/v1";var DEFAULT_ANTHROPIC_BASE_URL="https://api.anthropic.com/v1";var DEFAULT_MAX_COMMANDS=8;var RUN_HISTORY_PREFIX="ai-bot.runs.";var LAST_RUN_KEY="ai-bot.last-run";var MAX_EFFECT_RESULT_CHARS=8000;var MAX_MODEL_CONTEXT_CHARS=12000;var COMMANDS=[{command:"product.list",description:"List products with an optional read query.",mutates:false},{command:"product.retrieve",description:"Retrieve one product by id.",mutates:false},{command:"product.retrieveVariantByExternalSku",description:"Retrieve a variant by external SKU.",mutates:false},{command:"product.listVariants",description:"List variants for a product id.",mutates:false},{command:"product.listCategories",description:"List product categories.",mutates:false},{command:"price.listPriceList",description:"List price lists.",mutates:false},{command:"price.listPriceListPrice",description:"List price list prices.",mutates:false},{command:"stockLocation.listStockLocation",description:"List stock locations.",mutates:false},{command:"stockLocation.retrieveStockLocation",description:"Retrieve one stock location by id.",mutates:false},{command:"notification.listNotifications",description:"List notifications.",mutates:false},{command:"notification.retrieveNotification",description:"Retrieve one notification by id.",mutates:false},{command:"file.list",description:"List files.",mutates:false},{command:"file.retrieve",description:"Retrieve file metadata by id.",mutates:false},{command:"storage.db.get",description:"Read one extension storage record by key.",mutates:false},{command:"storage.db.list",description:"List extension storage records.",mutates:false},{command:"storage.cache.get",description:"Read one extension cache value by key.",mutates:false},{command:"product.create",description:"Create one or more products.",mutates:true},{command:"product.update",description:"Update one or more products.",mutates:true},{command:"product.createCategory",description:"Create a product category.",mutates:true},{command:"product.updateCategory",description:"Update a product category.",mutates:true},{command:"product.createVariant",description:"Create a product variant.",mutates:true},{command:"product.updateVariant",description:"Update a product variant.",mutates:true},{command:"product.addImage",description:"Add an image URL to a product.",mutates:true},{command:"product.upsertOption",description:"Create or update a product option.",mutates:true},{command:"product.upsertOptionValue",description:"Create or update a product option value.",mutates:true},{command:"product.linkVariantOptionValue",description:"Link a variant to an option value.",mutates:true},{command:"product.upsertAttribute",description:"Create or update a product attribute.",mutates:true},{command:"product.upsertAttributeValue",description:"Create or update a product attribute value.",mutates:true},{command:"price.createPriceList",description:"Create one or more price lists.",mutates:true},{command:"price.updatePriceList",description:"Update one or more price lists.",mutates:true},{command:"price.createPriceListPrice",description:"Create one or more price list prices.",mutates:true},{command:"price.updatePriceListPrice",description:"Update one or more price list prices.",mutates:true},{command:"price.setBasePrice",description:"Set a variant base price.",mutates:true},{command:"stockLocation.createStockLocation",description:"Create a stock location.",mutates:true},{command:"stockLocation.updateStockLocation",description:"Update a stock location.",mutates:true},{command:"stockLocation.upsertStockLocation",description:"Create or update a stock location.",mutates:true},{command:"inventory.enrollVariantInStore",description:"Enroll a variant in store inventory.",mutates:true},{command:"inventory.syncStockLevel",description:"Sync a stock level.",mutates:true},{command:"notification.createNotifications",description:"Create one or more notifications.",mutates:true},{command:"file.create",description:"Create a file from string content.",mutates:true},{command:"file.delete",description:"Delete one or more files by id.",mutates:true},{command:"storage.db.set",description:"Write an extension storage record.",mutates:true},{command:"storage.db.delete",description:"Delete extension storage records.",mutates:true},{command:"storage.cache.set",description:"Write an extension cache value.",mutates:true},{command:"storage.cache.delete",description:"Delete extension cache values.",mutates:true}];var COMMAND_BY_NAME=new Map(COMMANDS.map((command)=>[command.command,command]));var COMMAND_CATALOG_TEXT=COMMANDS.map((entry)=>`- ${entry.command} (${entry.mutates?"mutation":"read"}): ${entry.description}`).join(`
|
|
3
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(`
|
|
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:
|
|
5
|
+
`);var BRAND_MAP_DEVELOPER_URL="https://brand-map.ru";var EXTENSION_LOGO={alt:"AI Bot icon",src:"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5NiA5NiI+PHJlY3Qgd2lkdGg9Ijk2IiBoZWlnaHQ9Ijk2IiByeD0iMjAiIGZpbGw9IiMxMjE4MjYiLz48cGF0aCBkPSJNMjQgNDBjMC05Ljk0IDguMDYtMTggMTgtMThoMTJjOS45NCAwIDE4IDguMDYgMTggMTh2MThjMCA2LjYzLTUuMzcgMTItMTIgMTJIMzZjLTYuNjMgMC0xMi01LjM3LTEyLTEyVjQwWiIgZmlsbD0iIzJERDRCRiIvPjxwYXRoIGQ9Ik0zMiA0MmMwLTUuNTIgNC40OC0xMCAxMC0xMGgxMmM1LjUyIDAgMTAgNC40OCAxMCAxMHYxMmMwIDQuNDItMy41OCA4LTggOEg0MGMtNC40MiAwLTgtMy41OC04LThWNDJaIiBmaWxsPSIjRjhGQUZDIi8+PGNpcmNsZSBjeD0iNDIiIGN5PSI0OCIgcj0iNCIgZmlsbD0iIzEyMTgyNiIvPjxjaXJjbGUgY3g9IjU0IiBjeT0iNDgiIHI9IjQiIGZpbGw9IiMxMjE4MjYiLz48cGF0aCBkPSJNNDIgNjBoMTIiIHN0cm9rZT0iIzEyMTgyNiIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48cGF0aCBkPSJNNDggMTh2LTZNMjcgMjVsLTQtNE02OSAyNWw0LTRNMjYgNzZsLTUgNU03MCA3Nmw1IDUiIHN0cm9rZT0iI0E3OEJGQSIgc3Ryb2tlLXdpZHRoPSI1IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4="};function createAiBotExtension(options={}){const settings=readSettings(options);return extension({config:[{defaultValue:"openai",key:"aiProvider",label:"AI Provider",options:[{label:"OpenAI",value:"openai"},{label:"OpenAI Compatible",value:"openai-compatible"},{label:"Anthropic",value:"anthropic"}],type:"select"},{key:"apiToken",label:"AI Provider API Token",required:true,secret:true,type:"string"},{defaultValue:DEFAULT_OPENAI_BASE_URL,key:"apiBaseUrl",label:"AI API Base URL",type:"url"},{defaultValue:DEFAULT_MODEL,key:"model",label:"Model",type:"string"},{defaultValue:DEFAULT_MAX_COMMANDS,key:"maxCommands",label:"Max Commands",type:"number"},{defaultValue:false,description:"Allows the harness to execute write commands when workflow input also allows it.",key:"allowMutations",label:"Allow Mutations",type:"boolean"},{defaultValue:false,description:"Runs read commands but skips write commands.",key:"dryRun",label:"Dry Run",type:"boolean"},{defaultValue:DEFAULT_SYSTEM_PROMPT,key:"systemPrompt",label:"System Prompt",type:"string"}],description:"Runs a small AI harness as a Temporal workflow over approved Brand Map extension commands.",displayName:"AI Bot",developerUrl:BRAND_MAP_DEVELOPER_URL,logo:EXTENSION_LOGO,name:AI_BOT_EXTENSION_NAME,publisher:"Brand Map",permissions:AI_BOT_PERMISSIONS,callbacks:[callback("health",()=>({ok:true,service:AI_BOT_EXTENSION_NAME,workflow:"run-harness"})),callback("last-run",async({storage})=>{const record2=await storage.db.get(LAST_RUN_KEY);return{run:record2?.value??null}})],version:AI_BOT_VERSION,workflows:[temporalWorkflow("run-harness",async({brandMap,invocation,log,storage})=>{const input=readHarnessInput(invocation.input,settings);const startedAt=new Date().toISOString();const runId=`ai_bot_${invocation.invocationId}`;log.info("AI Bot Temporal workflow started",{allowMutations:input.allowMutations,dryRun:input.dryRun,invocationId:invocation.invocationId,runId});const result=await runHarness({brandMap,input,log,runId,settings,startedAt,storage}).catch(async(error)=>{const message=error instanceof Error?error.message:String(error);const failed={allowMutations:input.allowMutations,commands:[],dryRun:input.dryRun,effects:[],finishedAt:new Date().toISOString(),model:settings.model,planText:"",provider:settings.aiProvider,runId,startedAt,status:"failed",summary:{message,status:"failed"},task:input.task};await persistRun(storage,failed);return failed});log.info("AI Bot Temporal workflow completed",{commandCount:result.commands.length,effectCount:result.effects.length,invocationId:invocation.invocationId,runId,status:result.status});return result})]})}async function runHarness(input){if(!input.settings.apiToken){throw new Error("AI Bot requires apiToken in extension config.")}const planText=await callAiModel(input.settings,[{content:buildPlanningPrompt(input.input),role:"user"}]);const plannedCommands=normalizePlan(parseJsonObject(planText),input.input.maxCommands);const effects=[];for(const plannedCommand of plannedCommands){effects.push(await executePlannedCommand({brandMap:input.brandMap,command:plannedCommand,input:input.input,storage:input.storage}))}const summary=await createFinalSummary({effects,planText,settings:input.settings,task:input.input.task});const result={allowMutations:input.input.allowMutations,commands:plannedCommands,dryRun:input.input.dryRun,effects,finishedAt:new Date().toISOString(),model:input.settings.model,planText,provider:input.settings.aiProvider,runId:input.runId,startedAt:input.startedAt,status:effects.some((effect)=>effect.status==="error")?"failed":"completed",summary,task:input.input.task};await persistRun(input.storage,result);return result}async function createFinalSummary(input){const status=input.effects.some((effect)=>effect.status==="error")?"completed-with-errors":"completed";try{const summaryText=await callAiModel(input.settings,[{content:buildSummaryPrompt({effects:input.effects,planText:input.planText,task:input.task}),role:"user"}]);return toExtensionJson2(parseJsonObject(summaryText,{message:summaryText,status}))}catch(error){return{errors:[error instanceof Error?error.message:String(error)],status:"summary-failed",summary:"Commands ran, but the final AI summary request failed."}}}async function executePlannedCommand(input){const startedAt=new Date().toISOString();const definition=COMMAND_BY_NAME.get(input.command.command);const base={args:input.command.args,command:input.command.command,finishedAt:startedAt,id:input.command.id,reason:input.command.reason,startedAt};if(!definition){return{...base,skippedReason:"Unsupported command.",status:"skipped"}}if(input.input.allowedCommands&&!input.input.allowedCommands.has(input.command.command)){return{...base,skippedReason:"Command was not listed in workflow input allowedCommands.",status:"skipped"}}if(definition.mutates&&input.input.dryRun){return{...base,skippedReason:"Dry run is enabled.",status:"skipped"}}if(definition.mutates&&!input.input.allowMutations){return{...base,skippedReason:"Mutation commands are disabled.",status:"skipped"}}try{const result=await dispatchCommand(input.brandMap,input.storage,input.command);return{...base,finishedAt:new Date().toISOString(),result:compactResult(result),status:"ok"}}catch(error){return{...base,error:error instanceof Error?error.message:String(error),finishedAt:new Date().toISOString(),status:"error"}}}async function dispatchCommand(brandMap,storage,command){const args=command.args;switch(command.command){case"product.list":return await brandMap.product.list(args[0]);case"product.retrieve":return await brandMap.product.retrieve(readStringArg(args,0),args[1]);case"product.retrieveVariantByExternalSku":return await brandMap.product.retrieveVariantByExternalSku(readStringArg(args,0));case"product.listVariants":return await brandMap.product.listVariants(readStringArg(args,0));case"product.listCategories":return await brandMap.product.listCategories(args[0]);case"product.create":return await brandMap.product.create(args[0]);case"product.update":return await brandMap.product.update(args[0]);case"product.createCategory":return await brandMap.product.createCategory(args[0]);case"product.updateCategory":return await brandMap.product.updateCategory(readStringArg(args,0),args[1]);case"product.createVariant":return await brandMap.product.createVariant(readStringArg(args,0),args[1]);case"product.updateVariant":return await brandMap.product.updateVariant(readStringArg(args,0),args[1]);case"product.addImage":return await brandMap.product.addImage(readStringArg(args,0),readStringArg(args,1),readOptionalNumberArg(args,2));case"product.upsertOption":return await brandMap.product.upsertOption(readStringArg(args,0),args[1]);case"product.upsertOptionValue":return await brandMap.product.upsertOptionValue(readStringArg(args,0),args[1]);case"product.linkVariantOptionValue":return await brandMap.product.linkVariantOptionValue(readStringArg(args,0),readStringArg(args,1));case"product.upsertAttribute":return await brandMap.product.upsertAttribute(readStringArg(args,0),args[1]);case"product.upsertAttributeValue":return await brandMap.product.upsertAttributeValue(args[0]);case"price.listPriceList":return await brandMap.price.listPriceList(args[0]);case"price.listPriceListPrice":return await brandMap.price.listPriceListPrice(args[0]);case"price.createPriceList":return await brandMap.price.createPriceList(args[0]);case"price.updatePriceList":return await brandMap.price.updatePriceList(args[0]);case"price.createPriceListPrice":return await brandMap.price.createPriceListPrice(args[0]);case"price.updatePriceListPrice":return await brandMap.price.updatePriceListPrice(args[0]);case"price.setBasePrice":return await brandMap.price.setBasePrice(args[0]);case"stockLocation.listStockLocation":return await brandMap.stockLocation.listStockLocation(args[0]);case"stockLocation.retrieveStockLocation":return await brandMap.stockLocation.retrieveStockLocation(readStringArg(args,0),args[1]);case"stockLocation.createStockLocation":return await brandMap.stockLocation.createStockLocation(args[0]);case"stockLocation.updateStockLocation":return await brandMap.stockLocation.updateStockLocation(args[0]);case"stockLocation.upsertStockLocation":return await brandMap.stockLocation.upsertStockLocation(args[0]);case"inventory.enrollVariantInStore":return await brandMap.inventory.enrollVariantInStore(args[0]);case"inventory.syncStockLevel":return await brandMap.inventory.syncStockLevel(args[0]);case"notification.createNotifications":return await brandMap.notification.createNotifications(args[0]);case"notification.listNotifications":return await brandMap.notification.listNotifications(args[0]);case"notification.retrieveNotification":return await brandMap.notification.retrieveNotification(readStringArg(args,0),args[1]);case"file.create":return await brandMap.file.create(args[0]);case"file.delete":return await brandMap.file.delete(args[0]);case"file.list":return await brandMap.file.list(args[0]);case"file.retrieve":return await brandMap.file.retrieve(readStringArg(args,0),args[1]);case"storage.db.get":return await storage.db.get(readStringArg(args,0));case"storage.db.list":return await storage.db.list(args[0]);case"storage.db.set":return await storage.db.set(args[0]);case"storage.db.delete":return await storage.db.delete(args[0]);case"storage.cache.get":return await storage.cache.get(readStringArg(args,0));case"storage.cache.set":return await storage.cache.set(args[0]);case"storage.cache.delete":return await storage.cache.delete(args[0]);default:throw new Error(`Unsupported command "${command.command}"`)}}async function callAiModel(settings,messages){assertAiBaseUrl(settings.apiBaseUrl);if(settings.aiProvider==="anthropic"){return await callAnthropic(settings,messages)}return await callOpenAiCompatible(settings,messages)}async function callOpenAiCompatible(settings,messages){const response=await settings.fetchImplementation(`${settings.apiBaseUrl}/chat/completions`,{body:JSON.stringify({messages:[{content:settings.systemPrompt,role:"system"},...messages],model:settings.model,response_format:{type:"json_object"},temperature:0.1}),headers:{authorization:`Bearer ${settings.apiToken}`,"content-type":"application/json"},method:"POST"});const payload=await readAiResponse(response);const content=readPath(payload,["choices",0,"message","content"]);if(typeof content!=="string"){throw new Error("AI provider response did not include choices[0].message.content.")}return content}async function callAnthropic(settings,messages){const response=await settings.fetchImplementation(`${settings.apiBaseUrl}/messages`,{body:JSON.stringify({max_tokens:2000,messages,model:settings.model,system:settings.systemPrompt,temperature:0.1}),headers:{"anthropic-version":"2023-06-01","content-type":"application/json","x-api-key":settings.apiToken??""},method:"POST"});const payload=await readAiResponse(response);const blocks=readPath(payload,["content"]);if(!Array.isArray(blocks)){throw new Error("AI provider response did not include content blocks.")}return blocks.map((block)=>isRecord(block)&&typeof block.text==="string"?block.text:"").join(`
|
|
6
|
+
`).trim()}async function readAiResponse(response){const text=await response.text();const payload=parseJsonObject(text,{message:text});if(!response.ok){const message=readAiErrorMessage(payload)??`AI provider request failed with status ${response.status}.`;throw new Error(message)}return payload}function buildPlanningPrompt(input){return truncateText(JSON.stringify({context:input.context,instructions:["Pick the minimum command sequence needed.","Use read commands before mutation commands when identifiers are unknown.","Mutation commands are only useful when allowMutations is true and dryRun is false.","Return only JSON with a commands array."],runtime:{allowMutations:input.allowMutations,allowedCommands:input.allowedCommands?Array.from(input.allowedCommands):null,dryRun:input.dryRun,maxCommands:input.maxCommands},task:input.task},null,2),MAX_MODEL_CONTEXT_CHARS)}function buildSummaryPrompt(input){return truncateText(JSON.stringify({effects:input.effects,instructions:["Summarize what happened for the user.","Mention commands that were skipped or failed.","Return only JSON with keys summary, status, actions, skipped, errors, nextSteps."],planText:input.planText,task:input.task},null,2),MAX_MODEL_CONTEXT_CHARS)}function normalizePlan(input,maxCommands){if(!isRecord(input)||!Array.isArray(input.commands)){throw new Error("AI 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: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(`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)}
|
|
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};
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# AI Bot
|
|
2
|
+
|
|
3
|
+
The AI Bot extension runs an approved command harness as a Temporal workflow. It sends a user task and context to the configured AI provider, executes only commands from the extension command catalog, and stores the latest run in extension storage.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
- Calls the configured AI provider.
|
|
8
|
+
- Requires the model to return JSON command plans.
|
|
9
|
+
- Executes approved Brand Map read and write operations through the extension runtime.
|
|
10
|
+
- Supports dry runs for read-only execution.
|
|
11
|
+
- Requires both installation config and workflow input to allow mutations before write commands run.
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
- `aiProvider`: AI provider mode.
|
|
16
|
+
- `apiToken`: provider API token.
|
|
17
|
+
- `apiBaseUrl`: provider API base URL.
|
|
18
|
+
- `model`: model name.
|
|
19
|
+
- `maxCommands`: maximum commands per run.
|
|
20
|
+
- `allowMutations`: installation-level write permission switch.
|
|
21
|
+
- `dryRun`: skips write commands.
|
|
22
|
+
- `systemPrompt`: command planning prompt.
|
|
23
|
+
|
|
24
|
+
## Workflow Input
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"task": "Check the first five products and summarize missing thumbnails.",
|
|
29
|
+
"context": {
|
|
30
|
+
"storeId": "store_1"
|
|
31
|
+
},
|
|
32
|
+
"dryRun": false,
|
|
33
|
+
"allowMutations": false,
|
|
34
|
+
"maxCommands": 5
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Safety Model
|
|
39
|
+
|
|
40
|
+
The extension does not run shell commands. It executes only commands declared in the command catalog, and write commands require explicit mutation flags.
|
package/docs/SUMMARY.md
ADDED
package/package.json
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brand-map/ai-bot-extension",
|
|
3
|
-
"version": "0.0.10-alpha.
|
|
3
|
+
"version": "0.0.10-alpha.12",
|
|
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
|
}
|