@pluno/product-agent-web 0.1.204 → 0.1.206
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/dist/displayedErrors.d.ts +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/product-agent-runtime.cjs +1 -1
- package/dist/product-agent-runtime.js +52 -31
- package/dist/product-agent-sdk.js +396 -316
- package/dist/product-agent-widget.js +2563 -2431
- package/dist/public/operationRoutes.d.ts +4 -0
- package/dist/runtimeClient.d.ts +16 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function observeProductAgentDisplayedErrors(root: HTMLElement, report: (reason: string, errorFingerprint: string) => void): () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -305,6 +305,9 @@ export declare class ProductAgentSessionEngine {
|
|
|
305
305
|
private retryAttemptsByClientMessageId;
|
|
306
306
|
private retryTimersByClientMessageId;
|
|
307
307
|
private readonly reportedHealthSignalKeys;
|
|
308
|
+
private readonly firstResponseTimersByClientMessageId;
|
|
309
|
+
private lastProjectedTurnPhase;
|
|
310
|
+
private lastProjectedTurnClientMessageId;
|
|
308
311
|
private readonly clientMessageIdsByUserMessageItemId;
|
|
309
312
|
private readonly backgroundSessionIds;
|
|
310
313
|
private readonly backgroundClientMessageIds;
|
|
@@ -365,7 +368,10 @@ export declare class ProductAgentSessionEngine {
|
|
|
365
368
|
initiatedBy?: "pluno";
|
|
366
369
|
invocation?: ProductAgentInvocation | "pluno";
|
|
367
370
|
proactiveSuggestionQuestion?: string;
|
|
371
|
+
submittedAt?: number;
|
|
368
372
|
}): Promise<string | null>;
|
|
373
|
+
reportInvalidStateTransition(reason: string, clientMessageId?: string): void;
|
|
374
|
+
reportDisplayedError(reason: string, errorFingerprint: string): void;
|
|
369
375
|
getModel(): ProductAgentModel | undefined;
|
|
370
376
|
setModel(model: ProductAgentModel): void;
|
|
371
377
|
retryLastMessage(): boolean;
|
|
@@ -413,6 +419,9 @@ export declare class ProductAgentSessionEngine {
|
|
|
413
419
|
private getUploadToken;
|
|
414
420
|
private sendNow;
|
|
415
421
|
private reportHealthSignal;
|
|
422
|
+
private startFirstResponseTimer;
|
|
423
|
+
private clearFirstResponseTimer;
|
|
424
|
+
private clearAllFirstResponseTimers;
|
|
416
425
|
private requestTransientStarterPrompts;
|
|
417
426
|
private startStarterPromptUrlWatcher;
|
|
418
427
|
private handleStarterPromptUrlChange;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function d(s){return{key:s,status:"not_requested",data:null,error:null,requestId:0,updatedAt:null}}class m{constructor(t,e,i=(n,r)=>r){this.loader=e,this.merge=i,this.state=d(t)}loader;merge;state;listeners=new Set;inFlight=null;trailingLoad=null;getState(){return this.state}subscribe(t){return this.listeners.add(t),t(this.state),()=>this.listeners.delete(t)}setKey(t){t!==this.state.key&&(this.state=d(t),this.trailingLoad=null,this.publish())}reset(){this.state=d(this.state.key),this.trailingLoad=null,this.publish()}invalidate(){this.state={...this.state,status:this.state.data===null?"not_requested":"ready",updatedAt:null},this.publish()}load(t="replace",e=null){return this.trailingLoad={mode:t,cursor:e},this.inFlight?this.inFlight:(this.inFlight=this.runLoads().finally(()=>{this.inFlight=null}),this.inFlight)}update(t){this.state={...this.state,data:t(this.state.data)},this.publish()}async runLoads(){for(;this.trailingLoad;){const t=this.trailingLoad;this.trailingLoad=null;const e=this.state.key,i=this.state.requestId+1;this.state={...this.state,status:t.mode==="append"?"loading_more":this.state.data===null?"loading":"refreshing",error:null,requestId:i},this.publish();try{const n=await this.loader({key:e,cursor:t.cursor});if(e!==this.state.key||i!==this.state.requestId)continue;this.state={...this.state,status:"ready",data:this.merge(this.state.data,n,t.mode),error:null,updatedAt:Date.now()},this.publish()}catch(n){if(e!==this.state.key||i!==this.state.requestId)continue;this.state={...this.state,status:"error",error:n instanceof Error?n.message:"The query failed."},this.publish()}}}publish(){for(const t of this.listeners)t(this.state)}}function h(s){const t={},e=[];for(const i of s.entities)t[i.id]||e.push(i.id),t[i.id]=i;return{entitiesById:t,ids:e,nextCursor:s.nextCursor}}function P(s,t,e){if(e==="replace"||s===null)return t;const i={...s.entitiesById,...t.entitiesById},n=[...s.ids];for(const r of t.ids)s.entitiesById[r]||n.push(r);return{entitiesById:i,ids:n,nextCursor:t.nextCursor}}function S(s){return s?s.ids.map(t=>s.entitiesById[t]).filter(t=>!!t):[]}function E(s){return s.visible?s.minimized?{state:"minimized"}:{state:s.open?"visible_open":"visible_closed"}:{state:"hidden"}}function M(s,t){return t==="limit_exceeded"?{allowed:!1,reason:"credits_exhausted",actions:["upgrade","earn_credits"]}:t==="subscription_required"||t==="subscription_inactive"||t==="payment_issue"||t==="subscription_invalid"||t==="payment_required"?{allowed:!1,reason:"payment_issue",actions:["upgrade"]}:s??{allowed:!0,reason:"allowed",actions:[]}}function O(s){if(!s||typeof s!="object")return!1;const t=s.paidCreditFallbackModel;return typeof t=="string"&&t.length>0}function _(s){return s?s.submissionGate?.allowed===!1?{state:"action_required",reason:s.submissionGate.reason}:s.usingPaidCreditFallback===!0?{state:"paid_credit_fallback"}:s.creditLimit!==null&&s.creditLimit>0&&s.creditsRemaining!==null&&s.creditsRemaining>0&&s.creditsRemaining/s.creditLimit<=.2?{state:"low_credits"}:s.creditsUsed!==null?{state:"usage"}:{state:"hidden"}:{state:"hidden"}}function D(s){const t=s.hasDraftMessage||s.hasPreSubmittedAttachment;return s.hasRunningAssistantTurn&&!t?{action:"stop",disabled:!s.canStopRunningTurn}:{action:"send",disabled:!t||!s.canSubmitMessage}}class x{constructor(t,e,i=20){this.loadPage=e,this.limit=i,this.recentQuery=new m(`${t}:recent`,async({cursor:n})=>h(await this.loadPage({cursor:n,limit:this.limit,pinned:!1}).then(r=>({entities:r.sessions,nextCursor:r.nextCursor}))),P),this.pinnedQuery=new m(`${t}:pinned`,async()=>h({entities:await this.loadAllPinned(),nextCursor:null})),this.recentQuery.subscribe(()=>this.publish()),this.pinnedQuery.subscribe(()=>this.publish())}loadPage;limit;recentQuery;pinnedQuery;listeners=new Set;optimisticEntities=new Map;activityOverrides=new Map;pinnedOverrides=new Map;titleOverrides=new Map;refreshSequence=0;completedRefreshSequence=0;activityReconciliationScheduled=!1;getState(){const t=this.recentQuery.getState(),e=this.pinnedQuery.getState(),i=[...g(e.data),...g(t.data)],n=new Map(i.map(o=>[o.id,o])),r=Array.from(n.values()).map(o=>this.applyOverrides(o,this.completedRefreshSequence)),a=Array.from(this.optimisticEntities.values()).filter(o=>!n.has(o.id)).reverse(),l=t.data||e.data||a.length>0?h({entities:[...a,...r],nextCursor:t.data?.nextCursor??null}):null;return{key:t.key.slice(0,-7),status:C(t,e),data:l,error:t.error??e.error,requestId:Math.max(t.requestId,e.requestId),updatedAt:Math.max(t.updatedAt??0,e.updatedAt??0)||null}}subscribe(t){return this.listeners.add(t),t(this.getState()),()=>this.listeners.delete(t)}getEntity(t){return this.getState().data?.entitiesById[t]??null}setKey(t){this.optimisticEntities.clear(),this.activityOverrides.clear(),this.pinnedOverrides.clear(),this.titleOverrides.clear(),this.refreshSequence=0,this.completedRefreshSequence=0,this.activityReconciliationScheduled=!1,this.recentQuery.setKey(`${t}:recent`),this.pinnedQuery.setKey(`${t}:pinned`)}refresh(){const t=++this.refreshSequence,e=Promise.all([this.recentQuery.load("replace"),this.pinnedQuery.load("replace")]).then(()=>{this.completedRefreshSequence=Math.max(this.completedRefreshSequence,t),this.reconcileDurableEntities()});return e.then(()=>{!this.hasUnconfirmedActivityOverride()||this.activityReconciliationScheduled||(this.activityReconciliationScheduled=!0,this.refresh().finally(()=>{this.activityReconciliationScheduled=!1}))}),e}loadMore(t){return this.recentQuery.load("append",t)}addOptimistic(t){this.optimisticEntities.set(t.id,t),this.updateProjection()}removeOptimistic(t){this.optimisticEntities.delete(t)&&this.updateProjection()}acknowledgeOptimistic(t,e){this.optimisticEntities.delete(t),this.optimisticEntities.set(e.id,e),this.updateProjection()}setActivity(t,e){this.activityOverrides.set(t,{isActive:e,confirmAfterRefresh:this.completedRefreshSequence+1,releaseAfterRefresh:this.completedRefreshSequence+2}),this.updateEntity(t,i=>({...i,isActive:e}))}setPinned(t,e){const i={pinned:e,confirmAfterRefresh:Number.POSITIVE_INFINITY};return this.pinnedOverrides.set(t,i),this.updateEntity(t,n=>({...n,isPinned:e})),i}confirmPinned(t,e){this.pinnedOverrides.get(t)===e&&(e.confirmAfterRefresh=this.completedRefreshSequence+1)}rollbackPinned(t,e,i){this.pinnedOverrides.get(t)===e&&(this.pinnedOverrides.delete(t),this.updateEntity(t,n=>({...n,isPinned:i})))}setTitle(t,e){this.titleOverrides.set(t,e),this.updateEntity(t,i=>({...i,customTitle:e}))}confirmTitle(t){this.titleOverrides.delete(t)}reconcileDurableEntities(){const t=[...g(this.pinnedQuery.getState().data),...g(this.recentQuery.getState().data)],e=new Set(t.map(i=>i.id));for(const i of this.optimisticEntities.keys())e.has(i)&&this.optimisticEntities.delete(i);for(const i of t)this.applyOverrides(i,this.completedRefreshSequence);this.publish()}async loadAllPinned(){const t=[];let e=null;do{const i=await this.loadPage({cursor:e,limit:this.limit,pinned:!0});t.push(...i.sessions),e=i.nextCursor}while(e);return t}applyOverrides(t,e){let i=t;const n=this.activityOverrides.get(t.id);n&&(e>=n.confirmAfterRefresh&&t.isActive===n.isActive?this.activityOverrides.delete(t.id):e>=n.releaseAfterRefresh?this.activityOverrides.delete(t.id):i={...i,isActive:n.isActive});const r=this.pinnedOverrides.get(t.id);return r&&(e>=r.confirmAfterRefresh&&t.isPinned===!0===r.pinned?this.pinnedOverrides.delete(t.id):i={...i,isPinned:r.pinned}),this.titleOverrides.has(t.id)&&(i={...i,customTitle:this.titleOverrides.get(t.id)??null}),i}updateProjection(){this.publish()}updateEntity(t,e){const i=this.optimisticEntities.get(t);i&&this.optimisticEntities.set(t,e(i)),this.publish()}hasUnconfirmedActivityOverride(){return Array.from(this.activityOverrides.values()).some(t=>this.completedRefreshSequence<t.releaseAfterRefresh)}publish(){for(const t of this.listeners)t(this.getState())}}function g(s){return s?s.ids.map(t=>s.entitiesById[t]).filter(t=>!!t):[]}function C(s,t){return s.status==="error"||t.status==="error"?"error":s.status==="loading"||t.status==="loading"?"loading":s.status==="refreshing"||t.status==="refreshing"?"refreshing":s.status==="loading_more"?"loading_more":s.status==="ready"||t.status==="ready"?"ready":"not_requested"}class R{constructor(t,e=null){this.storage=t,e&&(this.decisions=new Map(e.filter(v).map(i=>[this.getDecisionKey(i),i])),this.initialized=!0)}storage;decisions=new Map;scheduledEligibility=new Map;initialized=!1;actionQueue=Promise.resolve();async initialize(){if(this.initialized)return;const t=await this.storage.load();this.decisions=new Map(t.filter(v).map(e=>[this.getDecisionKey(e),e])),this.initialized=!0}isEligible(t,e=Date.now()){const i=this.scheduledEligibility.get(this.getExactKey(t));return i!==void 0&&i>e?!1:this.isDecisionEligible(this.decisions.get(this.getExactKey(t)),e)&&this.isDecisionEligible(this.decisions.get(this.getCategoryKey(t)),e)}getDecision(t){return this.decisions.get(this.getExactKey(t))??this.decisions.get(this.getCategoryKey(t))??null}getStatus(t,e=Date.now()){const i=this.scheduledEligibility.get(this.getExactKey(t));if(i!==void 0&&i>e)return"scheduled";const n=this.getDecision(t);return n?n.action==="never"||n.action==="dont_show_again"?"suppressed":n.action==="dismiss"?"resolved":n.nextEligibleAt&&Date.parse(n.nextEligibleAt)>e?"snoozed":"presentable":"presentable"}scheduleEligibility(t,e){const i=this.getExactKey(t),n=this.scheduledEligibility.get(i);return n!==void 0?n:(this.scheduledEligibility.set(i,e),e)}getNextEligibilityAt(t=Date.now()){for(const[i,n]of this.scheduledEligibility)n<=t&&this.scheduledEligibility.delete(i);const e=[...this.scheduledEligibility.values(),...Array.from(this.decisions.values()).map(i=>i.nextEligibleAt?Date.parse(i.nextEligibleAt):Number.NaN).filter(i=>Number.isFinite(i)&&i>t)];return e.length>0?Math.min(...e):null}act(t,e,i={}){const n=this.actionQueue.then(()=>this.applyAction(t,e,i));return this.actionQueue=n.then(()=>{},()=>{}),n}async applyAction(t,e,i){if(!t.allowedActions.includes(e))throw new Error(`Interaction ${t.key} does not allow ${e}.`);if(!I(e))throw new Error(`Interaction action ${e} is not a persistence decision.`);const n=i.now??new Date,r={promptKey:t.key,category:t.category,action:e,scope:t.scope,decidedAt:n.toISOString(),nextEligibleAt:this.getNextEligibleAt(t,e,n,i.snoozeUntil)},a=e==="dont_show_again"?this.getCategoryKey(t):this.getExactKey(t),l=new Map(this.decisions);return l.set(a,r),await this.storage.save([...l.values()]),this.decisions=l,r}isDecisionEligible(t,e){return t?t.action==="dismiss"||t.action==="never"||t.action==="dont_show_again"?!1:!t.nextEligibleAt||Date.parse(t.nextEligibleAt)<=e:!0}getNextEligibleAt(t,e,i,n){if(e==="later")return new Date(i.getTime()+(t.laterDelayMs??3600*1e3)).toISOString();if(e==="snooze"){if(!n||n.getTime()<=i.getTime())throw new Error("Snooze requires a future next-eligible time.");return n.toISOString()}return null}getDecisionKey(t){const e=f(t.scope);return t.action==="dont_show_again"?`${e}:category:${t.category}`:`${e}:interaction:${t.promptKey}`}getExactKey(t){return`${f(t.scope)}:interaction:${t.key}`}getCategoryKey(t){return`${f(t.scope)}:category:${t.category}`}}function L(s,t){return{load:async()=>w(s,t),save:async e=>s.setItem(t,JSON.stringify(e))}}function w(s,t){const e=s.getItem(t);if(!e)return[];const i=JSON.parse(e);return Array.isArray(i)?i.filter(v):[]}function f(s){return`${s.level}:${s.key}`}function I(s){return s==="dismiss"||s==="later"||s==="snooze"||s==="never"||s==="dont_show_again"}function v(s){if(!s||typeof s!="object")return!1;const t=s;return typeof t.promptKey=="string"&&typeof t.category=="string"&&typeof t.decidedAt=="string"&&(t.nextEligibleAt===null||typeof t.nextEligibleAt=="string")&&I(t.action)&&!!(t.scope&&typeof t.scope=="object"&&typeof t.scope.level=="string"&&typeof t.scope.key=="string")}const q={working:"⏳",completed:"✅",failed:"❗",stopped:"⏹️"},k=/^(?:⌛|⏳|✅|❗|⏹️) Pluno(?:: )?/;function T(s,t){if(!t)return p(s);const e=p(s),i=`${q[t]} Pluno`;return e?`${i}: ${e}`:i}class Q{constructor(t){this.titleDocument=t}titleDocument;status=null;baseTitle="";lastAppliedTitle=null;stopObserving=null;liveStatusVersion=0;setStatus(t){this.liveStatusVersion+=1,this.applyStatus(t)}clear(){this.liveStatusVersion+=1,this.applyClear()}async syncStatus(t){const e=this.liveStatusVersion,i=await t();i===void 0||e!==this.liveStatusVersion||(i?this.applyStatus(i):this.applyClear())}applyStatus(t){const e=this.titleDocument.getTitle();e!==this.lastAppliedTitle&&(this.baseTitle=p(e)),this.status=t,this.stopObserving||(this.stopObserving=this.titleDocument.observeTitle(()=>this.handleTitleChanged())),this.applyTitle()}applyClear(){const t=this.titleDocument.getTitle(),e=this.lastAppliedTitle!==null&&t===this.lastAppliedTitle,i=this.lastAppliedTitle===null?p(t):t;this.status=null,this.lastAppliedTitle=null,this.stopObserving?.(),this.stopObserving=null,e?this.titleDocument.setTitle(this.baseTitle):i!==t&&this.titleDocument.setTitle(i)}handleTitleChanged(){!this.status||this.titleDocument.getTitle()===this.lastAppliedTitle||this.applyTitle()}applyTitle(){if(!this.status)return;const t=T(this.baseTitle,this.status);this.lastAppliedTitle=t,this.titleDocument.getTitle()!==t&&this.titleDocument.setTitle(t)}}function $(s){return{getTitle:()=>s.title,setTitle:t=>{s.title=t},observeTitle:t=>{const e=new MutationObserver(t);return e.observe(s.head,{childList:!0,subtree:!0,characterData:!0}),()=>e.disconnect()}}}function p(s){return s.replace(k,"")}function K(s){if(!s||typeof s!="object"||!("type"in s))return!1;const t=s;switch(t.type){case"runtime.connect":case"session.new":case"run.stop":case"run.retry":return!0;case"runtime.warmup":return t.reason==="panel_open"||t.reason==="extension_install"||t.reason==="composer_input";case"runtime.widget_lifecycle":return(t.action==="opened"||t.action==="closed"||t.action==="minimized")&&typeof t.trigger=="string";case"session.load":return typeof t.sessionId=="string"&&t.sessionId.length>0;case"session.list":return(t.cursor===void 0||t.cursor===null||typeof t.cursor=="string")&&(t.limit===void 0||typeof t.limit=="number")&&(t.pinned===void 0||typeof t.pinned=="boolean");case"session.set_model":return typeof t.model=="string";case"session.pin":return typeof t.sessionId=="string"&&typeof t.pinned=="boolean";case"session.rename":return typeof t.sessionId=="string"&&typeof t.title=="string";case"interaction.act":return typeof t.interactionId=="string"&&typeof t.action=="string"&&typeof t.expectedRevision=="number";case"conversation.stage_proactive_suggestion":return typeof t.question=="string"&&typeof t.clientMessageId=="string";case"conversation.stage":return typeof t.content=="string"&&typeof t.clientMessageId=="string"&&(t.attachments===void 0||Array.isArray(t.attachments));case"conversation.fail_staged":return typeof t.clientMessageId=="string"&&typeof t.message=="string";case"conversation.send":return typeof t.content=="string"&&typeof t.clientMessageId=="string"&&(t.attachments===void 0||Array.isArray(t.attachments));default:return!1}}class F{constructor(t,e,i){this.adapter=e,this.state=y(t),this.model=i}adapter;listeners={};attachmentFiles=new Map;sessionHistoryListeners=new Set;interactionListeners=new Set;accountListeners=new Set;state;sessionHistoryState=d("unavailable");model;interactions=[];account=null;stagedProactiveSuggestionClientMessageId=null;operationQueue=Promise.resolve();destroyed=!1;on(t,e){const i=this.listeners[t]??new Set;return i.add(e),this.listeners[t]=i,()=>i.delete(e)}getState(){return y(this.state)}updateProjection(t,e,i,n,r){if(!this.destroyed){if(this.state=y(t),e!==void 0&&(this.model=e),i){this.sessionHistoryState=A(i);for(const a of this.sessionHistoryListeners)a(this.getSessionHistoryState())}if(n){this.interactions=n.map(a=>({...a}));for(const a of this.interactionListeners)a(this.getInteractions())}if(r!==void 0){this.account=r?{...r}:null;for(const a of this.accountListeners)a(this.getAccount())}this.emit("state",this.getState())}}async connect(){await this.dispatch({type:"runtime.connect"})}destroy(){if(!this.destroyed){this.destroyed=!0,this.attachmentFiles.clear(),this.sessionHistoryListeners.clear(),this.interactionListeners.clear(),this.accountListeners.clear();for(const t of Object.values(this.listeners))t?.clear();this.adapter.onDisconnect?.()}}warmup(t="panel_open"){return this.adapter.dispatch({type:"runtime.warmup",reason:t}).then(()=>{})}recordWidgetLifecycle(t,e){this.dispatch({type:"runtime.widget_lifecycle",action:t,trigger:e})}sendMessage(t,e={}){const i=t.trim(),n=e.attachments??[];if(!i&&n.length===0)return Promise.resolve(null);const r=e.clientMessageId??(e.proactiveSuggestionQuestion&&this.stagedProactiveSuggestionClientMessageId?this.stagedProactiveSuggestionClientMessageId:crypto.randomUUID()),a=this.state,l={id:`local-${r}`,role:"user",content:i,createdAt:new Date().toISOString(),...n.length>0?{attachments:n}:{},clientMessageId:r};return this.state={...this.state,messages:[...this.state.messages,l],pendingMessageStatus:"sending",turnPhase:this.state.isThinking?this.state.turnPhase:"sending",taskStatus:"working",isRetrying:!1,lastError:null},this.emit("state",this.getState()),this.enqueueOperation(()=>this.sendMessageNow(i,{...e,clientMessageId:r},a))}async sendMessageNow(t,e,i){const n=t,r=e.clientMessageId;let a=e.attachments??[],l=!1;try{if(await this.adapter.dispatch({type:"conversation.stage",content:n,clientMessageId:r,proactiveSuggestionQuestion:e.proactiveSuggestionQuestion,attachments:a.length>0?a:void 0}),l=!0,a.length>0){if(!this.adapter.uploadAttachment)throw new Error("The runtime does not support attachments.");const c=[];for(const u of a){if(u.sandboxPath||u.storageKey){c.push(u);continue}const b=u.id?this.attachmentFiles.get(u.id):void 0;if(!b)throw new Error(`Attachment bytes are unavailable for ${u.name}`);c.push(await this.adapter.uploadAttachment(b,u,{clientMessageId:r}))}a=c}const o=await this.adapter.dispatch({type:"conversation.send",content:n,clientMessageId:r,initiatedBy:e.initiatedBy,invocation:e.invocation,proactiveSuggestionQuestion:e.proactiveSuggestionQuestion,attachments:a.length>0?a:void 0});for(const c of e.attachments??[])c.id&&this.attachmentFiles.delete(c.id);return r===this.stagedProactiveSuggestionClientMessageId&&(this.stagedProactiveSuggestionClientMessageId=null),o?.clientMessageId??r}catch(o){throw this.state={...this.state,messages:this.state.messages.filter(c=>c.id!==`local-${r}`&&c.id!==`optimistic-user-message:${r}`),pendingMessageStatus:i.pendingMessageStatus,turnPhase:i.turnPhase,isThinking:i.isThinking,taskStatus:i.taskStatus},this.emit("state",this.getState()),l&&await this.adapter.dispatch({type:"conversation.fail_staged",clientMessageId:r,message:o instanceof Error?o.message:String(o)}),o}}getModel(){return this.model}setModel(t){return this.dispatch({type:"session.set_model",model:t}).then(()=>{})}retryLastMessage(){return this.dispatch({type:"run.retry"}),!0}createLocalAttachment(t){const e=crypto.randomUUID();return this.attachmentFiles.set(e,t),{id:e,name:t.name||"attachment",mimeType:t.type||"application/octet-stream",sizeBytes:t.size}}stop(){return this.dispatch({type:"run.stop"}).then(()=>{})}startNewSession(t={}){return t.notifyTransport===!1?Promise.resolve():this.dispatch({type:"session.new"}).then(()=>{})}async listSessions(t={}){await this.dispatch({type:"session.list",...t});const e=this.sessionHistoryState.data;return{sessions:S(e),nextCursor:e?.nextCursor??null}}getSessionHistoryState(){return A(this.sessionHistoryState)}subscribeSessionHistory(t){return this.sessionHistoryListeners.add(t),t(this.getSessionHistoryState()),()=>this.sessionHistoryListeners.delete(t)}refreshSessionHistory(){return this.dispatch({type:"session.list",limit:20}).then(()=>{})}loadMoreSessionHistory(){const t=this.sessionHistoryState.data?.nextCursor??null;return t?this.dispatch({type:"session.list",cursor:t,limit:20}).then(()=>{}):Promise.resolve()}setSessionPinned(t,e){return this.dispatch({type:"session.pin",sessionId:t,pinned:e}).then(()=>{})}renameSession(t,e){return this.dispatch({type:"session.rename",sessionId:t,title:e}).then(()=>{})}getInteractions(){return this.interactions.map(t=>({...t}))}subscribeInteractions(t){return this.interactionListeners.add(t),t(this.getInteractions()),()=>this.interactionListeners.delete(t)}actOnInteraction(t,e,i,n={}){return this.dispatch({type:"interaction.act",interactionId:t,action:e,expectedRevision:i,...n}).then(()=>{})}getAccount(){return this.account?{...this.account}:null}subscribeAccount(t){return this.accountListeners.add(t),t(this.getAccount()),()=>this.accountListeners.delete(t)}refreshAccount(){return Promise.resolve()}loadSession(t){return this.dispatch({type:"session.load",sessionId:t}).then(()=>{})}stageProactiveSuggestionQuestion(t){const e=t.trim();if(!e)return Promise.resolve();const i=this.stagedProactiveSuggestionClientMessageId??crypto.randomUUID();return this.stagedProactiveSuggestionClientMessageId=i,this.dispatch({type:"conversation.stage_proactive_suggestion",question:e,clientMessageId:i}).then(()=>{})}dispatch(t){return this.enqueueOperation(()=>this.adapter.dispatch(t))}enqueueOperation(t){const e=this.operationQueue.then(t);return this.operationQueue=e.then(()=>{},()=>{}),e}emit(t,e){const i=this.listeners[t];for(const n of i??[])n(e)}}function y(s){return{...s,starterPrompts:[...s.starterPrompts],appearance:s.appearance?{...s.appearance}:null,messages:s.messages.map(t=>{const e={...t,attachments:t.attachments?.map(r=>({...r}))},i=t.assistantDraftItemId,n=t.clientMessageId;return i&&Object.defineProperty(e,"assistantDraftItemId",{value:i,enumerable:!1}),n&&Object.defineProperty(e,"clientMessageId",{value:n,enumerable:!1}),e}),activeScheduledFollowUps:s.activeScheduledFollowUps?.map(t=>({...t}))??null}}function A(s){return{...s,data:s.data?h({entities:S(s.data).map(t=>({...t})),nextCursor:s.data.nextCursor}):null}}exports.ProductAgentInteractionManager=R;exports.ProductAgentQueryController=m;exports.ProductAgentRemoteRuntimeClient=F;exports.ProductAgentSessionHistoryManager=x;exports.ProductAgentTaskPageTitleController=Q;exports.createLocalStorageInteractionDecisionStorage=L;exports.createProductAgentQueryState=d;exports.createProductAgentTaskPageTitleDocument=$;exports.formatProductAgentTaskPageTitle=T;exports.hasProductAgentPaidCreditFallback=O;exports.isProductAgentRuntimeCommand=K;exports.mergeProductAgentEntityPages=P;exports.normalizeProductAgentEntityPage=h;exports.readLocalStorageInteractionDecisions=w;exports.reconcileProductAgentSubmissionGate=M;exports.resolveProductAgentBillingPresentation=_;exports.resolveProductAgentComposerAction=D;exports.resolveProductAgentWidgetPresentation=E;exports.selectProductAgentQueryEntities=S;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function u(s){return{key:s,status:"not_requested",data:null,error:null,requestId:0,updatedAt:null}}class m{constructor(t,e,i=(n,r)=>r){this.loader=e,this.merge=i,this.state=u(t)}loader;merge;state;listeners=new Set;inFlight=null;trailingLoad=null;getState(){return this.state}subscribe(t){return this.listeners.add(t),t(this.state),()=>this.listeners.delete(t)}setKey(t){t!==this.state.key&&(this.state=u(t),this.trailingLoad=null,this.publish())}reset(){this.state=u(this.state.key),this.trailingLoad=null,this.publish()}invalidate(){this.state={...this.state,status:this.state.data===null?"not_requested":"ready",updatedAt:null},this.publish()}load(t="replace",e=null){return this.trailingLoad={mode:t,cursor:e},this.inFlight?this.inFlight:(this.inFlight=this.runLoads().finally(()=>{this.inFlight=null}),this.inFlight)}update(t){this.state={...this.state,data:t(this.state.data)},this.publish()}async runLoads(){for(;this.trailingLoad;){const t=this.trailingLoad;this.trailingLoad=null;const e=this.state.key,i=this.state.requestId+1;this.state={...this.state,status:t.mode==="append"?"loading_more":this.state.data===null?"loading":"refreshing",error:null,requestId:i},this.publish();try{const n=await this.loader({key:e,cursor:t.cursor});if(e!==this.state.key||i!==this.state.requestId)continue;this.state={...this.state,status:"ready",data:this.merge(this.state.data,n,t.mode),error:null,updatedAt:Date.now()},this.publish()}catch(n){if(e!==this.state.key||i!==this.state.requestId)continue;this.state={...this.state,status:"error",error:n instanceof Error?n.message:"The query failed."},this.publish()}}}publish(){for(const t of this.listeners)t(this.state)}}function h(s){const t={},e=[];for(const i of s.entities)t[i.id]||e.push(i.id),t[i.id]=i;return{entitiesById:t,ids:e,nextCursor:s.nextCursor}}function P(s,t,e){if(e==="replace"||s===null)return t;const i={...s.entitiesById,...t.entitiesById},n=[...s.ids];for(const r of t.ids)s.entitiesById[r]||n.push(r);return{entitiesById:i,ids:n,nextCursor:t.nextCursor}}function b(s){return s?s.ids.map(t=>s.entitiesById[t]).filter(t=>!!t):[]}function T(s){return s.visible?s.minimized?{state:"minimized"}:{state:s.open?"visible_open":"visible_closed"}:{state:"hidden"}}function E(s,t){return t==="limit_exceeded"?{allowed:!1,reason:"credits_exhausted",actions:["upgrade","earn_credits"]}:t==="subscription_required"||t==="subscription_inactive"||t==="payment_issue"||t==="subscription_invalid"||t==="payment_required"?{allowed:!1,reason:"payment_issue",actions:["upgrade"]}:s??{allowed:!0,reason:"allowed",actions:[]}}function M(s){if(!s||typeof s!="object")return!1;const t=s.paidCreditFallbackModel;return typeof t=="string"&&t.length>0}function O(s){return s?s.submissionGate?.allowed===!1?{state:"action_required",reason:s.submissionGate.reason}:s.usingPaidCreditFallback===!0?{state:"paid_credit_fallback"}:s.creditLimit!==null&&s.creditLimit>0&&s.creditsRemaining!==null&&s.creditsRemaining>0&&s.creditsRemaining/s.creditLimit<=.2?{state:"low_credits"}:s.creditsUsed!==null?{state:"usage"}:{state:"hidden"}:{state:"hidden"}}function D(s){const t=s.hasDraftMessage||s.hasPreSubmittedAttachment;return s.hasRunningAssistantTurn&&!t?{action:"stop",disabled:!s.canStopRunningTurn}:{action:"send",disabled:!t||!s.canSubmitMessage}}class x{constructor(t,e,i=20){this.loadPage=e,this.limit=i,this.recentQuery=new m(`${t}:recent`,async({cursor:n})=>h(await this.loadPage({cursor:n,limit:this.limit,pinned:!1}).then(r=>({entities:r.sessions,nextCursor:r.nextCursor}))),P),this.pinnedQuery=new m(`${t}:pinned`,async()=>h({entities:await this.loadAllPinned(),nextCursor:null})),this.recentQuery.subscribe(()=>this.publish()),this.pinnedQuery.subscribe(()=>this.publish())}loadPage;limit;recentQuery;pinnedQuery;listeners=new Set;optimisticEntities=new Map;activityOverrides=new Map;pinnedOverrides=new Map;titleOverrides=new Map;refreshSequence=0;completedRefreshSequence=0;activityReconciliationScheduled=!1;getState(){const t=this.recentQuery.getState(),e=this.pinnedQuery.getState(),i=[...g(e.data),...g(t.data)],n=new Map(i.map(o=>[o.id,o])),r=Array.from(n.values()).map(o=>this.applyOverrides(o,this.completedRefreshSequence)),a=Array.from(this.optimisticEntities.values()).filter(o=>!n.has(o.id)).reverse(),l=t.data||e.data||a.length>0?h({entities:[...a,...r],nextCursor:t.data?.nextCursor??null}):null;return{key:t.key.slice(0,-7),status:C(t,e),data:l,error:t.error??e.error,requestId:Math.max(t.requestId,e.requestId),updatedAt:Math.max(t.updatedAt??0,e.updatedAt??0)||null}}subscribe(t){return this.listeners.add(t),t(this.getState()),()=>this.listeners.delete(t)}getEntity(t){return this.getState().data?.entitiesById[t]??null}setKey(t){this.optimisticEntities.clear(),this.activityOverrides.clear(),this.pinnedOverrides.clear(),this.titleOverrides.clear(),this.refreshSequence=0,this.completedRefreshSequence=0,this.activityReconciliationScheduled=!1,this.recentQuery.setKey(`${t}:recent`),this.pinnedQuery.setKey(`${t}:pinned`)}refresh(){const t=++this.refreshSequence,e=Promise.all([this.recentQuery.load("replace"),this.pinnedQuery.load("replace")]).then(()=>{this.completedRefreshSequence=Math.max(this.completedRefreshSequence,t),this.reconcileDurableEntities()});return e.then(()=>{!this.hasUnconfirmedActivityOverride()||this.activityReconciliationScheduled||(this.activityReconciliationScheduled=!0,this.refresh().finally(()=>{this.activityReconciliationScheduled=!1}))}),e}loadMore(t){return this.recentQuery.load("append",t)}addOptimistic(t){this.optimisticEntities.set(t.id,t),this.updateProjection()}removeOptimistic(t){this.optimisticEntities.delete(t)&&this.updateProjection()}acknowledgeOptimistic(t,e){this.optimisticEntities.delete(t),this.optimisticEntities.set(e.id,e),this.updateProjection()}setActivity(t,e){this.activityOverrides.set(t,{isActive:e,confirmAfterRefresh:this.completedRefreshSequence+1,releaseAfterRefresh:this.completedRefreshSequence+2}),this.updateEntity(t,i=>({...i,isActive:e}))}setPinned(t,e){const i={pinned:e,confirmAfterRefresh:Number.POSITIVE_INFINITY};return this.pinnedOverrides.set(t,i),this.updateEntity(t,n=>({...n,isPinned:e})),i}confirmPinned(t,e){this.pinnedOverrides.get(t)===e&&(e.confirmAfterRefresh=this.completedRefreshSequence+1)}rollbackPinned(t,e,i){this.pinnedOverrides.get(t)===e&&(this.pinnedOverrides.delete(t),this.updateEntity(t,n=>({...n,isPinned:i})))}setTitle(t,e){this.titleOverrides.set(t,e),this.updateEntity(t,i=>({...i,customTitle:e}))}confirmTitle(t){this.titleOverrides.delete(t)}reconcileDurableEntities(){const t=[...g(this.pinnedQuery.getState().data),...g(this.recentQuery.getState().data)],e=new Set(t.map(i=>i.id));for(const i of this.optimisticEntities.keys())e.has(i)&&this.optimisticEntities.delete(i);for(const i of t)this.applyOverrides(i,this.completedRefreshSequence);this.publish()}async loadAllPinned(){const t=[];let e=null;do{const i=await this.loadPage({cursor:e,limit:this.limit,pinned:!0});t.push(...i.sessions),e=i.nextCursor}while(e);return t}applyOverrides(t,e){let i=t;const n=this.activityOverrides.get(t.id);n&&(e>=n.confirmAfterRefresh&&t.isActive===n.isActive?this.activityOverrides.delete(t.id):e>=n.releaseAfterRefresh?this.activityOverrides.delete(t.id):i={...i,isActive:n.isActive});const r=this.pinnedOverrides.get(t.id);return r&&(e>=r.confirmAfterRefresh&&t.isPinned===!0===r.pinned?this.pinnedOverrides.delete(t.id):i={...i,isPinned:r.pinned}),this.titleOverrides.has(t.id)&&(i={...i,customTitle:this.titleOverrides.get(t.id)??null}),i}updateProjection(){this.publish()}updateEntity(t,e){const i=this.optimisticEntities.get(t);i&&this.optimisticEntities.set(t,e(i)),this.publish()}hasUnconfirmedActivityOverride(){return Array.from(this.activityOverrides.values()).some(t=>this.completedRefreshSequence<t.releaseAfterRefresh)}publish(){for(const t of this.listeners)t(this.getState())}}function g(s){return s?s.ids.map(t=>s.entitiesById[t]).filter(t=>!!t):[]}function C(s,t){return s.status==="error"||t.status==="error"?"error":s.status==="loading"||t.status==="loading"?"loading":s.status==="refreshing"||t.status==="refreshing"?"refreshing":s.status==="loading_more"?"loading_more":s.status==="ready"||t.status==="ready"?"ready":"not_requested"}class R{constructor(t,e=null){this.storage=t,e&&(this.decisions=new Map(e.filter(v).map(i=>[this.getDecisionKey(i),i])),this.initialized=!0)}storage;decisions=new Map;scheduledEligibility=new Map;initialized=!1;actionQueue=Promise.resolve();async initialize(){if(this.initialized)return;const t=await this.storage.load();this.decisions=new Map(t.filter(v).map(e=>[this.getDecisionKey(e),e])),this.initialized=!0}isEligible(t,e=Date.now()){const i=this.scheduledEligibility.get(this.getExactKey(t));return i!==void 0&&i>e?!1:this.isDecisionEligible(this.decisions.get(this.getExactKey(t)),e)&&this.isDecisionEligible(this.decisions.get(this.getCategoryKey(t)),e)}getDecision(t){return this.decisions.get(this.getExactKey(t))??this.decisions.get(this.getCategoryKey(t))??null}getStatus(t,e=Date.now()){const i=this.scheduledEligibility.get(this.getExactKey(t));if(i!==void 0&&i>e)return"scheduled";const n=this.getDecision(t);return n?n.action==="never"||n.action==="dont_show_again"?"suppressed":n.action==="dismiss"?"resolved":n.nextEligibleAt&&Date.parse(n.nextEligibleAt)>e?"snoozed":"presentable":"presentable"}scheduleEligibility(t,e){const i=this.getExactKey(t),n=this.scheduledEligibility.get(i);return n!==void 0?n:(this.scheduledEligibility.set(i,e),e)}getNextEligibilityAt(t=Date.now()){for(const[i,n]of this.scheduledEligibility)n<=t&&this.scheduledEligibility.delete(i);const e=[...this.scheduledEligibility.values(),...Array.from(this.decisions.values()).map(i=>i.nextEligibleAt?Date.parse(i.nextEligibleAt):Number.NaN).filter(i=>Number.isFinite(i)&&i>t)];return e.length>0?Math.min(...e):null}act(t,e,i={}){const n=this.actionQueue.then(()=>this.applyAction(t,e,i));return this.actionQueue=n.then(()=>{},()=>{}),n}async applyAction(t,e,i){if(!t.allowedActions.includes(e))throw new Error(`Interaction ${t.key} does not allow ${e}.`);if(!I(e))throw new Error(`Interaction action ${e} is not a persistence decision.`);const n=i.now??new Date,r={promptKey:t.key,category:t.category,action:e,scope:t.scope,decidedAt:n.toISOString(),nextEligibleAt:this.getNextEligibleAt(t,e,n,i.snoozeUntil)},a=e==="dont_show_again"?this.getCategoryKey(t):this.getExactKey(t),l=new Map(this.decisions);return l.set(a,r),await this.storage.save([...l.values()]),this.decisions=l,r}isDecisionEligible(t,e){return t?t.action==="dismiss"||t.action==="never"||t.action==="dont_show_again"?!1:!t.nextEligibleAt||Date.parse(t.nextEligibleAt)<=e:!0}getNextEligibleAt(t,e,i,n){if(e==="later")return new Date(i.getTime()+(t.laterDelayMs??3600*1e3)).toISOString();if(e==="snooze"){if(!n||n.getTime()<=i.getTime())throw new Error("Snooze requires a future next-eligible time.");return n.toISOString()}return null}getDecisionKey(t){const e=f(t.scope);return t.action==="dont_show_again"?`${e}:category:${t.category}`:`${e}:interaction:${t.promptKey}`}getExactKey(t){return`${f(t.scope)}:interaction:${t.key}`}getCategoryKey(t){return`${f(t.scope)}:category:${t.category}`}}function L(s,t){return{load:async()=>w(s,t),save:async e=>s.setItem(t,JSON.stringify(e))}}function w(s,t){const e=s.getItem(t);if(!e)return[];const i=JSON.parse(e);return Array.isArray(i)?i.filter(v):[]}function f(s){return`${s.level}:${s.key}`}function I(s){return s==="dismiss"||s==="later"||s==="snooze"||s==="never"||s==="dont_show_again"}function v(s){if(!s||typeof s!="object")return!1;const t=s;return typeof t.promptKey=="string"&&typeof t.category=="string"&&typeof t.decidedAt=="string"&&(t.nextEligibleAt===null||typeof t.nextEligibleAt=="string")&&I(t.action)&&!!(t.scope&&typeof t.scope=="object"&&typeof t.scope.level=="string"&&typeof t.scope.key=="string")}const q={working:"⏳",completed:"✅",failed:"❗",stopped:"⏹️"},k=/^(?:⌛|⏳|✅|❗|⏹️) Pluno(?:: )?/;function _(s,t){if(!t)return p(s);const e=p(s),i=`${q[t]} Pluno`;return e?`${i}: ${e}`:i}class Q{constructor(t){this.titleDocument=t}titleDocument;status=null;baseTitle="";lastAppliedTitle=null;stopObserving=null;liveStatusVersion=0;setStatus(t){this.liveStatusVersion+=1,this.applyStatus(t)}clear(){this.liveStatusVersion+=1,this.applyClear()}async syncStatus(t){const e=this.liveStatusVersion,i=await t();i===void 0||e!==this.liveStatusVersion||(i?this.applyStatus(i):this.applyClear())}applyStatus(t){const e=this.titleDocument.getTitle();e!==this.lastAppliedTitle&&(this.baseTitle=p(e)),this.status=t,this.stopObserving||(this.stopObserving=this.titleDocument.observeTitle(()=>this.handleTitleChanged())),this.applyTitle()}applyClear(){const t=this.titleDocument.getTitle(),e=this.lastAppliedTitle!==null&&t===this.lastAppliedTitle,i=this.lastAppliedTitle===null?p(t):t;this.status=null,this.lastAppliedTitle=null,this.stopObserving?.(),this.stopObserving=null,e?this.titleDocument.setTitle(this.baseTitle):i!==t&&this.titleDocument.setTitle(i)}handleTitleChanged(){!this.status||this.titleDocument.getTitle()===this.lastAppliedTitle||this.applyTitle()}applyTitle(){if(!this.status)return;const t=_(this.baseTitle,this.status);this.lastAppliedTitle=t,this.titleDocument.getTitle()!==t&&this.titleDocument.setTitle(t)}}function $(s){return{getTitle:()=>s.title,setTitle:t=>{s.title=t},observeTitle:t=>{const e=new MutationObserver(t);return e.observe(s.head,{childList:!0,subtree:!0,characterData:!0}),()=>e.disconnect()}}}function p(s){return s.replace(k,"")}function K(s){if(!s||typeof s!="object"||!("type"in s))return!1;const t=s;switch(t.type){case"runtime.connect":case"session.new":case"run.stop":case"run.retry":return!0;case"runtime.warmup":return t.reason==="panel_open"||t.reason==="extension_install"||t.reason==="composer_input";case"runtime.report_displayed_error":return(t.reason==="conversation_error"||t.reason==="attachment_error"||t.reason==="history_error"||t.reason==="action_error")&&typeof t.errorFingerprint=="string"&&/^fnv1a-[0-9a-f]{8}$/.test(t.errorFingerprint);case"runtime.report_invalid_state_transition":return(t.reason==="submitted_turn_returned_to_welcome_without_new_chat"||t.reason==="new_messages_button_without_user_scroll")&&(t.clientMessageId===void 0||typeof t.clientMessageId=="string");case"runtime.widget_lifecycle":return(t.action==="opened"||t.action==="closed"||t.action==="minimized")&&typeof t.trigger=="string";case"session.load":return typeof t.sessionId=="string"&&t.sessionId.length>0;case"session.list":return(t.cursor===void 0||t.cursor===null||typeof t.cursor=="string")&&(t.limit===void 0||typeof t.limit=="number")&&(t.pinned===void 0||typeof t.pinned=="boolean");case"session.set_model":return typeof t.model=="string";case"session.pin":return typeof t.sessionId=="string"&&typeof t.pinned=="boolean";case"session.rename":return typeof t.sessionId=="string"&&typeof t.title=="string";case"interaction.act":return typeof t.interactionId=="string"&&typeof t.action=="string"&&typeof t.expectedRevision=="number";case"conversation.stage_proactive_suggestion":return typeof t.question=="string"&&typeof t.clientMessageId=="string";case"conversation.stage":return typeof t.content=="string"&&typeof t.clientMessageId=="string"&&(t.submittedAt===void 0||typeof t.submittedAt=="number")&&(t.attachments===void 0||Array.isArray(t.attachments));case"conversation.fail_staged":return typeof t.clientMessageId=="string"&&typeof t.message=="string";case"conversation.send":return typeof t.content=="string"&&typeof t.clientMessageId=="string"&&(t.attachments===void 0||Array.isArray(t.attachments));default:return!1}}class F{constructor(t,e,i){this.adapter=e,this.state=y(t),this.model=i}adapter;listeners={};attachmentFiles=new Map;sessionHistoryListeners=new Set;interactionListeners=new Set;accountListeners=new Set;state;sessionHistoryState=u("unavailable");model;interactions=[];account=null;stagedProactiveSuggestionClientMessageId=null;operationQueue=Promise.resolve();destroyed=!1;on(t,e){const i=this.listeners[t]??new Set;return i.add(e),this.listeners[t]=i,()=>i.delete(e)}getState(){return y(this.state)}updateProjection(t,e,i,n,r){if(!this.destroyed){if(this.state=y(t),e!==void 0&&(this.model=e),i){this.sessionHistoryState=A(i);for(const a of this.sessionHistoryListeners)a(this.getSessionHistoryState())}if(n){this.interactions=n.map(a=>({...a}));for(const a of this.interactionListeners)a(this.getInteractions())}if(r!==void 0){this.account=r?{...r}:null;for(const a of this.accountListeners)a(this.getAccount())}this.emit("state",this.getState())}}async connect(){await this.dispatch({type:"runtime.connect"})}destroy(){if(!this.destroyed){this.destroyed=!0,this.attachmentFiles.clear(),this.sessionHistoryListeners.clear(),this.interactionListeners.clear(),this.accountListeners.clear();for(const t of Object.values(this.listeners))t?.clear();this.adapter.onDisconnect?.()}}warmup(t="panel_open"){return this.adapter.dispatch({type:"runtime.warmup",reason:t}).then(()=>{})}recordWidgetLifecycle(t,e){this.dispatch({type:"runtime.widget_lifecycle",action:t,trigger:e})}reportInvalidStateTransition(t,e){this.adapter.dispatch({type:"runtime.report_invalid_state_transition",reason:t,clientMessageId:e}).catch(()=>{})}reportDisplayedError(t,e){this.adapter.dispatch({type:"runtime.report_displayed_error",reason:t,errorFingerprint:e}).catch(()=>{})}sendMessage(t,e={}){const i=t.trim(),n=e.attachments??[];if(!i&&n.length===0)return Promise.resolve(null);const r=e.clientMessageId??(e.proactiveSuggestionQuestion&&this.stagedProactiveSuggestionClientMessageId?this.stagedProactiveSuggestionClientMessageId:crypto.randomUUID()),a=e.submittedAt??Date.now(),l=this.state,o={id:`local-${r}`,role:"user",content:i,createdAt:new Date().toISOString(),...n.length>0?{attachments:n}:{},clientMessageId:r};return this.state={...this.state,messages:[...this.state.messages,o],pendingMessageStatus:"sending",turnPhase:this.state.isThinking?this.state.turnPhase:"sending",taskStatus:"working",isRetrying:!1,lastError:null},this.emit("state",this.getState()),this.enqueueOperation(()=>this.sendMessageNow(i,{...e,clientMessageId:r,submittedAt:a},l))}async sendMessageNow(t,e,i){const n=t,r=e.clientMessageId;let a=e.attachments??[],l=!1;try{if(await this.adapter.dispatch({type:"conversation.stage",content:n,clientMessageId:r,proactiveSuggestionQuestion:e.proactiveSuggestionQuestion,attachments:a.length>0?a:void 0,submittedAt:e.submittedAt}),l=!0,a.length>0){if(!this.adapter.uploadAttachment)throw new Error("The runtime does not support attachments.");const c=[];for(const d of a){if(d.sandboxPath||d.storageKey){c.push(d);continue}const S=d.id?this.attachmentFiles.get(d.id):void 0;if(!S)throw new Error(`Attachment bytes are unavailable for ${d.name}`);c.push(await this.adapter.uploadAttachment(S,d,{clientMessageId:r}))}a=c}const o=await this.adapter.dispatch({type:"conversation.send",content:n,clientMessageId:r,initiatedBy:e.initiatedBy,invocation:e.invocation,proactiveSuggestionQuestion:e.proactiveSuggestionQuestion,attachments:a.length>0?a:void 0});for(const c of e.attachments??[])c.id&&this.attachmentFiles.delete(c.id);return r===this.stagedProactiveSuggestionClientMessageId&&(this.stagedProactiveSuggestionClientMessageId=null),o?.clientMessageId??r}catch(o){throw this.state={...this.state,messages:this.state.messages.filter(c=>c.id!==`local-${r}`&&c.id!==`optimistic-user-message:${r}`),pendingMessageStatus:i.pendingMessageStatus,turnPhase:i.turnPhase,isThinking:i.isThinking,taskStatus:i.taskStatus},this.emit("state",this.getState()),l&&await this.adapter.dispatch({type:"conversation.fail_staged",clientMessageId:r,message:o instanceof Error?o.message:String(o)}),o}}getModel(){return this.model}setModel(t){return this.dispatch({type:"session.set_model",model:t}).then(()=>{})}retryLastMessage(){return this.dispatch({type:"run.retry"}),!0}createLocalAttachment(t){const e=crypto.randomUUID();return this.attachmentFiles.set(e,t),{id:e,name:t.name||"attachment",mimeType:t.type||"application/octet-stream",sizeBytes:t.size}}stop(){return this.dispatch({type:"run.stop"}).then(()=>{})}startNewSession(t={}){return t.notifyTransport===!1?Promise.resolve():this.dispatch({type:"session.new"}).then(()=>{})}async listSessions(t={}){await this.dispatch({type:"session.list",...t});const e=this.sessionHistoryState.data;return{sessions:b(e),nextCursor:e?.nextCursor??null}}getSessionHistoryState(){return A(this.sessionHistoryState)}subscribeSessionHistory(t){return this.sessionHistoryListeners.add(t),t(this.getSessionHistoryState()),()=>this.sessionHistoryListeners.delete(t)}refreshSessionHistory(){return this.dispatch({type:"session.list",limit:20}).then(()=>{})}loadMoreSessionHistory(){const t=this.sessionHistoryState.data?.nextCursor??null;return t?this.dispatch({type:"session.list",cursor:t,limit:20}).then(()=>{}):Promise.resolve()}setSessionPinned(t,e){return this.dispatch({type:"session.pin",sessionId:t,pinned:e}).then(()=>{})}renameSession(t,e){return this.dispatch({type:"session.rename",sessionId:t,title:e}).then(()=>{})}getInteractions(){return this.interactions.map(t=>({...t}))}subscribeInteractions(t){return this.interactionListeners.add(t),t(this.getInteractions()),()=>this.interactionListeners.delete(t)}actOnInteraction(t,e,i,n={}){return this.dispatch({type:"interaction.act",interactionId:t,action:e,expectedRevision:i,...n}).then(()=>{})}getAccount(){return this.account?{...this.account}:null}subscribeAccount(t){return this.accountListeners.add(t),t(this.getAccount()),()=>this.accountListeners.delete(t)}refreshAccount(){return Promise.resolve()}loadSession(t){return this.dispatch({type:"session.load",sessionId:t}).then(()=>{})}stageProactiveSuggestionQuestion(t){const e=t.trim();if(!e)return Promise.resolve();const i=this.stagedProactiveSuggestionClientMessageId??crypto.randomUUID();return this.stagedProactiveSuggestionClientMessageId=i,this.dispatch({type:"conversation.stage_proactive_suggestion",question:e,clientMessageId:i}).then(()=>{})}dispatch(t){return this.enqueueOperation(()=>this.adapter.dispatch(t))}enqueueOperation(t){const e=this.operationQueue.then(t);return this.operationQueue=e.then(()=>{},()=>{}),e}emit(t,e){const i=this.listeners[t];for(const n of i??[])n(e)}}function y(s){return{...s,starterPrompts:[...s.starterPrompts],appearance:s.appearance?{...s.appearance}:null,messages:s.messages.map(t=>{const e={...t,attachments:t.attachments?.map(r=>({...r}))},i=t.assistantDraftItemId,n=t.clientMessageId;return i&&Object.defineProperty(e,"assistantDraftItemId",{value:i,enumerable:!1}),n&&Object.defineProperty(e,"clientMessageId",{value:n,enumerable:!1}),e}),activeScheduledFollowUps:s.activeScheduledFollowUps?.map(t=>({...t}))??null}}function A(s){return{...s,data:s.data?h({entities:b(s.data).map(t=>({...t})),nextCursor:s.data.nextCursor}):null}}exports.ProductAgentInteractionManager=R;exports.ProductAgentQueryController=m;exports.ProductAgentRemoteRuntimeClient=F;exports.ProductAgentSessionHistoryManager=x;exports.ProductAgentTaskPageTitleController=Q;exports.createLocalStorageInteractionDecisionStorage=L;exports.createProductAgentQueryState=u;exports.createProductAgentTaskPageTitleDocument=$;exports.formatProductAgentTaskPageTitle=_;exports.hasProductAgentPaidCreditFallback=M;exports.isProductAgentRuntimeCommand=K;exports.mergeProductAgentEntityPages=P;exports.normalizeProductAgentEntityPage=h;exports.readLocalStorageInteractionDecisions=w;exports.reconcileProductAgentSubmissionGate=E;exports.resolveProductAgentBillingPresentation=O;exports.resolveProductAgentComposerAction=D;exports.resolveProductAgentWidgetPresentation=T;exports.selectProductAgentQueryEntities=b;
|
|
@@ -103,7 +103,7 @@ function P(s, t, e) {
|
|
|
103
103
|
function A(s) {
|
|
104
104
|
return s ? s.ids.map((t) => s.entitiesById[t]).filter((t) => !!t) : [];
|
|
105
105
|
}
|
|
106
|
-
function
|
|
106
|
+
function O(s) {
|
|
107
107
|
return s.visible ? s.minimized ? { state: "minimized" } : { state: s.open ? "visible_open" : "visible_closed" } : { state: "hidden" };
|
|
108
108
|
}
|
|
109
109
|
function x(s, t) {
|
|
@@ -160,8 +160,8 @@ class q {
|
|
|
160
160
|
activityReconciliationScheduled = !1;
|
|
161
161
|
getState() {
|
|
162
162
|
const t = this.recentQuery.getState(), e = this.pinnedQuery.getState(), i = [
|
|
163
|
-
...
|
|
164
|
-
...
|
|
163
|
+
...u(e.data),
|
|
164
|
+
...u(t.data)
|
|
165
165
|
], n = new Map(i.map((o) => [o.id, o])), r = Array.from(n.values()).map(
|
|
166
166
|
(o) => this.applyOverrides(o, this.completedRefreshSequence)
|
|
167
167
|
), a = Array.from(this.optimisticEntities.values()).filter((o) => !n.has(o.id)).reverse(), l = t.data || e.data || a.length > 0 ? p({
|
|
@@ -170,7 +170,7 @@ class q {
|
|
|
170
170
|
}) : null;
|
|
171
171
|
return {
|
|
172
172
|
key: t.key.slice(0, -7),
|
|
173
|
-
status:
|
|
173
|
+
status: _(t, e),
|
|
174
174
|
data: l,
|
|
175
175
|
error: t.error ?? e.error,
|
|
176
176
|
requestId: Math.max(t.requestId, e.requestId),
|
|
@@ -236,8 +236,8 @@ class q {
|
|
|
236
236
|
}
|
|
237
237
|
reconcileDurableEntities() {
|
|
238
238
|
const t = [
|
|
239
|
-
...
|
|
240
|
-
...
|
|
239
|
+
...u(this.pinnedQuery.getState().data),
|
|
240
|
+
...u(this.recentQuery.getState().data)
|
|
241
241
|
], e = new Set(t.map((i) => i.id));
|
|
242
242
|
for (const i of this.optimisticEntities.keys())
|
|
243
243
|
e.has(i) && this.optimisticEntities.delete(i);
|
|
@@ -276,10 +276,10 @@ class q {
|
|
|
276
276
|
for (const t of this.listeners) t(this.getState());
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
|
-
function
|
|
279
|
+
function u(s) {
|
|
280
280
|
return s ? s.ids.map((t) => s.entitiesById[t]).filter((t) => !!t) : [];
|
|
281
281
|
}
|
|
282
|
-
function
|
|
282
|
+
function _(s, t) {
|
|
283
283
|
return s.status === "error" || t.status === "error" ? "error" : s.status === "loading" || t.status === "loading" ? "loading" : s.status === "refreshing" || t.status === "refreshing" ? "refreshing" : s.status === "loading_more" ? "loading_more" : s.status === "ready" || t.status === "ready" ? "ready" : "not_requested";
|
|
284
284
|
}
|
|
285
285
|
class L {
|
|
@@ -373,11 +373,11 @@ class L {
|
|
|
373
373
|
}
|
|
374
374
|
function Q(s, t) {
|
|
375
375
|
return {
|
|
376
|
-
load: async () =>
|
|
376
|
+
load: async () => I(s, t),
|
|
377
377
|
save: async (e) => s.setItem(t, JSON.stringify(e))
|
|
378
378
|
};
|
|
379
379
|
}
|
|
380
|
-
function
|
|
380
|
+
function I(s, t) {
|
|
381
381
|
const e = s.getItem(t);
|
|
382
382
|
if (!e) return [];
|
|
383
383
|
const i = JSON.parse(e);
|
|
@@ -394,15 +394,15 @@ function m(s) {
|
|
|
394
394
|
const t = s;
|
|
395
395
|
return typeof t.promptKey == "string" && typeof t.category == "string" && typeof t.decidedAt == "string" && (t.nextEligibleAt === null || typeof t.nextEligibleAt == "string") && w(t.action) && !!(t.scope && typeof t.scope == "object" && typeof t.scope.level == "string" && typeof t.scope.key == "string");
|
|
396
396
|
}
|
|
397
|
-
const
|
|
397
|
+
const E = {
|
|
398
398
|
working: "⏳",
|
|
399
399
|
completed: "✅",
|
|
400
400
|
failed: "❗",
|
|
401
401
|
stopped: "⏹️"
|
|
402
|
-
},
|
|
403
|
-
function
|
|
402
|
+
}, T = /^(?:⌛|⏳|✅|❗|⏹️) Pluno(?:: )?/;
|
|
403
|
+
function M(s, t) {
|
|
404
404
|
if (!t) return g(s);
|
|
405
|
-
const e = g(s), i = `${
|
|
405
|
+
const e = g(s), i = `${E[t]} Pluno`;
|
|
406
406
|
return e ? `${i}: ${e}` : i;
|
|
407
407
|
}
|
|
408
408
|
class k {
|
|
@@ -439,7 +439,7 @@ class k {
|
|
|
439
439
|
applyTitle() {
|
|
440
440
|
if (!this.status)
|
|
441
441
|
return;
|
|
442
|
-
const t =
|
|
442
|
+
const t = M(this.baseTitle, this.status);
|
|
443
443
|
this.lastAppliedTitle = t, this.titleDocument.getTitle() !== t && this.titleDocument.setTitle(t);
|
|
444
444
|
}
|
|
445
445
|
}
|
|
@@ -460,7 +460,7 @@ function $(s) {
|
|
|
460
460
|
};
|
|
461
461
|
}
|
|
462
462
|
function g(s) {
|
|
463
|
-
return s.replace(
|
|
463
|
+
return s.replace(T, "");
|
|
464
464
|
}
|
|
465
465
|
function K(s) {
|
|
466
466
|
if (!s || typeof s != "object" || !("type" in s)) return !1;
|
|
@@ -473,6 +473,10 @@ function K(s) {
|
|
|
473
473
|
return !0;
|
|
474
474
|
case "runtime.warmup":
|
|
475
475
|
return t.reason === "panel_open" || t.reason === "extension_install" || t.reason === "composer_input";
|
|
476
|
+
case "runtime.report_displayed_error":
|
|
477
|
+
return (t.reason === "conversation_error" || t.reason === "attachment_error" || t.reason === "history_error" || t.reason === "action_error") && typeof t.errorFingerprint == "string" && /^fnv1a-[0-9a-f]{8}$/.test(t.errorFingerprint);
|
|
478
|
+
case "runtime.report_invalid_state_transition":
|
|
479
|
+
return (t.reason === "submitted_turn_returned_to_welcome_without_new_chat" || t.reason === "new_messages_button_without_user_scroll") && (t.clientMessageId === void 0 || typeof t.clientMessageId == "string");
|
|
476
480
|
case "runtime.widget_lifecycle":
|
|
477
481
|
return (t.action === "opened" || t.action === "closed" || t.action === "minimized") && typeof t.trigger == "string";
|
|
478
482
|
case "session.load":
|
|
@@ -490,7 +494,7 @@ function K(s) {
|
|
|
490
494
|
case "conversation.stage_proactive_suggestion":
|
|
491
495
|
return typeof t.question == "string" && typeof t.clientMessageId == "string";
|
|
492
496
|
case "conversation.stage":
|
|
493
|
-
return typeof t.content == "string" && typeof t.clientMessageId == "string" && (t.attachments === void 0 || Array.isArray(t.attachments));
|
|
497
|
+
return typeof t.content == "string" && typeof t.clientMessageId == "string" && (t.submittedAt === void 0 || typeof t.submittedAt == "number") && (t.attachments === void 0 || Array.isArray(t.attachments));
|
|
494
498
|
case "conversation.fail_staged":
|
|
495
499
|
return typeof t.clientMessageId == "string" && typeof t.message == "string";
|
|
496
500
|
case "conversation.send":
|
|
@@ -559,10 +563,26 @@ class F {
|
|
|
559
563
|
recordWidgetLifecycle(t, e) {
|
|
560
564
|
this.dispatch({ type: "runtime.widget_lifecycle", action: t, trigger: e });
|
|
561
565
|
}
|
|
566
|
+
reportInvalidStateTransition(t, e) {
|
|
567
|
+
this.adapter.dispatch({
|
|
568
|
+
type: "runtime.report_invalid_state_transition",
|
|
569
|
+
reason: t,
|
|
570
|
+
clientMessageId: e
|
|
571
|
+
}).catch(() => {
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
reportDisplayedError(t, e) {
|
|
575
|
+
this.adapter.dispatch({
|
|
576
|
+
type: "runtime.report_displayed_error",
|
|
577
|
+
reason: t,
|
|
578
|
+
errorFingerprint: e
|
|
579
|
+
}).catch(() => {
|
|
580
|
+
});
|
|
581
|
+
}
|
|
562
582
|
sendMessage(t, e = {}) {
|
|
563
583
|
const i = t.trim(), n = e.attachments ?? [];
|
|
564
584
|
if (!i && n.length === 0) return Promise.resolve(null);
|
|
565
|
-
const r = e.clientMessageId ?? (e.proactiveSuggestionQuestion && this.stagedProactiveSuggestionClientMessageId ? this.stagedProactiveSuggestionClientMessageId : crypto.randomUUID()), a = this.state,
|
|
585
|
+
const r = e.clientMessageId ?? (e.proactiveSuggestionQuestion && this.stagedProactiveSuggestionClientMessageId ? this.stagedProactiveSuggestionClientMessageId : crypto.randomUUID()), a = e.submittedAt ?? Date.now(), l = this.state, o = {
|
|
566
586
|
id: `local-${r}`,
|
|
567
587
|
role: "user",
|
|
568
588
|
content: i,
|
|
@@ -572,7 +592,7 @@ class F {
|
|
|
572
592
|
};
|
|
573
593
|
return this.state = {
|
|
574
594
|
...this.state,
|
|
575
|
-
messages: [...this.state.messages,
|
|
595
|
+
messages: [...this.state.messages, o],
|
|
576
596
|
pendingMessageStatus: "sending",
|
|
577
597
|
turnPhase: this.state.isThinking ? this.state.turnPhase : "sending",
|
|
578
598
|
taskStatus: "working",
|
|
@@ -580,8 +600,8 @@ class F {
|
|
|
580
600
|
lastError: null
|
|
581
601
|
}, this.emit("state", this.getState()), this.enqueueOperation(() => this.sendMessageNow(
|
|
582
602
|
i,
|
|
583
|
-
{ ...e, clientMessageId: r },
|
|
584
|
-
|
|
603
|
+
{ ...e, clientMessageId: r, submittedAt: a },
|
|
604
|
+
l
|
|
585
605
|
));
|
|
586
606
|
}
|
|
587
607
|
async sendMessageNow(t, e, i) {
|
|
@@ -593,19 +613,20 @@ class F {
|
|
|
593
613
|
content: n,
|
|
594
614
|
clientMessageId: r,
|
|
595
615
|
proactiveSuggestionQuestion: e.proactiveSuggestionQuestion,
|
|
596
|
-
attachments: a.length > 0 ? a : void 0
|
|
616
|
+
attachments: a.length > 0 ? a : void 0,
|
|
617
|
+
submittedAt: e.submittedAt
|
|
597
618
|
}), l = !0, a.length > 0) {
|
|
598
619
|
if (!this.adapter.uploadAttachment)
|
|
599
620
|
throw new Error("The runtime does not support attachments.");
|
|
600
621
|
const c = [];
|
|
601
|
-
for (const
|
|
602
|
-
if (
|
|
603
|
-
c.push(
|
|
622
|
+
for (const d of a) {
|
|
623
|
+
if (d.sandboxPath || d.storageKey) {
|
|
624
|
+
c.push(d);
|
|
604
625
|
continue;
|
|
605
626
|
}
|
|
606
|
-
const v =
|
|
607
|
-
if (!v) throw new Error(`Attachment bytes are unavailable for ${
|
|
608
|
-
c.push(await this.adapter.uploadAttachment(v,
|
|
627
|
+
const v = d.id ? this.attachmentFiles.get(d.id) : void 0;
|
|
628
|
+
if (!v) throw new Error(`Attachment bytes are unavailable for ${d.name}`);
|
|
629
|
+
c.push(await this.adapter.uploadAttachment(v, d, { clientMessageId: r }));
|
|
609
630
|
}
|
|
610
631
|
a = c;
|
|
611
632
|
}
|
|
@@ -792,15 +813,15 @@ export {
|
|
|
792
813
|
Q as createLocalStorageInteractionDecisionStorage,
|
|
793
814
|
h as createProductAgentQueryState,
|
|
794
815
|
$ as createProductAgentTaskPageTitleDocument,
|
|
795
|
-
|
|
816
|
+
M as formatProductAgentTaskPageTitle,
|
|
796
817
|
D as hasProductAgentPaidCreditFallback,
|
|
797
818
|
K as isProductAgentRuntimeCommand,
|
|
798
819
|
P as mergeProductAgentEntityPages,
|
|
799
820
|
p as normalizeProductAgentEntityPage,
|
|
800
|
-
|
|
821
|
+
I as readLocalStorageInteractionDecisions,
|
|
801
822
|
x as reconcileProductAgentSubmissionGate,
|
|
802
823
|
C as resolveProductAgentBillingPresentation,
|
|
803
824
|
R as resolveProductAgentComposerAction,
|
|
804
|
-
|
|
825
|
+
O as resolveProductAgentWidgetPresentation,
|
|
805
826
|
A as selectProductAgentQueryEntities
|
|
806
827
|
};
|