@tencent-ai/agent-harness 0.2.0-beta.3 → 0.2.0-beta.4
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/CHANGELOG.md +14 -0
- package/cli/dist-server/shared.cjs +267 -210
- package/cli/dist-server/types/node/acp/acp-protocol.d.ts +8 -0
- package/cli/dist-server/types/node/loopback/server-protocol.d.ts +5 -0
- package/cli/dist-server/types/node/tools/tool-protocol.d.ts +23 -22
- package/cli/dist-server/types/vendor/cbc-core/node/agent/runner-factory.d.ts +18 -0
- package/cli/dist-server/types/vendor/cbc-core/node/context/index.d.ts +1 -0
- package/cli/dist-server/types/vendor/cbc-core/node/context/mods-bridge.d.ts +115 -0
- package/cli/dist-server/types/vendor/cbc-core/node/message-queue/followup-queue-protocol.d.ts +3 -2
- package/cli/dist-server/types/vendor/cbc-core/node/message-queue/followup-queue.d.ts +1 -1
- package/cli/dist-server/types/vendor/cbc-core/node/message-queue/steer-input-buffer-protocol.d.ts +4 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/can-use-tool.d.ts +4 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-manager.d.ts +30 -0
- package/cli/dist-server/types/vendor/cbc-core/node/session/session-protocol.d.ts +12 -0
- package/cli/dist-server/types/vendor/cbc-core/node/utils/input-item-utils.d.ts +1 -1
- package/cli/dist-server/types/workspace/agent-client-protocol/lib/common/prompt-codec.d.ts +4 -0
- package/cli/dist-server/types/workspace/agent-client-protocol/lib/common/types.d.ts +15 -1
- package/cli/dist-server/types/workspace/cbc-core/lib/node/agent/runner-factory.d.ts +18 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/context/index.d.ts +1 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/context/mods-bridge.d.ts +115 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/message-queue/followup-queue-protocol.d.ts +3 -2
- package/cli/dist-server/types/workspace/cbc-core/lib/node/message-queue/followup-queue.d.ts +1 -1
- package/cli/dist-server/types/workspace/cbc-core/lib/node/message-queue/steer-input-buffer-protocol.d.ts +4 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/can-use-tool.d.ts +4 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-manager.d.ts +30 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/session/session-protocol.d.ts +12 -0
- package/cli/dist-server/types/workspace/cbc-core/lib/node/utils/input-item-utils.d.ts +1 -1
- package/cli/dist-server/types/workspace/product/lib/common/types/features.d.ts +16 -0
- package/cli/dist-server/types/workspace/prompts/lib/common/product-prompt-provider.d.ts +3 -1
- package/cli/dist-server/types/workspace/prompts/lib/common/prompt-protocol.d.ts +6 -0
- package/cli/product.cloudhosted.json +1 -803
- package/cli/product.internal.json +1 -1061
- package/cli/product.ioa.json +1 -1523
- package/cli/product.json +1 -2217
- package/cli/product.selfhosted.json +1 -364
- package/docs/acp-v2.md +19 -0
- package/docs/client.md +7 -0
- package/docs/product.md +4 -0
- package/docs/protocol.md +3 -1
- package/lib/agent/v2.js +1 -1
- package/lib/application/services.js +1 -1
- package/lib/auth/module.d.ts +3 -1
- package/lib/auth/module.js +1 -1
- package/lib/client/client.js +1 -1
- package/lib/components/sandbox.d.mts +2 -0
- package/lib/components/sandbox.mjs +1 -0
- package/lib/components/session-replay.d.mts +2 -0
- package/lib/components/session-replay.mjs +1 -1
- package/lib/effect-runtime/concurrency.d.mts +2 -4
- package/lib/effect-runtime/concurrency.mjs +1 -1
- package/lib/effect-runtime/process-runtime-context.d.ts +5 -1
- package/lib/protocol/acp-v2-credits.d.ts +10 -0
- package/lib/protocol/acp-v2-credits.js +1 -0
- package/lib/protocol/acp-v2-private-client.d.ts +1 -10
- package/lib/runtime/codebuddy-auth.d.ts +5 -3
- package/lib/runtime/codebuddy-auth.js +1 -1
- package/lib/session/replay.d.ts +1 -1
- package/lib/session/replay.js +1 -1
- package/lib/session/server-events.js +1 -1
- package/lib/session/server-interactions.js +1 -1
- package/lib/subagent/history.js +1 -1
- package/package.json +14 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
var z=Object.defineProperty;var d=(s,t)=>z(s,"name",{value:t,configurable:!0});import{randomUUID as N}from"node:crypto";import"../auth/session.js";import{createManagedAuthPreparation as G}from"../effect-runtime/managed-auth-preparation.mjs";import{currentHarnessProcessRuntime as L}from"../effect-runtime/process-runtime-context.js";import{abortable as v,abortReason as M}from"../internal/async.js";import{isRecord as C}from"../internal/guards.js";import{ACP_V2_METHODS as b}from"../protocol/acp-v2.js";import{validateAcpV2CoreSchema as T}from"../protocol/acp-v2-schema.js";import{AGENT_HARNESS_ERROR_META_KEY as B}from"../protocol/error.js";import{AGENT_HARNESS_JSON_RPC_ERROR_CODES as p,AgentHarnessJsonRpcError as g}from"../server/errors.js";import{measure as P}from"../telemetry/runtime.js";import{accountBinding as S}from"./external-product-binding.js";const q=-32e3,V=200,H=5e3,j=3e4,J=10*6e4;class _ extends Error{static{d(this,"AuthenticationOperationSupersededError")}constructor(){super("Authentication operation was superseded")}}class O extends Error{static{d(this,"AuthenticationGenerationChangedError")}constructor(){super("Authentication generation changed during reconciliation")}}class A extends Error{static{d(this,"CodeBuddyAuthProductLifecycleError")}constructor(t){super(`Authentication Product ${t} failed`),this.name="CodeBuddyAuthProductLifecycleError"}}export class CodeBuddyAuthProductRefreshRequiredError extends Error{static{d(this,"CodeBuddyAuthProductRefreshRequiredError")}constructor(){super("Authentication Product refresh required"),this.name="CodeBuddyAuthProductRefreshRequiredError"}}export const CODEBUDDY_AUTH_PRODUCT_RESOLVE_ERROR_CODES=["PRODUCT_AUTH_INVALID","PRODUCT_REMOTE_RESPONSE_INVALID","PRODUCT_REMOTE_TIMEOUT","PRODUCT_REMOTE_UNAVAILABLE","PRODUCT_RESOLVE_TIMEOUT","PRODUCT_ROUTING_INVALID"];const W=new Set(CODEBUDDY_AUTH_PRODUCT_RESOLVE_ERROR_CODES);export function isCodeBuddyAuthProductResolveErrorCode(s){return W.has(s)}d(isCodeBuddyAuthProductResolveErrorCode,"isCodeBuddyAuthProductResolveErrorCode");export class CodeBuddyAuthProductResolveError extends Error{static{d(this,"CodeBuddyAuthProductResolveError")}constructor(t){super("Authentication Product resolution failed"),this.code=t,this.name="CodeBuddyAuthProductResolveError"}}const Y={PRODUCT_AUTH_INVALID:{code:"product_auth_invalid",message:"Product authentication context is invalid."},PRODUCT_REMOTE_RESPONSE_INVALID:{code:"product_remote_response_invalid",message:"Product configuration response is invalid."},PRODUCT_REMOTE_TIMEOUT:{code:"product_resolve_timeout",message:"Product configuration resolution timed out."},PRODUCT_REMOTE_UNAVAILABLE:{code:"product_remote_unavailable",message:"Product configuration is unavailable."},PRODUCT_RESOLVE_TIMEOUT:{code:"product_resolve_timeout",message:"Product configuration resolution timed out."},PRODUCT_ROUTING_INVALID:{code:"product_routing_invalid",message:"Product routing is invalid."}};function y(s){return{authMode:"none",generation:s,snapshot:{account:null,mode:null,state:"unauthenticated"}}}d(y,"unauthenticated");function D(s){return{id:s.id,...s.displayName===void 0?{}:{displayName:s.displayName},...s.avatarUrl===void 0?{}:{avatarUrl:s.avatarUrl},...s.enterpriseId===void 0?{}:{organization:{id:s.enterpriseId,...s.enterpriseName===void 0?{}:{displayName:s.enterpriseName}}},...s.department===void 0?{}:{department:s.department}}}d(D,"projectManagedAccount");function E(s){return{account:D(s.account),providerIdentity:{accountType:s.account.accountType,...s.account.idp===void 0?{}:{idp:s.account.idp},...s.account.oneidAccountId===void 0?{}:{oneidAccountId:s.account.oneidAccountId}},credential:s.credential}}d(E,"projectManagedCredential");function h(s){return new g(q,"Authentication required",s?{reason:s}:void 0)}d(h,"authRequired");function I(s){if(s instanceof CodeBuddyAuthProductRefreshRequiredError)return h("credential_rejected");if(!(s instanceof CodeBuddyAuthProductResolveError))return;const t=Y[s.code];return new g(p.notReady,t.message,{reason:t.code,[B]:t})}d(I,"projectPublicProductError");class x extends g{static{d(this,"CodeBuddyAuthProductPreconditionError")}}function X(s){return s instanceof _||s instanceof CodeBuddyAuthProductRefreshRequiredError||s instanceof CodeBuddyAuthProductResolveError||s instanceof x}d(X,"canRetryExternalInitialization");export function productProvisionError(s,t,e={}){return new x(p.invalidRequest,t,{...e,reason:s})}d(productProvisionError,"productProvisionError");function U(s,t){const e=new AbortController,i=Promise.withResolvers(),n=s.createPolicyDeadline(t,{signals:[e.signal],timeoutReason:new Error("Product provision timed out")});return{controller:e,completed:i.promise,complete:d(()=>{n.close(),i.resolve()},"complete"),signal:n.signal}}d(U,"createPendingProductProvision");const l="Authentication operation aborted";function $(s){const t=s.client?.capabilities?.agent;return!C(t)||!C(t.elicitation)?!1:C(t.elicitation.url)}d($,"supportsUrlElicitation");function F(s,t){return JSON.stringify(s)===JSON.stringify(t)}d(F,"sameIdentity");function R(s,t,e,i,n,a){return s?.id===i.id&&(s.authMethodId??null)===(i.authMethodId??null)&&(s.organization?.id??null)===(i.organization?.id??null)&&(s.department??null)===(i.department??null)&&(t?.accountType??null)===(n?.accountType??null)&&(t?.oneidAccountId??null)===(n?.oneidAccountId??null)&&(t?.idp??null)===(n?.idp??null)&&e?.type===a.type&&(e.domain??null)===(a.domain??null)}d(R,"sameCredentialContext");export class CodeBuddyAuthRuntime{static{d(this,"CodeBuddyAuthRuntime")}constructor(t,e=L()){if(this.initializationController=new AbortController,this.managedActivationEpoch=0,this.connectionAuthProfiles=new WeakMap,this.connectionProductProfiles=new WeakMap,this.activeProductMode="managed",this.managedDiscoveryLastApplied=0,this.managedDiscoverySequence=0,this.authenticationEpoch=0,this.pendingManagedRestore=!1,this.closed=!1,this.processRuntime=e,this.mutationGate=e.createSerialGate("Authentication mutation"),this.refreshFlights=e.createSingleFlight("Authentication refresh"),this.stateCell=e.createStateCell(y(0)),this.managedPreparation=G(e),this.consumer=t.consumer,this.getAuthMethods=t.getAuthMethods??(()=>[]),this.managedAuth=t.managedAuth,this.onRuntimePreparing=t.onRuntimePreparing,this.onRuntimePrepared=t.onRuntimePrepared,this.productLifecycle=t.productLifecycle,this.productLifecycle&&(this.accountUpdatePublication="backend"),this.loginCleanupTimeoutMs=t.loginCleanupTimeoutMs??H,this.loginPollIntervalMs=t.loginPollIntervalMs??V,this.refreshTimeoutMs=t.refreshTimeoutMs??j,this.productProvisionTimeoutMs=t.productProvisionTimeoutMs??J,!Number.isSafeInteger(this.loginCleanupTimeoutMs)||this.loginCleanupTimeoutMs<=0||!Number.isSafeInteger(this.loginPollIntervalMs)||this.loginPollIntervalMs<=0||!Number.isSafeInteger(this.refreshTimeoutMs)||this.refreshTimeoutMs<=0||!Number.isSafeInteger(this.productProvisionTimeoutMs)||this.productProvisionTimeoutMs<=0)throw new RangeError("Authentication timeouts must be positive integers");this.releaseProcessOwnership=e.addFinalizer(()=>this.close(new Error("Agent Harness process runtime is closing")))}get state(){return this.stateCell.current}setState(t){return this.stateCell.set(t)}clearPendingManagedRestore(){this.pendingManagedRestore=!1,this.pendingManagedAccount=void 0}bindProtocolBridge(t){if(this.bridge&&this.bridge!==t)throw new Error("Authentication protocol bridge is already bound");this.bridge=t}selectConnectionProductProfile(t,e){const i=this.connectionProductProfiles.get(e.connectionSignal);if(i&&(i.mode!==t.mode||i.workspace!==t.workspace))throw new g(p.invalidRequest,"Product management profile cannot change on an initialized connection");this.connectionProductProfiles.set(e.connectionSignal,Object.freeze({...t})),this.state.authMode==="none"&&(this.activeProductMode=t.mode)}productModeFor(t){return(t===void 0?void 0:this.connectionProductProfiles.get(t)?.mode)??this.activeProductMode}activateProductMode(t){const e=this.productModeFor(t);return this.activeProductMode=e,e}startManagedDiscovery(){return this.closed?Promise.reject(new Error("Authentication runtime is closed")):this.state.authMode!=="none"?Promise.resolve():this.getOrStartManagedDiscovery().promise.then(()=>{})}selectConnectionAuthProfile(t,e){const i=this.connectionProductProfiles.get(e.connectionSignal);this.connectionAuthProfiles.set(e.connectionSignal,t),this.activeProductMode=i?.mode??this.activeProductMode,t.mode!=="external"&&this.startManagedDiscovery().catch(()=>{})}markConnectionInitialized(t){if(t.mode!=="external"){try{this.onRuntimePreparing?.()}catch{}this.startManagedPreparation().then(()=>{!this.closed&&this.state.authMode==="none"&&this.notifyRuntimePrepared()},()=>{})}}notifyRuntimePrepared(){if(this.productLifecycle?.isProductReady?.(this.activeProductMode)!==!1)try{this.onRuntimePrepared?.()}catch{}}async notifyCurrentAccountUpdated(){const t=this.bridge;if(t){if(this.state.authMode==="external"&&this.state.externalOwner){await t.notifyAccountUpdated(this.state.snapshot,{sourceOwner:this.state.externalOwner});return}await t.notifyAccountUpdated(this.state.snapshot)}}close(t){return this.closePromise??=this.closeInternal(t),this.closePromise}async closeInternal(t){if(this.closed)return;const e=t??new Error("Authentication runtime is closed");this.closed=!0,this.initializationController.abort(e),this.authenticationEpoch+=1,this.authenticationOperationController?.abort(e),this.authenticationOperationController=void 0,this.pendingManagedLoginId=void 0,this.abortReconciliation(e),this.abortRefreshFlights(e),this.pendingProductProvision?.controller.abort(e),await this.managedPreparation.close(e).catch(()=>{}),await this.refreshFlights.close(e),await this.pendingProductProvision?.completed;try{await this.withPolicyDeadline(this.loginCleanupTimeoutMs,[],i=>this.runMutation(async()=>{const n=this.nextGeneration();await this.executeProductTransition({credentialOrder:"before_product",mode:"none",origin:"shutdown_cleanup",signal:i,commitCredential:d(async()=>{this.clearPendingManagedRestore(),await this.setState(y(n)),await this.consumer.clearAuthentication({generation:n})},"commitCredential")})},{allowClosed:!0})).catch(()=>{})}finally{await this.mutationGate.close(e)}this.releaseProcessOwnership()}async readAccount(t,e){const i=await this.runConsistentRead(()=>this.state.authMode==="none"?void 0:structuredClone(this.state.snapshot));if(i!==void 0)return i;const n=this.initialization;return n&&!this.pendingManagedRestore?(await v(n,e.signal,l),this.runConsistentRead(()=>structuredClone(this.state.snapshot))):this.connectionAuthProfiles.get(e.connectionSignal)?.mode==="external"?this.runConsistentRead(()=>structuredClone(this.state.snapshot)):this.reconciliation!==void 0?this.runConsistentRead(()=>structuredClone(this.state.snapshot)):(await this.awaitManagedDiscovery(e.signal),this.runConsistentRead(()=>this.state.authMode!=="none"?structuredClone(this.state.snapshot):this.pendingManagedRestore&&this.pendingManagedAccount?{account:structuredClone(this.pendingManagedAccount),mode:"managed",state:"authenticated"}:structuredClone(this.state.snapshot)))}async prepareAuthStatus(t,e){this.connectionAuthProfiles.get(e.connectionSignal)?.mode!=="external"&&this.reconciliation===void 0&&await this.awaitManagedDiscovery(e.signal)}async readAuthStatus(t,e){return this.runConsistentRead(()=>({authenticated:this.state.authMode!=="none"||this.pendingManagedRestore&&this.reconciliation===void 0&&this.connectionAuthProfiles.get(e.connectionSignal)?.mode!=="external"}))}async readProduct(t,e){return this.runConsistentRead(()=>{const i=this.productLifecycle;if(!i)throw new g(p.notReady,"Product lifecycle is unavailable");const n=i.readProduct;if(!n)throw new g(p.notReady,"Product projection is unavailable");return n.call(i,this.productModeFor(e.connectionSignal))})}async prepareHostExecution(t){await this.awaitManagedDiscovery(t),await this.runConsistentRead(()=>this.state.authMode==="none"&&this.pendingManagedRestore)&&await this.ensurePublicInitialized(t)}currentSessionAuthentication(){const t=this.state;if(!(t.snapshot.state!=="authenticated"||!t.credential))return structuredClone({generation:t.generation,account:t.snapshot.account,credential:t.credential,providerIdentity:t.providerIdentity})}async refreshHostAuthentication(t,e){const i=d(()=>this.runConsistentRead(()=>{const a=this.currentSessionAuthentication();if(!a||!R(t.account,t.providerIdentity,t.credential,a.account,a.providerIdentity,a.credential))throw h("account_changed");return a}),"capture"),n=await i();if(n.generation!==t.generation)return n;try{return await this.refreshAuthentication({accountId:t.account.id,generation:t.generation},{signal:e})}catch(a){e.throwIfAborted();const o=await i();if(o.generation>t.generation&&o.credential.accessToken!==t.credential.accessToken)return o;throw a}}async prepareSessionRuntime(t,e){if((e===void 0?void 0:this.connectionAuthProfiles.get(e)?.mode)==="external"&&this.state.authMode==="none")throw h("account_provision_required");await this.ensurePublicInitialized(t),this.productLifecycle?.assertProductReady?.(this.productModeFor(e))}async refreshProductAuthentication(t){await this.ensureInitialized(t);const e=this.state;if(e.authMode==="none"||e.snapshot.state!=="authenticated")throw h();await this.refreshAuthentication({accountId:e.snapshot.account.id,generation:e.generation},{signal:t})}async runConsistentRead(t){for(;;){const e=this.pendingProductProvision;if(e){await e.completed;continue}const i=await this.runMutation(async()=>this.pendingProductProvision?{retry:!0}:{retry:!1,value:await t()});if(!i.retry)return i.value}}async listAuthMethods(t,e){return structuredClone(this.getAuthMethods())}async login(t,e){this.activateProductMode(e.connectionSignal);const{pendingLoginId:i,token:n}=this.beginExplicitAuthenticationOperation(new Error("Authentication login superseded prior reconciliation"));await this.ensurePublicInitialized(e.signal),this.assertCurrentAuthenticationOperation(n),i&&await this.cancelSupersededManagedLogin(n,i);const a=N();this.pendingManagedLoginId=a;let o,r;try{if(o=await this.managedAuth.startManagedAuthLogin(t.methodId,{loginId:a,signal:e.signal}),this.assertCurrentAuthenticationOperation(n),this.pendingManagedLoginId=o.loginId,r=await this.awaitManagedLogin(o,e),r.state!=="succeeded")throw h(r.state);return await this.reconcileManagedLoginForRequest(n),{}}catch(c){if(!this.isCurrentAuthenticationOperation(n))throw c;if(r?.state==="succeeded")throw this.startManagedLoginReconciliation(n),c;if(!r||r.state==="pending"||!r.settled){const u=o?.loginId??a,f=await this.withAuthenticationDeadline(n,this.loginCleanupTimeoutMs,m=>Promise.resolve(this.managedAuth.readManagedAuthLogin(u,{signal:m}))).catch(()=>{});if(!this.isCurrentAuthenticationOperation(n))throw c;if(f?.state==="succeeded")return await this.reconcileManagedLoginForRequest(n),{};if(await this.cancelManagedLogin(u),!this.isCurrentAuthenticationOperation(n))throw c;const w=await this.withAuthenticationDeadline(n,this.loginCleanupTimeoutMs,m=>this.awaitManagedLoginSettlement(u,f,m)).catch(()=>{});if(!this.isCurrentAuthenticationOperation(n))throw c;if(w?.state==="succeeded")return await this.reconcileManagedLoginForRequest(n),{};this.pendingManagedLoginId=w?.settled===!0?void 0:u,this.pendingManagedLoginId&&this.startPendingManagedLoginReconciliation(n,this.pendingManagedLoginId)}else this.pendingManagedLoginId=void 0;throw c}}async logout(t,e){this.activateProductMode(e.connectionSignal);const i=this.reconciliation,{pendingLoginId:n,token:a}=this.beginExplicitAuthenticationOperation(new Error("Authentication logout superseded prior reconciliation")),o=n??i?.loginId,r=o===void 0?void 0:await this.cancelManagedLogin(o);let c=this.state.authMode==="managed"||o!==void 0||i?.kind==="managed_login"||i?.kind==="managed_logout"||i?.kind==="pending_login";if(c||(await this.ensurePublicInitialized(e.signal),c=this.state.authMode==="managed"),this.assertCurrentAuthenticationOperation(a),!c&&this.state.authMode==="external")return await this.fenceAuthenticationForOperation(a,new Error("External authentication was detached")),this.pendingManagedLoginId=void 0,{};if(!c&&this.state.authMode==="none")return{};let u;try{await this.withAuthenticationDeadline(a,this.loginCleanupTimeoutMs,w=>this.managedAuth.logoutManagedAuth({signal:w}))}catch(w){u=w}const f=o!==void 0&&r?.settled!==!0;if(u!==void 0||f)throw await this.fenceAuthenticationForOperation(a,new Error("Managed authentication logout is ambiguous")),this.startManagedLogoutReconciliation(a,o),this.productLifecycle||await this.notifyCurrentAccountUpdated().catch(()=>{}),u??h("managed_login_cancellation_ambiguous");return await this.fenceAuthenticationForOperation(a,new Error("Authentication was logged out")),this.pendingManagedLoginId=void 0,{}}async provisionAccount(t,e){this.activateProductMode(e.connectionSignal);const{pendingLoginId:i,token:n}=this.beginExplicitAuthenticationOperation(new Error("External authentication superseded prior reconciliation"));if(t.state==="authenticated"&&this.initialization===void 0){this.managedActivationEpoch+=1,this.clearPendingManagedRestore();const a=(async()=>(await this.managedPreparation.join(),this.assertCurrentAuthenticationOperation(n),this.commitExternalAccount(t,e,n,i)))(),o=a.then(()=>{},r=>{throw this.initialization===o&&X(r)&&(this.initialization=void 0),r});return this.initialization=o,o.catch(()=>{}),a.catch(r=>{throw I(r)??r})}if(await this.ensurePublicInitialized(e.signal),this.assertCurrentAuthenticationOperation(n),i&&await this.cancelSupersededManagedLogin(n,i),t.state==="unauthenticated"){if(this.state.authMode==="managed")throw new g(p.invalidRequest,"account/provision cannot detach managed authentication");return await this.runMutation(async()=>{this.assertCurrentAuthenticationOperation(n);const a=this.nextGeneration();this.abortRefreshFlights(new Error("External authentication was detached")),await this.withAuthenticationDeadline(n,this.loginCleanupTimeoutMs,o=>this.executeProductTransition({credentialOrder:"before_product",mode:"none",origin:"explicit_auth_mutation",signal:o,commitCredential:d(async()=>{if(this.productLifecycle){this.clearPendingManagedRestore(),await this.setState(y(a)),await this.consumer.clearAuthentication({generation:a});return}await this.consumer.clearAuthentication({generation:a}),this.clearPendingManagedRestore(),await this.setState(y(a))},"commitCredential")}))}),structuredClone(this.state.snapshot)}try{return await this.commitExternalAccount(t,e,n)}catch(a){throw I(a)??a}}async commitExternalAccount(t,e,i,n){return this.assertCurrentAuthenticationOperation(i),n&&await this.cancelSupersededManagedLogin(i,n),await this.runMutation(async()=>{this.assertCurrentAuthenticationOperation(i);const a=this.nextGeneration(),o=this.state.authMode!=="none"&&(this.state.authMode!=="external"||this.state.snapshot.state!=="authenticated"||this.state.snapshot.account.id!==t.account.id||!R(this.state.snapshot.account,this.state.providerIdentity,this.state.credential,t.account,void 0,t.credential));this.abortRefreshFlights(new Error("Authentication state was replaced"));const r={account:t.account,credential:t.credential,generation:a};await this.withAuthenticationDeadline(i,this.refreshTimeoutMs,c=>this.executeProductTransition({authentication:r,credentialOrder:"after_product",mode:"external",origin:"explicit_auth_mutation",signal:c,commitCredential:d(async()=>{await this.consumer.setAuthentication(r,{fenceExisting:o}),this.clearPendingManagedRestore(),await this.setState({authMode:"external",credential:structuredClone(t.credential),externalOwner:e.connectionSignal,generation:a,snapshot:{account:structuredClone(t.account),mode:"external",state:"authenticated"}})},"commitCredential")}))}),this.notifyRuntimePrepared(),structuredClone(this.state.snapshot)}async provisionProduct(t,e){await this.ensurePublicInitialized(e.signal);const i=this.productLifecycle,n=i?.provisionExternal,a=i?.reserveExternalProvision;if(!n||!a)throw new g(p.notReady,"External Product provisioning is unavailable");if(this.connectionProductProfiles.get(e.connectionSignal)?.mode!=="external")throw new g(p.invalidRequest,"product/provision requires external Product management");const o=U(this.processRuntime,this.productProvisionTimeoutMs);let r,c;await this.runMutation(async()=>{if(this.pendingProductProvision)throw new g(p.notReady,"Product provisioning is already in progress");const u=this.state;if(u.snapshot.state!=="authenticated"||e.connectionSignal.aborted)throw h();r=S(u.snapshot.account,u.credential?.domain),c=a.call(i,r),this.pendingProductProvision=o});try{return await n.call(i,t,{binding:r,reservation:c,signal:o.signal})}finally{await this.runMutation(async()=>{if(this.pendingProductProvision===o){this.pendingProductProvision=void 0;try{c?.release()}finally{o.complete()}}},{allowClosed:!0})}}async provisionWorkspaceProduct(t,e){await this.ensurePublicInitialized(e.signal);const i=this.productLifecycle,n=i?.provisionWorkspace;if(!n)throw new g(p.notReady,"Workspace Product provisioning is unavailable");const a=U(this.processRuntime,this.productProvisionTimeoutMs);let o,r;await this.runMutation(async()=>{if(this.pendingProductProvision)throw new g(p.notReady,"Product provisioning is already in progress");const c=this.state;if(c.snapshot.state!=="authenticated"||e.connectionSignal.aborted)throw h();r=this.productModeFor(e.connectionSignal),i.assertProductReady?.(r),o=S(c.snapshot.account,c.credential?.domain),this.pendingProductProvision=a});try{return await n.call(i,t,{binding:o,mode:r,signal:a.signal})}finally{await this.runMutation(async()=>{this.pendingProductProvision===a&&(this.pendingProductProvision=void 0,a.complete())},{allowClosed:!0})}}async detachExternalAccount(t,e){if(this.activateProductMode(t.connectionSignal),await this.withPolicyDeadline(this.loginCleanupTimeoutMs,[],o=>this.ensureInitialized(o)),this.state.authMode!=="external"||this.state.externalOwner!==t.connectionSignal)return!1;const{pendingLoginId:i,token:n}=this.beginExplicitAuthenticationOperation(new Error("External authentication detach superseded prior reconciliation"));let a=!1;if(i)try{await this.cancelSupersededManagedLogin(n,i)}catch{a=!0}return this.runMutation(async()=>{if(this.assertCurrentAuthenticationOperation(n),this.state.authMode!=="external"||this.state.externalOwner!==t.connectionSignal)return a&&this.state.authMode==="none";const o=this.nextGeneration();return this.abortRefreshFlights(new Error("External authentication owner detached")),await this.withAuthenticationDeadline(n,this.loginCleanupTimeoutMs,r=>this.executeProductTransition({credentialOrder:"before_product",mode:"none",origin:"explicit_auth_mutation",signal:r,commitCredential:d(async()=>{this.clearPendingManagedRestore(),await this.setState(y(o)),await this.consumer.clearAuthentication({generation:o})},"commitCredential")})),!0})}async refreshAuthentication(t,e){await this.ensureInitialized(e.signal);const i=JSON.stringify([this.state.authMode,t.accountId,t.generation]),n=this.state;if(n.authMode==="none"||n.generation!==t.generation||n.snapshot.state!=="authenticated"||n.snapshot.account.id!==t.accountId)throw h();return this.refreshFlights.run(i,a=>this.performAuthenticationRefresh(n,t,AbortSignal.any([a,...n.authMode==="external"&&n.externalOwner?[n.externalOwner]:[]])),{abortMessage:l,signal:e.signal,timeoutMs:this.refreshTimeoutMs})}async performAuthenticationRefresh(t,e,i){const n=t.authMode;if(n==="none")throw h();const a=n==="managed"?E(await this.managedAuth.refreshManagedAuthCredential(e.accountId,{signal:i})):await this.refreshExternal(e,i,t.externalOwner);if(i.aborted)throw n==="external"&&t.externalOwner?.aborted?h("owner_disconnected"):M(i,l);if(a.account.id!==e.accountId||!R(t.snapshot.account,t.providerIdentity,t.credential,a.account,a.providerIdentity,a.credential))throw h("account_changed");if(n==="external"&&a.credential.accessToken===t.credential?.accessToken)throw h("credential_unchanged");let o,r=!1;return await this.runMutation(async()=>{if(i.aborted)throw M(i,l);if(this.state.authMode!==t.authMode||this.state.generation!==t.generation||this.state.snapshot.state!=="authenticated"||this.state.snapshot.account.id!==e.accountId||n==="external"&&(t.externalOwner?.aborted!==!1||this.state.externalOwner!==t.externalOwner))throw h("stale_generation");const c=this.nextGeneration(),u=this.state.snapshot.account;o={account:structuredClone(a.account),...a.providerIdentity===void 0?{}:{providerIdentity:structuredClone(a.providerIdentity)},credential:structuredClone(a.credential),generation:c},await this.executeProductTransition({authentication:o,credentialOrder:"after_product",mode:n,origin:"child_refresh",signal:i,commitCredential:d(async()=>{await this.consumer.setAuthentication(o),r=!F(u,a.account),await this.setState({...this.state,...a.providerIdentity===void 0?{}:{providerIdentity:structuredClone(a.providerIdentity)},credential:structuredClone(a.credential),generation:c,snapshot:{account:structuredClone(a.account),mode:n,state:"authenticated"}})},"commitCredential")})}),!this.productLifecycle&&r&&await this.notifyCurrentAccountUpdated(),o}async ensurePublicInitialized(t){try{await this.ensureInitialized(t)}catch(e){throw I(e)??e}}getOrStartManagedDiscovery(){const t=this.managedActivationEpoch,e=this.authenticationEpoch,i=this.managedDiscovery;if(i&&i.activationEpoch===t&&i.authenticationEpoch===e)return i;const n=++this.managedDiscoverySequence,o=this.discoverManagedAuthentication({activationEpoch:t,authenticationEpoch:e,sequence:n}).then(c=>(this.managedDiscovery?.promise===o&&!c.applied&&(this.managedDiscovery=void 0),c),c=>{throw this.managedDiscovery?.promise===o&&(this.managedDiscovery=void 0),c});o.catch(()=>{});const r={activationEpoch:t,authenticationEpoch:e,promise:o};return this.managedDiscovery=r,r}async discoverManagedAuthentication(t){const e=await this.managedAuth.readManagedAuth({signal:this.initializationController.signal});let i=!1;return await this.runMutation(async()=>{if(this.closed||t.activationEpoch!==this.managedActivationEpoch||t.authenticationEpoch!==this.authenticationEpoch||this.initialization!==void 0||this.state.authMode!=="none"||t.sequence<this.managedDiscoveryLastApplied)return;this.managedDiscoveryLastApplied=t.sequence;const n=e.account;this.pendingManagedRestore=e.authenticated&&n!==null;const a=this.pendingManagedRestore&&n?D(n):void 0;this.pendingManagedAccount=a,i=!0}),{...t,applied:i,snapshot:e}}async awaitManagedDiscovery(t){for(;;){if(this.closed)throw new Error("Authentication runtime is closed");if(t.aborted)throw M(t,l);if(this.state.authMode!=="none"||this.initialization!==void 0)return;const e=this.getOrStartManagedDiscovery();let i;try{i=await P("managedAuthDiscoveryWait",()=>v(e.promise,t,l))}catch(n){if(this.state.authMode!=="none"||this.initialization!==void 0||e.activationEpoch!==this.managedActivationEpoch||e.authenticationEpoch!==this.authenticationEpoch)return;throw n}if(i.applied&&i.activationEpoch===this.managedActivationEpoch&&i.authenticationEpoch===this.authenticationEpoch&&this.state.authMode==="none"&&this.initialization===void 0)return i.snapshot}}async ensureInitialized(t){for(;;){if(this.closed)throw new Error("Authentication runtime is closed");if(t.aborted)throw M(t,l);if(this.initialization){await v(this.initialization,t,l);return}if(this.state.authMode!=="none")return;try{await this.managedPreparation.run((e,i)=>this.initializeManagedRuntime(e,i),{signal:t})}catch(e){if(this.initialization!==void 0)continue;throw e}}}startManagedPreparation(){return this.closed?Promise.reject(new Error("Authentication runtime is closed")):this.initialization!==void 0||this.state.authMode!=="none"?Promise.resolve():this.managedPreparation.run((t,e)=>this.initializeManagedRuntime(t,e))}async initializeManagedRuntime(t,e){for(;;){if(this.closed)throw new Error("Authentication runtime is closed");if(t.aborted)throw M(t,l);if(this.initialization!==void 0||this.state.authMode!=="none")return;const i=await this.awaitManagedDiscovery(t);if(e.phaseCompleted("discovery_ready"),this.initialization!==void 0||this.state.authMode!=="none")return;if(i){if(!i.authenticated||!i.account){this.initialization??=Promise.resolve();return}this.managedActivationEpoch+=1,this.managedDiscovery=void 0,await this.initializeFromManaged(i.account,t,e),this.initialization??=Promise.resolve();return}}}async initializeFromManaged(t,e,i){let n=await P("managedCredentialRead",()=>this.managedAuth.readManagedAuthCredential({signal:e}));if(i.phaseCompleted("credential_ready"),n.account.id!==t.id)throw new Error("Managed authentication projection changed identity");try{await P("productReconcile",()=>this.commitManaged(n,void 0,e))}catch(a){if(!(a instanceof CodeBuddyAuthProductRefreshRequiredError))throw a;const o=await P("managedCredentialRefresh",()=>this.managedAuth.refreshManagedAuthCredential(t.id,{signal:e}));i.phaseCompleted("credential_refreshed");const r=E(n),c=E(o);if(!R(r.account,r.providerIdentity,r.credential,c.account,c.providerIdentity,c.credential))throw h("account_changed");n=o,await P("productReconcile",()=>this.commitManaged(n,void 0,e))}i.phaseCompleted("product_ready")}async reconcileManagedLoginForRequest(t){try{await this.reconcileSucceededManagedLogin(t)}catch(e){throw this.isCurrentAuthenticationOperation(t)&&this.startManagedLoginReconciliation(t),e}}async reconcileSucceededManagedLogin(t,e){await this.fencePreviousAuthenticationForManagedLogin(t),this.assertCurrentAuthenticationOperation(t);const i=this.state.generation;await this.withPolicyDeadline(this.loginCleanupTimeoutMs,[t.signal,...e===void 0?[]:[e]],async n=>{const[a,o]=await Promise.all([this.managedAuth.readManagedAuth({signal:n}),this.managedAuth.readManagedAuthCredential({signal:n})]);if(!a.authenticated||!a.account||a.account.id!==o.account.id)throw h("managed_projection_unavailable");if(n.aborted)throw M(n,l);await this.commitManaged(o,{expectedGeneration:i,signal:n,token:t})}),this.assertCurrentAuthenticationOperation(t),this.pendingManagedLoginId=void 0}fencePreviousAuthenticationForManagedLogin(t){return this.fenceAuthenticationForOperation(t,new Error("Managed login replaced the authentication state"))}async commitManaged(t,e,i){if(i===void 0)return this.withPolicyDeadline(this.refreshTimeoutMs,e?.signal===void 0?[]:[e.signal],o=>this.commitManaged(t,e,o));const n=E(t),a=await this.runMutation(async()=>{if(e){if(this.assertCurrentAuthenticationOperation(e.token),e.signal?.aborted)throw M(e.signal,l);if(this.state.generation!==e.expectedGeneration)throw new O}const o=this.state.authMode!=="managed"||this.state.snapshot.state!=="authenticated"||!F(this.state.snapshot.account,n.account),r=this.nextGeneration(),c=this.state.authMode!=="none"&&(this.state.authMode!=="managed"||this.state.snapshot.state!=="authenticated"||this.state.snapshot.account.id!==n.account.id||!R(this.state.snapshot.account,this.state.providerIdentity,this.state.credential,n.account,n.providerIdentity,n.credential));this.abortRefreshFlights(new Error("Managed authentication state was replaced"));const u={...n,generation:r};return await this.executeProductTransition({authentication:u,credentialOrder:"after_product",mode:"managed",origin:e?"explicit_auth_mutation":"lazy_activation",signal:i,commitCredential:d(async()=>{await this.consumer.setAuthentication(u,{fenceExisting:c}),this.clearPendingManagedRestore(),await this.setState({authMode:"managed",providerIdentity:structuredClone(n.providerIdentity),credential:structuredClone(n.credential),generation:r,snapshot:{account:structuredClone(n.account),mode:"managed",state:"authenticated"}})},"commitCredential")}),o});return this.notifyRuntimePrepared(),a}startPendingManagedLoginReconciliation(t,e){this.startReconciliation("pending_login",t,async i=>{for(;this.canContinueReconciliation(t,i);){let n;try{n=await this.withBackgroundDeadline(t,i,a=>this.managedAuth.readManagedAuthLogin(e,{signal:a}))}catch{}if(!this.canContinueReconciliation(t,i))return;if(n?.state==="succeeded"){await this.runManagedLoginReconciliation(t,i);return}if(n?.settled){this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}await this.waitForDelay(this.loginPollIntervalMs,i)}},e)}startManagedLoginReconciliation(t){this.startReconciliation("managed_login",t,e=>this.runManagedLoginReconciliation(t,e))}async runManagedLoginReconciliation(t,e){for(;this.canContinueReconciliation(t,e);){try{if(await this.reconcileSucceededManagedLogin(t,e),!this.canContinueReconciliation(t,e))return;this.productLifecycle||await this.notifyCurrentAccountUpdated().catch(()=>{});return}catch(i){if(this.shouldStopReconciliation(i,t,e))return}await this.waitForDelay(this.loginPollIntervalMs,e)}}startManagedLogoutReconciliation(t,e,i=!0){this.startReconciliation("managed_logout",t,async n=>{let a=!1;for(;this.canContinueReconciliation(t,n);){let o=e===void 0;if(e!==void 0){const c=await this.withBackgroundDeadline(t,n,u=>this.managedAuth.readManagedAuthLogin(e,{signal:u})).catch(()=>{});if(!this.canContinueReconciliation(t,n))return;if(a||=c?.state==="succeeded",o=a||c?.settled===!0,c?.state==="pending"&&await this.withBackgroundDeadline(t,n,u=>this.managedAuth.cancelManagedAuthLogin(e,{signal:u})).catch(()=>{}),!a&&c?.settled===!0&&c?.state!=="succeeded"&&!i){this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}}if(!i&&a&&await this.fenceManagedAuthenticationForOperation(t,new Error("Superseded managed login committed durably")),!i&&!o){await this.waitForDelay(this.loginPollIntervalMs,n);continue}const r=await this.withBackgroundDeadline(t,n,c=>this.managedAuth.readManagedAuth({signal:c})).catch(()=>{});if(!this.canContinueReconciliation(t,n))return;if(r&&!r.authenticated&&o){this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}r?.authenticated&&await this.withBackgroundDeadline(t,n,c=>this.managedAuth.logoutManagedAuth({signal:c})).catch(()=>{}),await this.waitForDelay(this.loginPollIntervalMs,n)}},e,i)}startReconciliation(t,e,i,n,a){if(!this.isCurrentAuthenticationOperation(e))return;const o=this.reconciliation;if(o&&o.epoch===e.epoch&&o.kind===t&&o.loginId===n&&o.logoutCurrentManaged===a)return;this.abortReconciliation(new Error("Authentication reconciliation was replaced"));const r=new AbortController,c=AbortSignal.any([e.signal,r.signal]),u=i(c).catch(()=>{}).finally(()=>{this.reconciliation?.controller===r&&(this.reconciliation=void 0)}),f={controller:r,epoch:e.epoch,kind:t,...n===void 0?{}:{loginId:n},...a===void 0?{}:{logoutCurrentManaged:a},promise:u};this.reconciliation=f}async awaitManagedLogin(t,e){const i=new AbortController,n=AbortSignal.any([e.signal,e.connectionSignal,i.signal]);let a,o,r,c=t;try{for(;c.state==="pending";){if(e.signal.aborted||e.connectionSignal.aborted)throw M(e.signal.aborted?e.signal:e.connectionSignal,l);if("error"in(o??{}))throw o.error;if(o&&"action"in o&&o.action!=="accept")throw h(o.action);if(c.authUrl&&!r){if(!$(e))throw h("url_elicitation_unsupported");if(e.requestId===void 0||e.requestId===null)throw new Error("Authentication request has no JSON-RPC request id");a=c.loginId;const f={elicitationId:a,message:"Complete sign-in in your browser.",mode:"url",requestId:e.requestId,url:c.authUrl},w=T("CreateElicitationRequest",f);if(w)throw new Error(`Invalid authentication elicitation: ${w.message}`);r=e.request(b.client.elicitation.create,f,{signal:n,timeoutMs:null}).then(m=>{if(T("CreateElicitationResponse",m)||!C(m))throw new Error("Client returned an invalid elicitation response");o={action:m.action}}).catch(m=>{i.signal.aborted||(o={error:m})})}const u=Date.parse(c.expiresAt);if(!Number.isFinite(u)||this.processRuntime.policyNow()>=u)throw h("timed_out");await this.waitForDelay(this.loginPollIntervalMs,e.signal),c=await this.managedAuth.readManagedAuthLogin(c.loginId,{signal:e.signal})}return c}finally{i.abort(new Error("Authentication elicitation completed")),await r?.catch(()=>{}),a&&await e.notify(b.client.elicitation.complete,{elicitationId:a}).catch(()=>{})}}async awaitManagedLoginSettlement(t,e,i){let n=e;for(;!n?.settled;){n&&await this.waitForDelay(this.loginPollIntervalMs,i);const a=await this.managedAuth.readManagedAuthLogin(t,{signal:i});if(!a)throw new Error("Host returned no authentication login state");n=a}return n}async cancelManagedLogin(t){return this.withPolicyDeadline(this.loginCleanupTimeoutMs,[],e=>Promise.resolve(this.managedAuth.cancelManagedAuthLogin(t,{signal:e}))).catch(()=>{})}async cancelSupersededManagedLogin(t,e){this.pendingManagedLoginId??=e;const i=await this.cancelManagedLogin(e);if(this.assertCurrentAuthenticationOperation(t),i?.settled&&i.state!=="succeeded"){this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}if(i?.settled&&i.state==="succeeded")try{await this.fenceManagedAuthenticationForOperation(t,new Error("Superseded managed login committed durably")),await this.withAuthenticationDeadline(t,this.loginCleanupTimeoutMs,n=>this.managedAuth.logoutManagedAuth({signal:n})),this.assertCurrentAuthenticationOperation(t),this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}catch(n){throw this.isCurrentAuthenticationOperation(t)&&this.startManagedLogoutReconciliation(t,e,!1),n}throw this.startManagedLogoutReconciliation(t,e,!1),h("managed_login_cancellation_ambiguous")}async refreshExternal(t,e,i){if(!this.bridge||!i)throw h();let n;try{n=await this.bridge.requestAccountRefresh({accountId:t.accountId},{expectedOwner:i,signal:e})}catch(a){throw i.aborted?h("owner_disconnected"):a}return{account:n.account,credential:n.credential}}beginExplicitAuthenticationOperation(t){if(this.closed)throw new Error("Authentication runtime is closed");const e=this.pendingManagedLoginId;this.authenticationEpoch+=1,this.authenticationOperationController?.abort(t),this.abortReconciliation(t);const i=new AbortController;return this.authenticationOperationController=i,{...e===void 0?{}:{pendingLoginId:e},token:{epoch:this.authenticationEpoch,signal:i.signal}}}isCurrentAuthenticationOperation(t){return!this.closed&&t.epoch===this.authenticationEpoch&&this.authenticationOperationController?.signal===t.signal&&!t.signal.aborted}assertCurrentAuthenticationOperation(t){if(!this.isCurrentAuthenticationOperation(t))throw new _}withAuthenticationDeadline(t,e,i){return this.withPolicyDeadline(e,[t.signal],i)}withBackgroundDeadline(t,e,i){return this.withPolicyDeadline(this.loginCleanupTimeoutMs,[t.signal,e],i)}async fenceAuthenticationForOperation(t,e,i={}){for(;;){this.assertCurrentAuthenticationOperation(t);const n=this.state.generation;try{return await this.runMutation(async()=>{if(this.assertCurrentAuthenticationOperation(t),this.state.generation!==n)throw new O;if(this.state.authMode==="none"||i.authMode!==void 0&&this.state.authMode!==i.authMode)return!1;const a=this.nextGeneration();return this.abortRefreshFlights(e),await this.withAuthenticationDeadline(t,this.loginCleanupTimeoutMs,o=>this.executeProductTransition({credentialOrder:"before_product",mode:"none",origin:"explicit_auth_mutation",signal:o,commitCredential:d(async()=>{this.clearPendingManagedRestore(),await this.setState(y(a)),await this.consumer.clearAuthentication({generation:a})},"commitCredential")})),!0})}catch(a){if(a instanceof O&&this.isCurrentAuthenticationOperation(t))continue;throw a}}}async fenceManagedAuthenticationForOperation(t,e){await this.fenceAuthenticationForOperation(t,e,{authMode:"managed"})&&!this.productLifecycle&&await this.notifyCurrentAccountUpdated().catch(()=>{})}canContinueReconciliation(t,e){return!e.aborted&&this.isCurrentAuthenticationOperation(t)}shouldStopReconciliation(t,e,i){return i.aborted||!this.isCurrentAuthenticationOperation(e)||t instanceof _}abortReconciliation(t){const e=this.reconciliation;e&&!e.controller.signal.aborted&&e.controller.abort(t)}nextGeneration(){if(this.state.generation>=Number.MAX_SAFE_INTEGER)throw new Error("Authentication generation exhausted");return this.state.generation+1}abortRefreshFlights(t){this.refreshFlights.abortAll(t)}async executeProductTransition(t){const e=this.productLifecycle;if(!e){await t.commitCredential();return}if(t.signal.aborted)throw M(t.signal,l);let i=!1,n=!1,a,o;try{o=await e.transition({...t.authentication===void 0?{}:{authentication:structuredClone(t.authentication)},credentialOrder:t.credentialOrder,mode:t.mode,origin:t.origin,productMode:t.productMode??this.activeProductMode,signal:t.signal,commitCredential:d(async()=>{if(i)throw new A("transition");i=!0;try{await t.commitCredential(),n=!0}catch(r){throw a=r,r}},"commitCredential")})}catch(r){if(a!==void 0)throw a;if(n)try{await this.notifyCurrentAccountUpdated()}catch(c){throw e.fail?.(c),new A("publication")}throw r instanceof CodeBuddyAuthProductRefreshRequiredError||!n&&r instanceof CodeBuddyAuthProductResolveError||!n&&r instanceof g||r instanceof A?r:new A("transition")}if(!n)throw new A("transition");try{await this.notifyCurrentAccountUpdated(),await o.publish()}catch(r){throw e.fail?.(r),new A("publication")}}runMutation(t,e={}){if(this.closed&&e.allowClosed!==!0)return Promise.reject(new Error("Authentication runtime is closed"));const i=d(()=>this.closed&&e.allowClosed!==!0?Promise.reject(new Error("Authentication runtime is closed")):t(),"guardedOperation");return this.mutationGate.run(()=>i())}waitForDelay(t,e){return this.processRuntime.policyDelay(t,e,l)}async withPolicyDeadline(t,e,i){const n=this.processRuntime.createPolicyDeadline(t,{signals:e});try{return await i(n.signal)}finally{n.close()}}}export function createCodeBuddyAuthRuntime(s,t=L()){return new CodeBuddyAuthRuntime(s,t)}d(createCodeBuddyAuthRuntime,"createCodeBuddyAuthRuntime");
|
|
1
|
+
var z=Object.defineProperty;var d=(s,t)=>z(s,"name",{value:t,configurable:!0});import{randomUUID as N}from"node:crypto";import"../auth/session.js";import{createManagedAuthPreparation as G}from"../effect-runtime/managed-auth-preparation.mjs";import{currentHarnessProcessRuntime as L}from"../effect-runtime/process-runtime-context.js";import{abortable as C,abortReason as M}from"../internal/async.js";import{isRecord as E}from"../internal/guards.js";import{ACP_V2_METHODS as b}from"../protocol/acp-v2.js";import{validateAcpV2CoreSchema as T}from"../protocol/acp-v2-schema.js";import{AGENT_HARNESS_ERROR_META_KEY as B}from"../protocol/error.js";import{AGENT_HARNESS_JSON_RPC_ERROR_CODES as f,AgentHarnessJsonRpcError as g}from"../server/errors.js";import{measure as P}from"../telemetry/runtime.js";import{accountBinding as S}from"./external-product-binding.js";const q=-32e3,V=200,H=5e3,j=3e4,J=10*6e4;class _ extends Error{static{d(this,"AuthenticationOperationSupersededError")}constructor(){super("Authentication operation was superseded")}}class O extends Error{static{d(this,"AuthenticationGenerationChangedError")}constructor(){super("Authentication generation changed during reconciliation")}}class A extends Error{static{d(this,"CodeBuddyAuthProductLifecycleError")}constructor(t){super(`Authentication Product ${t} failed`),this.name="CodeBuddyAuthProductLifecycleError"}}export class CodeBuddyAuthProductRefreshRequiredError extends Error{static{d(this,"CodeBuddyAuthProductRefreshRequiredError")}constructor(){super("Authentication Product refresh required"),this.name="CodeBuddyAuthProductRefreshRequiredError"}}export const CODEBUDDY_AUTH_PRODUCT_RESOLVE_ERROR_CODES=["PRODUCT_AUTH_INVALID","PRODUCT_REMOTE_RESPONSE_INVALID","PRODUCT_REMOTE_TIMEOUT","PRODUCT_REMOTE_UNAVAILABLE","PRODUCT_RESOLVE_TIMEOUT","PRODUCT_ROUTING_INVALID"];const W=new Set(CODEBUDDY_AUTH_PRODUCT_RESOLVE_ERROR_CODES);export function isCodeBuddyAuthProductResolveErrorCode(s){return W.has(s)}d(isCodeBuddyAuthProductResolveErrorCode,"isCodeBuddyAuthProductResolveErrorCode");export class CodeBuddyAuthProductResolveError extends Error{static{d(this,"CodeBuddyAuthProductResolveError")}constructor(t){super("Authentication Product resolution failed"),this.code=t,this.name="CodeBuddyAuthProductResolveError"}}const Y={PRODUCT_AUTH_INVALID:{code:"product_auth_invalid",message:"Product authentication context is invalid."},PRODUCT_REMOTE_RESPONSE_INVALID:{code:"product_remote_response_invalid",message:"Product configuration response is invalid."},PRODUCT_REMOTE_TIMEOUT:{code:"product_resolve_timeout",message:"Product configuration resolution timed out."},PRODUCT_REMOTE_UNAVAILABLE:{code:"product_remote_unavailable",message:"Product configuration is unavailable."},PRODUCT_RESOLVE_TIMEOUT:{code:"product_resolve_timeout",message:"Product configuration resolution timed out."},PRODUCT_ROUTING_INVALID:{code:"product_routing_invalid",message:"Product routing is invalid."}};function y(s){return{authMode:"none",generation:s,snapshot:{account:null,mode:null,state:"unauthenticated"}}}d(y,"unauthenticated");function D(s){return{id:s.id,...s.displayName===void 0?{}:{displayName:s.displayName},...s.avatarUrl===void 0?{}:{avatarUrl:s.avatarUrl},...s.enterpriseId===void 0?{}:{organization:{id:s.enterpriseId,...s.enterpriseName===void 0?{}:{displayName:s.enterpriseName}}},...s.department===void 0?{}:{department:s.department}}}d(D,"projectManagedAccount");function v(s){return{account:D(s.account),providerIdentity:{accountType:s.account.accountType,...s.account.idp===void 0?{}:{idp:s.account.idp},...s.account.oneidAccountId===void 0?{}:{oneidAccountId:s.account.oneidAccountId}},credential:s.credential}}d(v,"projectManagedCredential");function h(s){return new g(q,"Authentication required",s?{reason:s}:void 0)}d(h,"authRequired");function I(s){if(s instanceof CodeBuddyAuthProductRefreshRequiredError)return h("credential_rejected");if(!(s instanceof CodeBuddyAuthProductResolveError))return;const t=Y[s.code];return new g(f.notReady,t.message,{reason:t.code,[B]:t})}d(I,"projectPublicProductError");class x extends g{static{d(this,"CodeBuddyAuthProductPreconditionError")}}function X(s){return s instanceof _||s instanceof CodeBuddyAuthProductRefreshRequiredError||s instanceof CodeBuddyAuthProductResolveError||s instanceof x}d(X,"canRetryExternalInitialization");export function productProvisionError(s,t,e={}){return new x(f.invalidRequest,t,{...e,reason:s})}d(productProvisionError,"productProvisionError");function U(s,t,e){const n=new AbortController,i=Promise.withResolvers(),a=s.createPolicyDeadline(t,{signals:[n.signal,e],timeoutReason:new Error("Product provision timed out")});return{controller:n,completed:i.promise,complete:d(()=>{a.close(),i.resolve()},"complete"),signal:a.signal}}d(U,"createPendingProductProvision");const l="Authentication operation aborted";function $(s){const t=s.client?.capabilities?.agent;return!E(t)||!E(t.elicitation)?!1:E(t.elicitation.url)}d($,"supportsUrlElicitation");function F(s,t){return JSON.stringify(s)===JSON.stringify(t)}d(F,"sameIdentity");function R(s,t,e,n,i,a){return s?.id===n.id&&(s.authMethodId??null)===(n.authMethodId??null)&&(s.organization?.id??null)===(n.organization?.id??null)&&(s.department??null)===(n.department??null)&&(t?.accountType??null)===(i?.accountType??null)&&(t?.oneidAccountId??null)===(i?.oneidAccountId??null)&&(t?.idp??null)===(i?.idp??null)&&e?.type===a.type&&(e.domain??null)===(a.domain??null)}d(R,"sameCredentialContext");export class CodeBuddyAuthRuntime{static{d(this,"CodeBuddyAuthRuntime")}constructor(t,e=L()){if(this.initializationController=new AbortController,this.managedActivationEpoch=0,this.connectionAuthProfiles=new WeakMap,this.connectionProductProfiles=new WeakMap,this.activeProductMode="managed",this.managedDiscoveryLastApplied=0,this.managedDiscoverySequence=0,this.authenticationEpoch=0,this.pendingManagedRestore=!1,this.closed=!1,this.processRuntime=e,this.mutationGate=e.createSerialGate("Authentication mutation"),this.refreshFlights=e.createSingleFlight("Authentication refresh"),this.stateCell=e.createStateCell(y(0)),this.managedPreparation=G(e),this.consumer=t.consumer,this.getAuthMethods=t.getAuthMethods??(()=>[]),this.managedAuth=t.managedAuth,this.onRuntimePreparing=t.onRuntimePreparing,this.onRuntimePrepared=t.onRuntimePrepared,this.productLifecycle=t.productLifecycle,this.productLifecycle&&(this.accountUpdatePublication="backend"),this.loginCleanupTimeoutMs=t.loginCleanupTimeoutMs??H,this.loginPollIntervalMs=t.loginPollIntervalMs??V,this.refreshTimeoutMs=t.refreshTimeoutMs??j,this.productProvisionTimeoutMs=t.productProvisionTimeoutMs??J,!Number.isSafeInteger(this.loginCleanupTimeoutMs)||this.loginCleanupTimeoutMs<=0||!Number.isSafeInteger(this.loginPollIntervalMs)||this.loginPollIntervalMs<=0||!Number.isSafeInteger(this.refreshTimeoutMs)||this.refreshTimeoutMs<=0||!Number.isSafeInteger(this.productProvisionTimeoutMs)||this.productProvisionTimeoutMs<=0)throw new RangeError("Authentication timeouts must be positive integers");this.releaseProcessOwnership=e.addFinalizer(()=>this.close(new Error("Agent Harness process runtime is closing")))}get state(){return this.stateCell.current}setState(t){return this.stateCell.set(t)}clearPendingManagedRestore(){this.pendingManagedRestore=!1,this.pendingManagedAccount=void 0}bindProtocolBridge(t){if(this.bridge&&this.bridge!==t)throw new Error("Authentication protocol bridge is already bound");this.bridge=t}selectConnectionProductProfile(t,e){const n=this.connectionProductProfiles.get(e.connectionSignal);if(n&&(n.mode!==t.mode||n.workspace!==t.workspace))throw new g(f.invalidRequest,"Product management profile cannot change on an initialized connection");this.connectionProductProfiles.set(e.connectionSignal,Object.freeze({...t})),this.state.authMode==="none"&&(this.activeProductMode=t.mode)}productModeFor(t){return(t===void 0?void 0:this.connectionProductProfiles.get(t)?.mode)??this.activeProductMode}activateProductMode(t){const e=this.productModeFor(t);return this.activeProductMode=e,e}startManagedDiscovery(){return this.closed?Promise.reject(new Error("Authentication runtime is closed")):this.state.authMode!=="none"?Promise.resolve():this.getOrStartManagedDiscovery().promise.then(()=>{})}selectConnectionAuthProfile(t,e){const n=this.connectionProductProfiles.get(e.connectionSignal);this.connectionAuthProfiles.set(e.connectionSignal,t),this.activeProductMode=n?.mode??this.activeProductMode,t.mode!=="external"&&this.startManagedDiscovery().catch(()=>{})}markConnectionInitialized(t){if(t.mode!=="external"){try{this.onRuntimePreparing?.()}catch{}this.startManagedPreparation().then(()=>{!this.closed&&this.state.authMode==="none"&&this.notifyRuntimePrepared()},()=>{})}}notifyRuntimePrepared(){if(this.productLifecycle?.isProductReady?.(this.activeProductMode)!==!1)try{this.onRuntimePrepared?.()}catch{}}async notifyCurrentAccountUpdated(){const t=this.bridge;if(t){if(this.state.authMode==="external"&&this.state.externalOwner){await t.notifyAccountUpdated(this.state.snapshot,{sourceOwner:this.state.externalOwner});return}await t.notifyAccountUpdated(this.state.snapshot)}}close(t){return this.closePromise??=this.closeInternal(t),this.closePromise}async closeInternal(t){if(this.closed)return;const e=t??new Error("Authentication runtime is closed");this.closed=!0,this.initializationController.abort(e),this.authenticationEpoch+=1,this.authenticationOperationController?.abort(e),this.authenticationOperationController=void 0,this.pendingManagedLoginId=void 0,this.abortReconciliation(e),this.abortRefreshFlights(e),this.pendingProductProvision?.controller.abort(e),await this.managedPreparation.close(e).catch(()=>{}),await this.refreshFlights.close(e),await this.pendingProductProvision?.completed;try{await this.withPolicyDeadline(this.loginCleanupTimeoutMs,[],n=>this.runMutation(async()=>{const i=this.nextGeneration();await this.executeProductTransition({credentialOrder:"before_product",mode:"none",origin:"shutdown_cleanup",signal:n,commitCredential:d(async()=>{this.clearPendingManagedRestore(),await this.setState(y(i)),await this.consumer.clearAuthentication({generation:i})},"commitCredential")})},{allowClosed:!0})).catch(()=>{})}finally{await this.mutationGate.close(e)}this.releaseProcessOwnership()}async readAccount(t,e){const n=await this.runConsistentRead(()=>this.state.authMode==="none"?void 0:structuredClone(this.state.snapshot),{signal:e.signal});if(n!==void 0)return n;const i=this.initialization;return i&&!this.pendingManagedRestore?(await C(i,e.signal,l),this.runConsistentRead(()=>structuredClone(this.state.snapshot),{signal:e.signal})):this.connectionAuthProfiles.get(e.connectionSignal)?.mode==="external"?this.runConsistentRead(()=>structuredClone(this.state.snapshot),{signal:e.signal}):this.reconciliation!==void 0?this.runConsistentRead(()=>structuredClone(this.state.snapshot),{signal:e.signal}):(await this.awaitManagedDiscovery(e.signal),this.runConsistentRead(()=>this.state.authMode!=="none"?structuredClone(this.state.snapshot):this.pendingManagedRestore&&this.pendingManagedAccount?{account:structuredClone(this.pendingManagedAccount),mode:"managed",state:"authenticated"}:structuredClone(this.state.snapshot),{signal:e.signal}))}async prepareAuthStatus(t,e){this.connectionAuthProfiles.get(e.connectionSignal)?.mode!=="external"&&this.reconciliation===void 0&&await this.awaitManagedDiscovery(e.signal)}async readAuthStatus(t,e){return this.runConsistentRead(()=>({authenticated:this.state.authMode!=="none"||this.pendingManagedRestore&&this.reconciliation===void 0&&this.connectionAuthProfiles.get(e.connectionSignal)?.mode!=="external"}),{signal:e.signal})}async readProduct(t,e){return this.runConsistentRead(()=>{const n=this.productLifecycle;if(!n)throw new g(f.notReady,"Product lifecycle is unavailable");const i=n.readProduct;if(!i)throw new g(f.notReady,"Product projection is unavailable");return i.call(n,this.productModeFor(e.connectionSignal))},{signal:e.signal})}async prepareHostExecution(t){await this.awaitManagedDiscovery(t),await this.runConsistentRead(()=>this.state.authMode==="none"&&this.pendingManagedRestore,{signal:t})&&await this.ensurePublicInitialized(t)}currentSessionAuthentication(){const t=this.state;if(!(t.snapshot.state!=="authenticated"||!t.credential))return structuredClone({generation:t.generation,account:t.snapshot.account,credential:t.credential,providerIdentity:t.providerIdentity})}async refreshHostAuthentication(t,e){const n=d(()=>this.runConsistentRead(()=>{const a=this.currentSessionAuthentication();if(!a||!R(t.account,t.providerIdentity,t.credential,a.account,a.providerIdentity,a.credential))throw h("account_changed");return a},{signal:e}),"capture"),i=await n();if(i.generation!==t.generation)return i;try{return await this.refreshAuthentication({accountId:t.account.id,generation:t.generation},{signal:e})}catch(a){e.throwIfAborted();const o=await n();if(o.generation>t.generation&&o.credential.accessToken!==t.credential.accessToken)return o;throw a}}async prepareSessionRuntime(t,e){if((e===void 0?void 0:this.connectionAuthProfiles.get(e)?.mode)==="external"&&this.state.authMode==="none")throw h("account_provision_required");await this.ensurePublicInitialized(t),this.productLifecycle?.assertProductReady?.(this.productModeFor(e))}async refreshProductAuthentication(t){await this.ensureInitialized(t);const e=this.state;if(e.authMode==="none"||e.snapshot.state!=="authenticated")throw h();await this.refreshAuthentication({accountId:e.snapshot.account.id,generation:e.generation},{signal:t})}async runConsistentRead(t,e={}){for(;;){e.signal?.throwIfAborted();const n=this.pendingProductProvision;if(n){await C(n.completed,e.signal,l);continue}const i=await this.runMutation(async()=>this.pendingProductProvision?{retry:!0}:{retry:!1,value:await t()},e);if(!i.retry)return i.value}}async listAuthMethods(t,e){return structuredClone(this.getAuthMethods())}async login(t,e){this.activateProductMode(e.connectionSignal);const{pendingLoginId:n,token:i}=this.beginExplicitAuthenticationOperation(new Error("Authentication login superseded prior reconciliation"));await this.ensurePublicInitialized(e.signal),this.assertCurrentAuthenticationOperation(i),n&&await this.cancelSupersededManagedLogin(i,n);const a=N();this.pendingManagedLoginId=a;let o,r;try{if(o=await this.managedAuth.startManagedAuthLogin(t.methodId,{loginId:a,signal:e.signal}),this.assertCurrentAuthenticationOperation(i),this.pendingManagedLoginId=o.loginId,r=await this.awaitManagedLogin(o,e),r.state!=="succeeded")throw h(r.state);return await this.reconcileManagedLoginForRequest(i),{}}catch(c){if(!this.isCurrentAuthenticationOperation(i))throw c;if(r?.state==="succeeded")throw this.startManagedLoginReconciliation(i),c;if(!r||r.state==="pending"||!r.settled){const u=o?.loginId??a,p=await this.withAuthenticationDeadline(i,this.loginCleanupTimeoutMs,m=>Promise.resolve(this.managedAuth.readManagedAuthLogin(u,{signal:m}))).catch(()=>{});if(!this.isCurrentAuthenticationOperation(i))throw c;if(p?.state==="succeeded")return await this.reconcileManagedLoginForRequest(i),{};if(await this.cancelManagedLogin(u),!this.isCurrentAuthenticationOperation(i))throw c;const w=await this.withAuthenticationDeadline(i,this.loginCleanupTimeoutMs,m=>this.awaitManagedLoginSettlement(u,p,m)).catch(()=>{});if(!this.isCurrentAuthenticationOperation(i))throw c;if(w?.state==="succeeded")return await this.reconcileManagedLoginForRequest(i),{};this.pendingManagedLoginId=w?.settled===!0?void 0:u,this.pendingManagedLoginId&&this.startPendingManagedLoginReconciliation(i,this.pendingManagedLoginId)}else this.pendingManagedLoginId=void 0;throw c}}async logout(t,e){this.activateProductMode(e.connectionSignal);const n=this.reconciliation,{pendingLoginId:i,token:a}=this.beginExplicitAuthenticationOperation(new Error("Authentication logout superseded prior reconciliation")),o=i??n?.loginId,r=o===void 0?void 0:await this.cancelManagedLogin(o);let c=this.state.authMode==="managed"||o!==void 0||n?.kind==="managed_login"||n?.kind==="managed_logout"||n?.kind==="pending_login";if(c||(await this.ensurePublicInitialized(e.signal),c=this.state.authMode==="managed"),this.assertCurrentAuthenticationOperation(a),!c&&this.state.authMode==="external")return await this.fenceAuthenticationForOperation(a,new Error("External authentication was detached")),this.pendingManagedLoginId=void 0,{};if(!c&&this.state.authMode==="none")return{};let u;try{await this.withAuthenticationDeadline(a,this.loginCleanupTimeoutMs,w=>this.managedAuth.logoutManagedAuth({signal:w}))}catch(w){u=w}const p=o!==void 0&&r?.settled!==!0;if(u!==void 0||p)throw await this.fenceAuthenticationForOperation(a,new Error("Managed authentication logout is ambiguous")),this.startManagedLogoutReconciliation(a,o),this.productLifecycle||await this.notifyCurrentAccountUpdated().catch(()=>{}),u??h("managed_login_cancellation_ambiguous");return await this.fenceAuthenticationForOperation(a,new Error("Authentication was logged out")),this.pendingManagedLoginId=void 0,{}}async provisionAccount(t,e){this.activateProductMode(e.connectionSignal);const{pendingLoginId:n,token:i}=this.beginExplicitAuthenticationOperation(new Error("External authentication superseded prior reconciliation"));if(t.state==="authenticated"&&this.initialization===void 0){this.managedActivationEpoch+=1,this.clearPendingManagedRestore();const a=(async()=>(await this.managedPreparation.join(),this.assertCurrentAuthenticationOperation(i),this.commitExternalAccount(t,e,i,n)))(),o=a.then(()=>{},r=>{throw this.initialization===o&&X(r)&&(this.initialization=void 0),r});return this.initialization=o,o.catch(()=>{}),a.catch(r=>{throw I(r)??r})}if(await this.ensurePublicInitialized(e.signal),this.assertCurrentAuthenticationOperation(i),n&&await this.cancelSupersededManagedLogin(i,n),t.state==="unauthenticated"){if(this.state.authMode==="managed")throw new g(f.invalidRequest,"account/provision cannot detach managed authentication");return await this.runMutation(async()=>{this.assertCurrentAuthenticationOperation(i);const a=this.nextGeneration();this.abortRefreshFlights(new Error("External authentication was detached")),await this.withAuthenticationDeadline(i,this.loginCleanupTimeoutMs,o=>this.executeProductTransition({credentialOrder:"before_product",mode:"none",origin:"explicit_auth_mutation",signal:o,commitCredential:d(async()=>{if(this.productLifecycle){this.clearPendingManagedRestore(),await this.setState(y(a)),await this.consumer.clearAuthentication({generation:a});return}await this.consumer.clearAuthentication({generation:a}),this.clearPendingManagedRestore(),await this.setState(y(a))},"commitCredential")}))}),structuredClone(this.state.snapshot)}try{return await this.commitExternalAccount(t,e,i)}catch(a){throw I(a)??a}}async commitExternalAccount(t,e,n,i){return this.assertCurrentAuthenticationOperation(n),i&&await this.cancelSupersededManagedLogin(n,i),await this.runMutation(async()=>{this.assertCurrentAuthenticationOperation(n);const a=this.nextGeneration(),o=this.state.authMode!=="none"&&(this.state.authMode!=="external"||this.state.snapshot.state!=="authenticated"||this.state.snapshot.account.id!==t.account.id||!R(this.state.snapshot.account,this.state.providerIdentity,this.state.credential,t.account,void 0,t.credential));this.abortRefreshFlights(new Error("Authentication state was replaced"));const r={account:t.account,credential:t.credential,generation:a};await this.withAuthenticationDeadline(n,this.refreshTimeoutMs,c=>this.executeProductTransition({authentication:r,credentialOrder:"after_product",mode:"external",origin:"explicit_auth_mutation",signal:c,commitCredential:d(async()=>{await this.consumer.setAuthentication(r,{fenceExisting:o}),this.clearPendingManagedRestore(),await this.setState({authMode:"external",credential:structuredClone(t.credential),externalOwner:e.connectionSignal,generation:a,snapshot:{account:structuredClone(t.account),mode:"external",state:"authenticated"}})},"commitCredential")}))}),this.notifyRuntimePrepared(),structuredClone(this.state.snapshot)}async provisionProduct(t,e){await this.ensurePublicInitialized(e.signal);const n=this.productLifecycle,i=n?.provisionExternal,a=n?.reserveExternalProvision;if(!i||!a)throw new g(f.notReady,"External Product provisioning is unavailable");if(this.connectionProductProfiles.get(e.connectionSignal)?.mode!=="external")throw new g(f.invalidRequest,"product/provision requires external Product management");const o=U(this.processRuntime,this.productProvisionTimeoutMs,e.signal);let r,c;try{return await this.runMutation(async()=>{if(this.pendingProductProvision)throw new g(f.notReady,"Product provisioning is already in progress");const u=this.state;if(u.snapshot.state!=="authenticated"||e.connectionSignal.aborted)throw h();r=S(u.snapshot.account,u.credential?.domain),c=a.call(n,r),this.pendingProductProvision=o},{signal:o.signal}),await i.call(n,t,{binding:r,reservation:c,signal:o.signal})}finally{try{this.pendingProductProvision===o&&await this.runMutation(async()=>{this.pendingProductProvision===o&&(this.pendingProductProvision=void 0,c?.release())},{allowClosed:!0})}finally{o.complete()}}}async provisionWorkspaceProduct(t,e){await this.ensurePublicInitialized(e.signal);const n=this.productLifecycle,i=n?.provisionWorkspace;if(!i)throw new g(f.notReady,"Workspace Product provisioning is unavailable");const a=U(this.processRuntime,this.productProvisionTimeoutMs,e.signal);let o,r;try{return await this.runMutation(async()=>{if(this.pendingProductProvision)throw new g(f.notReady,"Product provisioning is already in progress");const c=this.state;if(c.snapshot.state!=="authenticated"||e.connectionSignal.aborted)throw h();r=this.productModeFor(e.connectionSignal),n.assertProductReady?.(r),o=S(c.snapshot.account,c.credential?.domain),this.pendingProductProvision=a},{signal:a.signal}),await i.call(n,t,{binding:o,mode:r,signal:a.signal})}finally{try{this.pendingProductProvision===a&&await this.runMutation(async()=>{this.pendingProductProvision===a&&(this.pendingProductProvision=void 0)},{allowClosed:!0})}finally{a.complete()}}}async detachExternalAccount(t,e){if(this.activateProductMode(t.connectionSignal),await this.withPolicyDeadline(this.loginCleanupTimeoutMs,[],o=>this.ensureInitialized(o)),this.state.authMode!=="external"||this.state.externalOwner!==t.connectionSignal)return!1;const{pendingLoginId:n,token:i}=this.beginExplicitAuthenticationOperation(new Error("External authentication detach superseded prior reconciliation"));let a=!1;if(n)try{await this.cancelSupersededManagedLogin(i,n)}catch{a=!0}return this.runMutation(async()=>{if(this.assertCurrentAuthenticationOperation(i),this.state.authMode!=="external"||this.state.externalOwner!==t.connectionSignal)return a&&this.state.authMode==="none";const o=this.nextGeneration();return this.abortRefreshFlights(new Error("External authentication owner detached")),await this.withAuthenticationDeadline(i,this.loginCleanupTimeoutMs,r=>this.executeProductTransition({credentialOrder:"before_product",mode:"none",origin:"explicit_auth_mutation",signal:r,commitCredential:d(async()=>{this.clearPendingManagedRestore(),await this.setState(y(o)),await this.consumer.clearAuthentication({generation:o})},"commitCredential")})),!0})}async refreshAuthentication(t,e){await this.ensureInitialized(e.signal);const n=JSON.stringify([this.state.authMode,t.accountId,t.generation]),i=this.state;if(i.authMode==="none"||i.generation!==t.generation||i.snapshot.state!=="authenticated"||i.snapshot.account.id!==t.accountId)throw h();return this.refreshFlights.run(n,a=>this.performAuthenticationRefresh(i,t,AbortSignal.any([a,...i.authMode==="external"&&i.externalOwner?[i.externalOwner]:[]])),{abortMessage:l,signal:e.signal,timeoutMs:this.refreshTimeoutMs})}async performAuthenticationRefresh(t,e,n){const i=t.authMode;if(i==="none")throw h();const a=i==="managed"?v(await this.managedAuth.refreshManagedAuthCredential(e.accountId,{signal:n})):await this.refreshExternal(e,n,t.externalOwner);if(n.aborted)throw i==="external"&&t.externalOwner?.aborted?h("owner_disconnected"):M(n,l);if(a.account.id!==e.accountId||!R(t.snapshot.account,t.providerIdentity,t.credential,a.account,a.providerIdentity,a.credential))throw h("account_changed");if(i==="external"&&a.credential.accessToken===t.credential?.accessToken)throw h("credential_unchanged");let o,r=!1;return await this.runMutation(async()=>{if(n.aborted)throw M(n,l);if(this.state.authMode!==t.authMode||this.state.generation!==t.generation||this.state.snapshot.state!=="authenticated"||this.state.snapshot.account.id!==e.accountId||i==="external"&&(t.externalOwner?.aborted!==!1||this.state.externalOwner!==t.externalOwner))throw h("stale_generation");const c=this.nextGeneration(),u=this.state.snapshot.account;o={account:structuredClone(a.account),...a.providerIdentity===void 0?{}:{providerIdentity:structuredClone(a.providerIdentity)},credential:structuredClone(a.credential),generation:c},await this.executeProductTransition({authentication:o,credentialOrder:"after_product",mode:i,origin:"child_refresh",signal:n,commitCredential:d(async()=>{await this.consumer.setAuthentication(o),r=!F(u,a.account),await this.setState({...this.state,...a.providerIdentity===void 0?{}:{providerIdentity:structuredClone(a.providerIdentity)},credential:structuredClone(a.credential),generation:c,snapshot:{account:structuredClone(a.account),mode:i,state:"authenticated"}})},"commitCredential")})}),!this.productLifecycle&&r&&await this.notifyCurrentAccountUpdated(),o}async ensurePublicInitialized(t){try{await this.ensureInitialized(t)}catch(e){throw I(e)??e}}getOrStartManagedDiscovery(){const t=this.managedActivationEpoch,e=this.authenticationEpoch,n=this.managedDiscovery;if(n&&n.activationEpoch===t&&n.authenticationEpoch===e)return n;const i=++this.managedDiscoverySequence,o=this.discoverManagedAuthentication({activationEpoch:t,authenticationEpoch:e,sequence:i}).then(c=>(this.managedDiscovery?.promise===o&&!c.applied&&(this.managedDiscovery=void 0),c),c=>{throw this.managedDiscovery?.promise===o&&(this.managedDiscovery=void 0),c});o.catch(()=>{});const r={activationEpoch:t,authenticationEpoch:e,promise:o};return this.managedDiscovery=r,r}async discoverManagedAuthentication(t){const e=await this.managedAuth.readManagedAuth({signal:this.initializationController.signal});let n=!1;return await this.runMutation(async()=>{if(this.closed||t.activationEpoch!==this.managedActivationEpoch||t.authenticationEpoch!==this.authenticationEpoch||this.initialization!==void 0||this.state.authMode!=="none"||t.sequence<this.managedDiscoveryLastApplied)return;this.managedDiscoveryLastApplied=t.sequence;const i=e.account;this.pendingManagedRestore=e.authenticated&&i!==null;const a=this.pendingManagedRestore&&i?D(i):void 0;this.pendingManagedAccount=a,n=!0}),{...t,applied:n,snapshot:e}}async awaitManagedDiscovery(t){for(;;){if(this.closed)throw new Error("Authentication runtime is closed");if(t.aborted)throw M(t,l);if(this.state.authMode!=="none"||this.initialization!==void 0)return;const e=this.getOrStartManagedDiscovery();let n;try{n=await P("managedAuthDiscoveryWait",()=>C(e.promise,t,l))}catch(i){if(this.state.authMode!=="none"||this.initialization!==void 0||e.activationEpoch!==this.managedActivationEpoch||e.authenticationEpoch!==this.authenticationEpoch)return;throw i}if(n.applied&&n.activationEpoch===this.managedActivationEpoch&&n.authenticationEpoch===this.authenticationEpoch&&this.state.authMode==="none"&&this.initialization===void 0)return n.snapshot}}async ensureInitialized(t){for(;;){if(this.closed)throw new Error("Authentication runtime is closed");if(t.aborted)throw M(t,l);if(this.initialization){await C(this.initialization,t,l);return}if(this.state.authMode!=="none")return;try{await this.managedPreparation.run((e,n)=>this.initializeManagedRuntime(e,n),{signal:t})}catch(e){if(this.initialization!==void 0)continue;throw e}}}startManagedPreparation(){return this.closed?Promise.reject(new Error("Authentication runtime is closed")):this.initialization!==void 0||this.state.authMode!=="none"?Promise.resolve():this.managedPreparation.run((t,e)=>this.initializeManagedRuntime(t,e))}async initializeManagedRuntime(t,e){for(;;){if(this.closed)throw new Error("Authentication runtime is closed");if(t.aborted)throw M(t,l);if(this.initialization!==void 0||this.state.authMode!=="none")return;const n=await this.awaitManagedDiscovery(t);if(e.phaseCompleted("discovery_ready"),this.initialization!==void 0||this.state.authMode!=="none")return;if(n){if(!n.authenticated||!n.account){this.initialization??=Promise.resolve();return}this.managedActivationEpoch+=1,this.managedDiscovery=void 0,await this.initializeFromManaged(n.account,t,e),this.initialization??=Promise.resolve();return}}}async initializeFromManaged(t,e,n){let i=await P("managedCredentialRead",()=>this.managedAuth.readManagedAuthCredential({signal:e}));if(n.phaseCompleted("credential_ready"),i.account.id!==t.id)throw new Error("Managed authentication projection changed identity");try{await P("productReconcile",()=>this.commitManaged(i,void 0,e))}catch(a){if(!(a instanceof CodeBuddyAuthProductRefreshRequiredError))throw a;const o=await P("managedCredentialRefresh",()=>this.managedAuth.refreshManagedAuthCredential(t.id,{signal:e}));n.phaseCompleted("credential_refreshed");const r=v(i),c=v(o);if(!R(r.account,r.providerIdentity,r.credential,c.account,c.providerIdentity,c.credential))throw h("account_changed");i=o,await P("productReconcile",()=>this.commitManaged(i,void 0,e))}n.phaseCompleted("product_ready")}async reconcileManagedLoginForRequest(t){try{await this.reconcileSucceededManagedLogin(t)}catch(e){throw this.isCurrentAuthenticationOperation(t)&&this.startManagedLoginReconciliation(t),e}}async reconcileSucceededManagedLogin(t,e){await this.fencePreviousAuthenticationForManagedLogin(t),this.assertCurrentAuthenticationOperation(t);const n=this.state.generation;await this.withPolicyDeadline(this.loginCleanupTimeoutMs,[t.signal,...e===void 0?[]:[e]],async i=>{const[a,o]=await Promise.all([this.managedAuth.readManagedAuth({signal:i}),this.managedAuth.readManagedAuthCredential({signal:i})]);if(!a.authenticated||!a.account||a.account.id!==o.account.id)throw h("managed_projection_unavailable");if(i.aborted)throw M(i,l);await this.commitManaged(o,{expectedGeneration:n,signal:i,token:t})}),this.assertCurrentAuthenticationOperation(t),this.pendingManagedLoginId=void 0}fencePreviousAuthenticationForManagedLogin(t){return this.fenceAuthenticationForOperation(t,new Error("Managed login replaced the authentication state"))}async commitManaged(t,e,n){if(n===void 0)return this.withPolicyDeadline(this.refreshTimeoutMs,e?.signal===void 0?[]:[e.signal],o=>this.commitManaged(t,e,o));const i=v(t),a=await this.runMutation(async()=>{if(e){if(this.assertCurrentAuthenticationOperation(e.token),e.signal?.aborted)throw M(e.signal,l);if(this.state.generation!==e.expectedGeneration)throw new O}const o=this.state.authMode!=="managed"||this.state.snapshot.state!=="authenticated"||!F(this.state.snapshot.account,i.account),r=this.nextGeneration(),c=this.state.authMode!=="none"&&(this.state.authMode!=="managed"||this.state.snapshot.state!=="authenticated"||this.state.snapshot.account.id!==i.account.id||!R(this.state.snapshot.account,this.state.providerIdentity,this.state.credential,i.account,i.providerIdentity,i.credential));this.abortRefreshFlights(new Error("Managed authentication state was replaced"));const u={...i,generation:r};return await this.executeProductTransition({authentication:u,credentialOrder:"after_product",mode:"managed",origin:e?"explicit_auth_mutation":"lazy_activation",signal:n,commitCredential:d(async()=>{await this.consumer.setAuthentication(u,{fenceExisting:c}),this.clearPendingManagedRestore(),await this.setState({authMode:"managed",providerIdentity:structuredClone(i.providerIdentity),credential:structuredClone(i.credential),generation:r,snapshot:{account:structuredClone(i.account),mode:"managed",state:"authenticated"}})},"commitCredential")}),o});return this.notifyRuntimePrepared(),a}startPendingManagedLoginReconciliation(t,e){this.startReconciliation("pending_login",t,async n=>{for(;this.canContinueReconciliation(t,n);){let i;try{i=await this.withBackgroundDeadline(t,n,a=>this.managedAuth.readManagedAuthLogin(e,{signal:a}))}catch{}if(!this.canContinueReconciliation(t,n))return;if(i?.state==="succeeded"){await this.runManagedLoginReconciliation(t,n);return}if(i?.settled){this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}await this.waitForDelay(this.loginPollIntervalMs,n)}},e)}startManagedLoginReconciliation(t){this.startReconciliation("managed_login",t,e=>this.runManagedLoginReconciliation(t,e))}async runManagedLoginReconciliation(t,e){for(;this.canContinueReconciliation(t,e);){try{if(await this.reconcileSucceededManagedLogin(t,e),!this.canContinueReconciliation(t,e))return;this.productLifecycle||await this.notifyCurrentAccountUpdated().catch(()=>{});return}catch(n){if(this.shouldStopReconciliation(n,t,e))return}await this.waitForDelay(this.loginPollIntervalMs,e)}}startManagedLogoutReconciliation(t,e,n=!0){this.startReconciliation("managed_logout",t,async i=>{let a=!1;for(;this.canContinueReconciliation(t,i);){let o=e===void 0;if(e!==void 0){const c=await this.withBackgroundDeadline(t,i,u=>this.managedAuth.readManagedAuthLogin(e,{signal:u})).catch(()=>{});if(!this.canContinueReconciliation(t,i))return;if(a||=c?.state==="succeeded",o=a||c?.settled===!0,c?.state==="pending"&&await this.withBackgroundDeadline(t,i,u=>this.managedAuth.cancelManagedAuthLogin(e,{signal:u})).catch(()=>{}),!a&&c?.settled===!0&&c?.state!=="succeeded"&&!n){this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}}if(!n&&a&&await this.fenceManagedAuthenticationForOperation(t,new Error("Superseded managed login committed durably")),!n&&!o){await this.waitForDelay(this.loginPollIntervalMs,i);continue}const r=await this.withBackgroundDeadline(t,i,c=>this.managedAuth.readManagedAuth({signal:c})).catch(()=>{});if(!this.canContinueReconciliation(t,i))return;if(r&&!r.authenticated&&o){this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}r?.authenticated&&await this.withBackgroundDeadline(t,i,c=>this.managedAuth.logoutManagedAuth({signal:c})).catch(()=>{}),await this.waitForDelay(this.loginPollIntervalMs,i)}},e,n)}startReconciliation(t,e,n,i,a){if(!this.isCurrentAuthenticationOperation(e))return;const o=this.reconciliation;if(o&&o.epoch===e.epoch&&o.kind===t&&o.loginId===i&&o.logoutCurrentManaged===a)return;this.abortReconciliation(new Error("Authentication reconciliation was replaced"));const r=new AbortController,c=AbortSignal.any([e.signal,r.signal]),u=n(c).catch(()=>{}).finally(()=>{this.reconciliation?.controller===r&&(this.reconciliation=void 0)}),p={controller:r,epoch:e.epoch,kind:t,...i===void 0?{}:{loginId:i},...a===void 0?{}:{logoutCurrentManaged:a},promise:u};this.reconciliation=p}async awaitManagedLogin(t,e){const n=new AbortController,i=AbortSignal.any([e.signal,e.connectionSignal,n.signal]);let a,o,r,c=t;try{for(;c.state==="pending";){if(e.signal.aborted||e.connectionSignal.aborted)throw M(e.signal.aborted?e.signal:e.connectionSignal,l);if("error"in(o??{}))throw o.error;if(o&&"action"in o&&o.action!=="accept")throw h(o.action);if(c.authUrl&&!r){if(!$(e))throw h("url_elicitation_unsupported");if(e.requestId===void 0||e.requestId===null)throw new Error("Authentication request has no JSON-RPC request id");a=c.loginId;const p={elicitationId:a,message:"Complete sign-in in your browser.",mode:"url",requestId:e.requestId,url:c.authUrl},w=T("CreateElicitationRequest",p);if(w)throw new Error(`Invalid authentication elicitation: ${w.message}`);r=e.request(b.client.elicitation.create,p,{signal:i,timeoutMs:null}).then(m=>{if(T("CreateElicitationResponse",m)||!E(m))throw new Error("Client returned an invalid elicitation response");o={action:m.action}}).catch(m=>{n.signal.aborted||(o={error:m})})}const u=Date.parse(c.expiresAt);if(!Number.isFinite(u)||this.processRuntime.policyNow()>=u)throw h("timed_out");await this.waitForDelay(this.loginPollIntervalMs,e.signal),c=await this.managedAuth.readManagedAuthLogin(c.loginId,{signal:e.signal})}return c}finally{n.abort(new Error("Authentication elicitation completed")),await r?.catch(()=>{}),a&&await e.notify(b.client.elicitation.complete,{elicitationId:a}).catch(()=>{})}}async awaitManagedLoginSettlement(t,e,n){let i=e;for(;!i?.settled;){i&&await this.waitForDelay(this.loginPollIntervalMs,n);const a=await this.managedAuth.readManagedAuthLogin(t,{signal:n});if(!a)throw new Error("Host returned no authentication login state");i=a}return i}async cancelManagedLogin(t){return this.withPolicyDeadline(this.loginCleanupTimeoutMs,[],e=>Promise.resolve(this.managedAuth.cancelManagedAuthLogin(t,{signal:e}))).catch(()=>{})}async cancelSupersededManagedLogin(t,e){this.pendingManagedLoginId??=e;const n=await this.cancelManagedLogin(e);if(this.assertCurrentAuthenticationOperation(t),n?.settled&&n.state!=="succeeded"){this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}if(n?.settled&&n.state==="succeeded")try{await this.fenceManagedAuthenticationForOperation(t,new Error("Superseded managed login committed durably")),await this.withAuthenticationDeadline(t,this.loginCleanupTimeoutMs,i=>this.managedAuth.logoutManagedAuth({signal:i})),this.assertCurrentAuthenticationOperation(t),this.pendingManagedLoginId===e&&(this.pendingManagedLoginId=void 0);return}catch(i){throw this.isCurrentAuthenticationOperation(t)&&this.startManagedLogoutReconciliation(t,e,!1),i}throw this.startManagedLogoutReconciliation(t,e,!1),h("managed_login_cancellation_ambiguous")}async refreshExternal(t,e,n){if(!this.bridge||!n)throw h();let i;try{i=await this.bridge.requestAccountRefresh({accountId:t.accountId},{expectedOwner:n,signal:e})}catch(a){throw n.aborted?h("owner_disconnected"):a}return{account:i.account,credential:i.credential}}beginExplicitAuthenticationOperation(t){if(this.closed)throw new Error("Authentication runtime is closed");const e=this.pendingManagedLoginId;this.authenticationEpoch+=1,this.authenticationOperationController?.abort(t),this.abortReconciliation(t);const n=new AbortController;return this.authenticationOperationController=n,{...e===void 0?{}:{pendingLoginId:e},token:{epoch:this.authenticationEpoch,signal:n.signal}}}isCurrentAuthenticationOperation(t){return!this.closed&&t.epoch===this.authenticationEpoch&&this.authenticationOperationController?.signal===t.signal&&!t.signal.aborted}assertCurrentAuthenticationOperation(t){if(!this.isCurrentAuthenticationOperation(t))throw new _}withAuthenticationDeadline(t,e,n){return this.withPolicyDeadline(e,[t.signal],n)}withBackgroundDeadline(t,e,n){return this.withPolicyDeadline(this.loginCleanupTimeoutMs,[t.signal,e],n)}async fenceAuthenticationForOperation(t,e,n={}){for(;;){this.assertCurrentAuthenticationOperation(t);const i=this.state.generation;try{return await this.runMutation(async()=>{if(this.assertCurrentAuthenticationOperation(t),this.state.generation!==i)throw new O;if(this.state.authMode==="none"||n.authMode!==void 0&&this.state.authMode!==n.authMode)return!1;const a=this.nextGeneration();return this.abortRefreshFlights(e),await this.withAuthenticationDeadline(t,this.loginCleanupTimeoutMs,o=>this.executeProductTransition({credentialOrder:"before_product",mode:"none",origin:"explicit_auth_mutation",signal:o,commitCredential:d(async()=>{this.clearPendingManagedRestore(),await this.setState(y(a)),await this.consumer.clearAuthentication({generation:a})},"commitCredential")})),!0})}catch(a){if(a instanceof O&&this.isCurrentAuthenticationOperation(t))continue;throw a}}}async fenceManagedAuthenticationForOperation(t,e){await this.fenceAuthenticationForOperation(t,e,{authMode:"managed"})&&!this.productLifecycle&&await this.notifyCurrentAccountUpdated().catch(()=>{})}canContinueReconciliation(t,e){return!e.aborted&&this.isCurrentAuthenticationOperation(t)}shouldStopReconciliation(t,e,n){return n.aborted||!this.isCurrentAuthenticationOperation(e)||t instanceof _}abortReconciliation(t){const e=this.reconciliation;e&&!e.controller.signal.aborted&&e.controller.abort(t)}nextGeneration(){if(this.state.generation>=Number.MAX_SAFE_INTEGER)throw new Error("Authentication generation exhausted");return this.state.generation+1}abortRefreshFlights(t){this.refreshFlights.abortAll(t)}async executeProductTransition(t){const e=this.productLifecycle;if(!e){await t.commitCredential();return}if(t.signal.aborted)throw M(t.signal,l);let n=!1,i=!1,a,o;try{o=await e.transition({...t.authentication===void 0?{}:{authentication:structuredClone(t.authentication)},credentialOrder:t.credentialOrder,mode:t.mode,origin:t.origin,productMode:t.productMode??this.activeProductMode,signal:t.signal,commitCredential:d(async()=>{if(n)throw new A("transition");n=!0;try{await t.commitCredential(),i=!0}catch(r){throw a=r,r}},"commitCredential")})}catch(r){if(a!==void 0)throw a;if(i)try{await this.notifyCurrentAccountUpdated()}catch(c){throw e.fail?.(c),new A("publication")}throw r instanceof CodeBuddyAuthProductRefreshRequiredError||!i&&r instanceof CodeBuddyAuthProductResolveError||!i&&r instanceof g||r instanceof A?r:new A("transition")}if(!i)throw new A("transition");try{await this.notifyCurrentAccountUpdated(),await o.publish()}catch(r){throw e.fail?.(r),new A("publication")}}runMutation(t,e={}){if(this.closed&&e.allowClosed!==!0)return Promise.reject(new Error("Authentication runtime is closed"));const n=d(()=>this.closed&&e.allowClosed!==!0?Promise.reject(new Error("Authentication runtime is closed")):t(),"guardedOperation");return this.mutationGate.run(()=>n(),{signal:e.signal,uninterruptible:!0})}waitForDelay(t,e){return this.processRuntime.policyDelay(t,e,l)}async withPolicyDeadline(t,e,n){const i=this.processRuntime.createPolicyDeadline(t,{signals:e});try{return await n(i.signal)}finally{i.close()}}}export function createCodeBuddyAuthRuntime(s,t=L()){return new CodeBuddyAuthRuntime(s,t)}d(createCodeBuddyAuthRuntime,"createCodeBuddyAuthRuntime");
|
package/lib/session/replay.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export interface SessionReplayProjection {
|
|
|
37
37
|
readonly response: AgentHarnessResumeSessionResponse;
|
|
38
38
|
}
|
|
39
39
|
/** Pure projection seam; the implementation reuses agent-cli's ACP codecs. */
|
|
40
|
-
export type SessionReplayProjector = (snapshot: SessionSnapshot, replayFrom: AgentHarnessResumeSessionRequest['replayFrom'], readFile?: (path: string) => Promise<Uint8Array
|
|
40
|
+
export type SessionReplayProjector = (snapshot: SessionSnapshot, replayFrom: AgentHarnessResumeSessionRequest['replayFrom'], readFile?: (path: string) => Promise<Uint8Array>, contextSize?: (modelId?: string) => number | undefined) => Promise<SessionReplayProjection>;
|
|
41
41
|
export type AgentItemProjector = (sessionId: string, item: SessionSnapshot['history'][number]) => Promise<AcpV2UpdateSessionNotification[]>;
|
|
42
42
|
export type AgentEventProjector = (frame: import('#agent-harness-codebuddy/server').AgentEvent) => Promise<AcpV2UpdateSessionNotification[]>;
|
|
43
43
|
export declare const replayCodecs: () => Promise<typeof import('#agent-harness-components/session-replay')>;
|
package/lib/session/replay.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var h=Object.defineProperty;var r=(l,o)=>h(l,"name",{value:o,configurable:!0});import{Context as b,Effect as y,Layer as x}from"effect";import{isRecord as A}from"../internal/guards.js";import{loadAgentServerModule as I}from"../runtime/private-runtime-role.js";import{AgentHarnessInvalidParamsError as p}from"../server/errors.js";import{createSubagentHistory as v,readSessionTree as C}from"../subagent/history.js";import{SessionConfigStore as R}from"./config-store.js";import{ServerSessionConfig as S}from"./server-config.js";import{turnReplayValidationError as U}from"./turn.js";let _;export const replayCodecs=r(()=>_??=import("#agent-harness-components/session-replay"),"replayCodecs");export async function replaySession(l,o,s,g={},w){s.signal.throwIfAborted();const t=U(o.replayFrom);if(t)throw new p(t);const e=await l(o.sessionId,{...g,cwd:o.cwd,signal:s.signal,includeSubagents:!0});if(!e)throw new p(`Session '${o.sessionId}' was not found in the requested cwd`);if(s.signal.throwIfAborted(),e.mainAgent&&s.config?.update({agent:e.mainAgent}),o.replayFrom==null)return{};const{projectSessionReplay:d,createSessionUsage:f}=await replayCodecs(),c=s.config?f(e.sessionId,e.history,await C(l,o,s.signal,g,e)):void 0,i=o.replayFrom,u=await d(e,i,w,n=>s.config?.contextSize(n)).catch(n=>{throw n instanceof Error&&"code"in n&&typeof n.code=="string"&&["invalid_history","invalid_replay","cursor_not_found"].includes(n.code)?new p(n.message):n});for(const n of u.events){s.signal.throwIfAborted();const a=n.update._meta;if(A(a)){const m=a["codebuddy.ai/requestId"];typeof m=="string"&&a["codebuddy.ai/rootRequestId"]===void 0&&(n.update._meta={...a,"codebuddy.ai/rootRequestId":m})}await s.onUpdate(n)}if(s.config){const n=c?.context,a=s.config.contextSize();s.signal.throwIfAborted(),n&&a!==void 0&&await s.onUpdate({sessionId:e.sessionId,update:{sessionUpdate:"usage_update",used:n.used,size:a,...c?.cost?{cost:c.cost}:{}}})}return s.signal.throwIfAborted(),u.response}r(replaySession,"replaySession");export class SessionReplay extends b.Service()("@genie/agent-harness/session/SessionReplay"){static{r(this,"SessionReplay")}static layer(o={},s,g){return x.effect(SessionReplay,y.gen(function*(){const w=yield*R;return SessionReplay.of({subagents:v(async(t,e)=>(await I()).readSession(t,e),async(...t)=>(await replayCodecs()).projectSessionReplay(...t),o,s,async(t,e,d,f)=>{const c=await S.create({product:t.workspace?.product});c.restore(await y.runPromise(w.read(t)));const i=(await replayCodecs()).createSessionUsage(t.sessionId,[],d).snapshot(e),u=c.contextSize(i.context?.modelId);return f.throwIfAborted(),i.context&&u!==void 0?{sessionId:e,update:{sessionUpdate:"usage_update",used:i.context.used,size:u,...i.cost?{cost:i.cost}:{}}}:void 0}),resume:r((t,e)=>y.tryPromise({try:r(async()=>{const d=await I(),[f,c]=await Promise.all([g?.(t.cwd,e.signal),y.runPromise(w.read({sessionId:t.sessionId,cwd:t.cwd}))]),i=await S.create({product:e.workspace?.product},e.workspace?.sessionModelConfigOption,e.clientCapabilities,f);return i.restore(c),{...await replaySession(d.readSession,t,{...e,config:i},o,s),configOptions:i.snapshot()}},"try"),catch:r(d=>d,"catch")}),"resume")})}))}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var I=Object.defineProperty;var h=(g,t)=>I(g,"name",{value:t,configurable:!0});import{isRecord as c}from"../internal/guards.js";import{AGENT_HARNESS_ERROR_META_KEY as y,AGENT_HARNESS_ERROR_UPDATE as l,agentHarnessErrorSchema as f}from"../protocol/error.js";import{replayCodecs as a}from"./replay.js";export class ServerSessionEvents{static{h(this,"ServerSessionEvents")}constructor(t,e,s,n){this.sessionId=t,this.deliver=e,this.config=s,this.persistConfig=n,this.delivery=Promise.resolve(),this.configurationObserved=!1,this.interactions=new Map,this.pendingTools=new Map}get meta(){return this.requestId?{"codebuddy.ai/requestId":this.requestId,"codebuddy.ai/rootRequestId":this.requestId}:{}}async interaction(t,e){const s=e["codebuddy.ai/requestId"];if(typeof s!="string")return;const n=Math.max(0,(this.interactions.get(s)??0)+(t?1:-1));n?this.interactions.set(s,n):this.interactions.delete(s),(!t&&n===0||t&&n===1)&&(e["codebuddy.ai/subagent"]||this.requestId===s)&&await this.send({sessionUpdate:"state_update",state:t?"requires_action":"running"},e)}async begin(t){const e=Promise.withResolvers();e.promise.catch(()=>{}),this.completion={runId:t,outcome:e},this.requestId||await this.start(t)}async start(t){this.requestId!==t&&(this.requestId=t,this.foregroundError=void 0,this.resultError=void 0,await this.send({sessionUpdate:"state_update",state:"running"},this.meta))}waitForCompletion(t){return this.completion?.runId!==t?Promise.reject(new Error("No matching foreground run")):this.completion.outcome.promise}fail(t){this.completion?.outcome.reject(t)}async end(t){const e=t.stopReason==="error"?this.foregroundError??(this.resultError?.runId===t.runId?this.resultError.error:void 0)??(await a()).projectAgentError(t.errorMessage??"Agent execution failed"):void 0;e&&!this.foregroundError&&await this.send({sessionUpdate:l,error:e,willRetry:!1},this.meta),await this.finishTools(s=>!s["codebuddy.ai/subagent"]&&s["codebuddy.ai/requestId"]===t.runId,t.stopReason==="aborted"?"Tool execution cancelled":"Tool did not complete"),await this.send({sessionUpdate:"state_update",state:"idle",stopReason:t.stopReason==="aborted"?"cancelled":t.stopReason==="error"?l:"end_turn",...t.usage?{usage:t.usage}:{}},{...this.meta,...e?{[y]:e}:{}}),this.requestId=void 0,this.interactions.delete(t.runId),this.completion?.runId===t.runId&&this.completion.outcome.resolve(t)}async restoreUsage(t,e){this.accounting=(await a()).createSessionUsage(this.sessionId,t,e),this.lastContextTokens=this.accounting.context?.used??(t.length===0?0:void 0)}async configuration(t){await this.send({sessionUpdate:"config_option_update",configOptions:t}),this.lastContextTokens!==void 0&&await this.usage(this.lastContextTokens)}send(t,e={}){const s={sessionId:this.sessionId,update:{...t,_meta:{...e,...c(t._meta)?t._meta:{}}}};return t.sessionUpdate===l&&t.willRetry===!1&&this.requestId!==void 0&&s.update._meta["codebuddy.ai/requestId"]===this.requestId&&!s.update._meta["codebuddy.ai/subagent"]&&(this.foregroundError=f.parse(t.error)),t.sessionUpdate==="tool_call_update"&&typeof t.toolCallId=="string"&&(t.status==="completed"||t.status==="failed"||t.status==="cancelled"?this.pendingTools.delete(t.toolCallId):(t.status==="pending"||t.status==="in_progress")&&this.pendingTools.set(t.toolCallId,s.update._meta)),this.delivery=this.delivery.then(()=>this.deliver(s)),this.delivery}async finishTools(t,e){for(const[s,n]of this.pendingTools)t(n)&&await this.send({sessionUpdate:"tool_call_update",toolCallId:s,status:"failed",content:[{type:"content",content:{type:"text",text:e}}]},n)}async usage(t,e,s={}){const n=this.config?.contextSize(e),i=s["codebuddy.ai/subagent"],o=c(i)&&typeof i.sessionId=="string"?i.sessionId:this.sessionId,d=this.accounting?.snapshot(o).cost;n!==void 0&&await this.send({sessionUpdate:"usage_update",used:t,size:n,...d?{cost:d}:{}},s)}async catalog(t){const e=await a();for(const s of await e.projectAgentEvent({type:"agent_event",session_id:this.sessionId,event:{type:"catalog",data:t}}))await this.accept({type:"acp_update",notification:s})}async accept(t){if("session_id"in t&&t.session_id!==this.sessionId)return;if(t.type==="run_started"){await this.start(t.runId);return}if(t.type==="run_completed"){if(!this.requestId&&this.completion?.runId===t.runId&&(this.requestId=t.runId,this.foregroundError=void 0,this.resultError=void 0),t.session_id===this.sessionId&&t.runId===this.requestId){const{type:i,session_id:o,_meta:d,...r}=t;await this.end(r)}return}const e={...t.origin===void 0?this.meta:{},...t._meta,...t.origin?.requestId?{"codebuddy.ai/requestId":t.origin.requestId}:{},...t.origin?.rootRequestId?{"codebuddy.ai/rootRequestId":t.origin.rootRequestId}:{},...t.origin?.subagent?{"codebuddy.ai/subagent":t.origin.subagent}:{}},s=h(i=>this.send(i,e),"send"),n=t.item??(t.type==="agent_event"&&t.event.type==="input"?t.event.data:void 0);if(n){this.accounting??=(await a()).createSessionUsage(this.sessionId);const i=e["codebuddy.ai/subagent"],o=c(i)&&typeof i.sessionId=="string"?i.sessionId:this.sessionId;this.accounting.accept(n,o);const d=(await a()).readItemUsageMeta(n,e),r=this.accounting.snapshot(o).context;d&&r&&await this.usage(r.used,r.modelId,d);const u=t.origin?.requestId??t._meta?.["codebuddy.ai/requestId"]??n.providerData?.conversationRequestId;if(o===this.sessionId&&typeof u=="string"&&u===this.requestId){const p=(await a()).projectAgentItemError(n);p&&(this.resultError={runId:u,error:p})}}if(t.type==="acp_update"){t.notification.sessionId===this.sessionId&&await s(t.notification.update);return}if(t.type==="agent_event"){if(t.event.type==="subagent_status"&&(this.accounting??=(await a()).createSessionUsage(this.sessionId),this.accounting.child(t.event.data.sessionId,t.event.data.parentSessionId,t.event.data.parentToolCallId)),t.event.type==="subagent_status"&&t.event.data.status!=="running"){const i=t.event.data.sessionId;this.interactions.delete(t.event.data.conversationRequestId),await this.finishTools(o=>c(o["codebuddy.ai/subagent"])&&o["codebuddy.ai/subagent"].sessionId===i,"Subagent tool did not complete")}if(t.event.type==="error"){const i=t.origin?.requestId;i&&i===this.requestId&&!t.origin?.subagent&&this.resultError?.runId!==i&&(this.resultError={runId:i,error:(await a()).projectAgentFailure(t.event.data)})}else if(t.event.type==="configuration"){const i=t.origin?.subagent?void 0:this.config?.copy(),o=JSON.stringify(this.config?.selections()),d=i?.update(t.event.data,this.configurationObserved);i&&(this.configurationObserved=!0),i&&d&&(this.config.replace(i),JSON.stringify(i.selections())!==o&&await this.persistConfig?.(i),await s({sessionUpdate:"config_option_update",configOptions:i.snapshot()}))}else t.event.type==="usage"?(t.origin?.subagent||(this.lastContextTokens=t.event.data.contextTokens),await this.usage(t.event.data.contextTokens,t.event.data.modelId,e),t.origin?.subagent&&this.lastContextTokens!==void 0&&await this.usage(this.lastContextTokens)):t.event.type==="input"&&this.completeToolInvocation(t.event.data)}}completeToolInvocation(t){c(t)&&t.type==="function_call_result"&&t.status==="completed"&&typeof t.callId=="string"&&this.pendingTools.delete(t.callId)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var h=Object.defineProperty;var
|
|
1
|
+
var h=Object.defineProperty;var l=(o,t)=>h(o,"name",{value:t,configurable:!0});import{createAskUserQuestionElicitation as A,normalizeAskUserQuestionElicitationAnswers as m}from"#agent-harness-components/question-elicitation";import{FILE_DIRECTORY_APPROVAL_OPTION_ID as q,parseSandboxPermissionMetadata as k}from"#agent-harness-components/sandbox";import{abortable as C}from"../internal/async.js";import{isRecord as y}from"../internal/guards.js";function v(o){if(!Array.isArray(o.questions)||o.questions.length===0)throw new Error("AskUserQuestion requires questions");return{questions:o.questions.map(t=>{if(!y(t)||typeof t.question!="string"||!Array.isArray(t.options))throw new Error("Invalid AskUserQuestion question");return{question:t.question,header:typeof t.header=="string"?t.header:"",multiSelect:t.multiSelect===!0,options:t.options.map(a=>{if(!y(a)||typeof a.label!="string")throw new Error("Invalid AskUserQuestion option");return{label:a.label,description:typeof a.description=="string"?a.description:""}})}})}}l(v,"questionsFrom");export function serverCanUseTool(o,t,a){return async(d,n,e)=>{const i=l(r=>({behavior:"deny",message:r}),"deny");if(e.signal.aborted)return i("Interaction cancelled");const{id:b,meta:p}=t(),c=e.origin?{...e.origin.requestId?{"codebuddy.ai/requestId":e.origin.requestId}:{},...e.origin.rootRequestId?{"codebuddy.ai/rootRequestId":e.origin.rootRequestId}:{},...e.origin.subagent?{"codebuddy.ai/subagent":e.origin.subagent}:{}}:p,g=l(async r=>{await a?.(!0,c);try{return await C(r(),e.signal)}finally{e.signal.aborted||await a?.(!1,c)}},"interact");if(d==="AskUserQuestion"){if(!o.clientCapabilities.elicitation?.form)return i("Client does not support form elicitation");const r=v(n),I=await g(()=>o.callbacks.createElicitation(A(r,b,e.toolUseID,c),{signal:e.signal}));return e.signal.aborted||I.action!=="accept"?{...i("User declined to answer"),interrupt:!0}:{behavior:"allow",updatedInput:{...n,answers:m(r,I.content)}}}const u=e.suggestions?.length?structuredClone(e.suggestions):void 0,f=e.metadata?structuredClone(e.metadata):void 0,{fileApprovalScope:w}=f?.["codebuddy.ai/sandboxIntercept"]===!0?k(f):{},_={sessionId:b,title:e.title??e.displayName??d,...e.description?{description:e.description}:{},subject:{type:"tool_call",toolCall:{toolCallId:e.toolUseID,title:d,rawInput:n,...e.blockedPath?{locations:[{path:e.blockedPath}]}:{},...f?{_meta:{...f,"codebuddy.ai/toolName":d}}:{}}},options:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},...u&&!w?[{optionId:"allow_always",name:u.every(r=>r.destination==="session")?"Allow for this session":"Always allow",kind:"allow_always"}]:[],{optionId:"reject_once",name:"Reject",kind:"reject_once"}],_meta:c},s=await g(()=>o.callbacks.requestPermission(_,{signal:e.signal}));return e.signal.aborted||s.outcome.outcome!=="selected"?i("Permission request cancelled"):s.outcome.optionId==="allow_once"?{behavior:"allow",updatedInput:n,decisionClassification:"user_temporary"}:s.outcome.optionId===q&&w?{behavior:"allow",updatedInput:n,decisionClassification:"user_permanent",metadata:{_fileDirectoryApprovalResponderVersion:1}}:s.outcome.optionId==="allow_always"&&w?{behavior:"allow",updatedInput:n,decisionClassification:"user_temporary"}:s.outcome.optionId==="allow_always"&&u?{behavior:"allow",updatedInput:n,updatedPermissions:u,decisionClassification:"user_permanent"}:{...i("Permission denied"),decisionClassification:"user_reject"}}}l(serverCanUseTool,"serverCanUseTool");
|
package/lib/subagent/history.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var y=Object.defineProperty;var
|
|
1
|
+
var y=Object.defineProperty;var p=(d,i)=>y(d,"name",{value:i,configurable:!0});import{isRecord as m}from"../internal/guards.js";import{AGENT_HARNESS_JSON_RPC_ERROR_CODES as b,AgentHarnessJsonRpcError as w}from"../server/errors.js";import{projectStoredSubagentDescriptor as _}from"./projection.js";const R=1e3,g=1e5;function I(d){return new w(b.internalError,d)}p(I,"invalidHistory");function A(d,i,o){let u={sessionId:o.sessionId,parentSessionId:i.sessionId,rootSessionId:d,runtimeStatus:"notLoaded",state:null};for(const e of i.history){if(!["function_call_result","function_call_output"].includes(e.type??""))continue;const t=e.providerData?.toolResult?.subAgent;if(!m(t)||t.sessionId!==o.sessionId||t.descriptor===void 0)continue;const s=_(t.descriptor);if(s.sessionId!==o.sessionId||s.parentSessionId!==i.sessionId||s.rootSessionId!==d||s.parentToolCallId!==("callId"in e?e.callId:void 0))throw I("Stored Subagent descriptor disagrees with its transcript parent");u={...s,runtimeStatus:"notLoaded",state:s.state.state==="running"?null:s.state}}let n;for(let e=o.history.length-1;e>=0;e--){const t=o.history[e];if(t.type==="message"&&t.role==="user"){n=t;break}}if(n){const e=n.providerData;typeof e?.agent=="string"&&(u={...u,agentName:e.agent});const t=e?.conversationRequestId;if(typeof t=="string"&&t&&u._meta?.["codebuddy.ai/requestId"]!==t){const{parentToolCallId:s,error:a,...f}=u;u={...f,state:null,_meta:{"codebuddy.ai/requestId":t,...typeof e?.rootRequestId=="string"?{"codebuddy.ai/rootRequestId":e.rootRequestId}:{}}}}}return u}p(A,"snapshotFor");export async function readSessionTree(d,i,o,u={},n){const e={...u,cwd:i.cwd,signal:o,includeSubagents:!0};o.throwIfAborted();const t=n===void 0?await d(i.sessionId,e):n;if(o.throwIfAborted(),!t)return[];const s=[{snapshot:t}],a=new Set([i.sessionId]);let f=t.history.length;if(f>g)throw I("Subagent history exceeds the item limit");for(let l=0;l<s.length;l++){const r=s[l].snapshot;for(const c of r.subagents??[]){if(o.throwIfAborted(),a.has(c.sessionId))throw I("Duplicate or cyclic Subagent storage identity");if(a.size>R)throw I("Subagent history exceeds the child limit");a.add(c.sessionId);const h=await d(c.key,e);if(o.throwIfAborted(),!h)throw I(`Subagent transcript disappeared: ${c.sessionId}`);if(h.sessionId!==c.sessionId)throw I("Subagent storage identity changed while reading");if(f+=h.history.length,f>g)throw I("Subagent history exceeds the item limit");s.push({snapshot:h,parentSessionId:r.sessionId})}}return s}p(readSessionTree,"readSessionTree");export function createSubagentHistory(d,i,o={},u,n){const e=p(async(t,s)=>{const a=await readSessionTree(d,t,s,o),f=new Map(a.map(r=>[r.snapshot.sessionId,r.snapshot])),l=a.filter(r=>r.parentSessionId).map(r=>({subagent:A(t.sessionId,f.get(r.parentSessionId),r.snapshot),snapshot:r.snapshot}));return{tree:a,records:l}},"visit");return{list:p(async(t,s)=>(await e(t,s)).records.map(a=>a.subagent),"list"),read:p(async(t,s,a)=>{const{tree:f,records:l}=await e(t,a),r=l.find(S=>S.snapshot.sessionId===s);if(!r)return;const c=await n?.(t,s,f,a),h=await i(r.snapshot,{type:"start"},u,()=>c?.update.sessionUpdate==="usage_update"&&typeof c.update.size=="number"?c.update.size:void 0);return a.throwIfAborted(),{subagent:r.subagent,journal:[...h.events,...c?[c]:[]]}},"read")}}p(createSubagentHistory,"createSubagentHistory");export function mergeSubagentReplay(d,i){const o=p(n=>{const e=n.update;return"messageId"in e&&typeof e.messageId=="string"?`${n.sessionId}:${e.sessionUpdate}:${e.messageId}`:void 0},"messageKey"),u=new Set(i.map(o).filter(n=>n!==void 0));return[...d.filter(n=>!u.has(o(n))),...i].filter(n=>n.update.sessionUpdate!=="state_update")}p(mergeSubagentReplay,"mergeSubagentReplay");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tencent-ai/agent-harness",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.4",
|
|
4
4
|
"description": "Standalone JSON-RPC agent harness backed by CodeBuddy Code",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
"types": "./lib/components/sandbox-center.d.mts",
|
|
41
41
|
"default": "./lib/components/sandbox-center.mjs"
|
|
42
42
|
},
|
|
43
|
+
"#agent-harness-components/sandbox": {
|
|
44
|
+
"types": "./lib/components/sandbox.d.mts",
|
|
45
|
+
"default": "./lib/components/sandbox.mjs"
|
|
46
|
+
},
|
|
43
47
|
"#agent-harness-components/session-replay": {
|
|
44
48
|
"types": "./lib/components/session-replay.d.mts",
|
|
45
49
|
"default": "./lib/components/session-replay.mjs"
|
|
@@ -220,13 +224,14 @@
|
|
|
220
224
|
"@tencent-ai/sandbox-cli-linux-arm64": "5.8.0-beta.7",
|
|
221
225
|
"@tencent-ai/sandbox-cli-linux-x64": "5.8.0-beta.7",
|
|
222
226
|
"@tencent-ai/sandbox-cli-win32-x64": "5.8.0-beta.7",
|
|
223
|
-
"
|
|
224
|
-
"@tencent-ai/agent-harness-darwin-
|
|
225
|
-
"@tencent-ai/agent-harness-
|
|
226
|
-
"@tencent-ai/agent-harness-linux-arm64
|
|
227
|
-
"@tencent-ai/agent-harness-linux-
|
|
228
|
-
"@tencent-ai/agent-harness-linux-x64
|
|
229
|
-
"@tencent-ai/agent-harness-
|
|
227
|
+
"esbuild": "^0.25.12",
|
|
228
|
+
"@tencent-ai/agent-harness-darwin-arm64": "0.2.0-beta.4",
|
|
229
|
+
"@tencent-ai/agent-harness-darwin-x64": "0.2.0-beta.4",
|
|
230
|
+
"@tencent-ai/agent-harness-linux-arm64": "0.2.0-beta.4",
|
|
231
|
+
"@tencent-ai/agent-harness-linux-arm64-musl": "0.2.0-beta.4",
|
|
232
|
+
"@tencent-ai/agent-harness-linux-x64": "0.2.0-beta.4",
|
|
233
|
+
"@tencent-ai/agent-harness-linux-x64-musl": "0.2.0-beta.4",
|
|
234
|
+
"@tencent-ai/agent-harness-win32-x64": "0.2.0-beta.4"
|
|
230
235
|
},
|
|
231
236
|
"devDependencies": {
|
|
232
237
|
"@anthropic-ai/sandbox-runtime": "0.0.17",
|
|
@@ -263,7 +268,7 @@
|
|
|
263
268
|
"@types/sinon": "^10.0.15",
|
|
264
269
|
"@types/which": "^3.0.4",
|
|
265
270
|
"@types/ws": "^8.18.1",
|
|
266
|
-
"esbuild": "0.
|
|
271
|
+
"esbuild": "^0.25.12",
|
|
267
272
|
"pngjs": "6.0.0",
|
|
268
273
|
"rxjs": "^6.6.0",
|
|
269
274
|
"sinon": "^15.2.0",
|