@code-yeongyu/senpi 2026.10.9 → 2026.10.10-3

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.
Files changed (113) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/bundle/chunks/{anthropic-messages-CVXI6CLT.js → anthropic-messages-OE3QBX4P.js} +1 -1
  3. package/dist/bundle/chunks/{app-server-command-2HNDZGTR.js → app-server-command-DVWM37GF.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-MJGHZT4N.js → chunk-3A3C5VVO.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-Q2ZTPMWD.js → chunk-4TK7VCZZ.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-CB77NQMN.js → chunk-7GVD54RM.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-6EH7QXOG.js → chunk-CTERKXVZ.js} +2 -2
  8. package/dist/bundle/chunks/{chunk-SB22X6ZR.js → chunk-H4UIUFU5.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-CM5QTRC2.js → chunk-H67EVDWG.js} +1 -1
  10. package/dist/bundle/chunks/chunk-I5HLTDT4.js +2 -0
  11. package/dist/bundle/chunks/chunk-IZOTKUWG.js +2 -0
  12. package/dist/bundle/chunks/{chunk-DERNLWDS.js → chunk-MT2C4I5R.js} +151 -148
  13. package/dist/bundle/chunks/{chunk-LSE7KE2C.js → chunk-ODYQK5XJ.js} +1 -1
  14. package/dist/bundle/chunks/chunk-PDSG6VER.js +14 -0
  15. package/dist/bundle/chunks/{chunk-LUWWM7GA.js → chunk-RADHRQ4K.js} +3 -3
  16. package/dist/bundle/chunks/chunk-RRU5LXMS.js +3 -0
  17. package/dist/bundle/chunks/{chunk-7Q3EY6HH.js → chunk-UMJL74VN.js} +1 -1
  18. package/dist/bundle/chunks/{chunk-3YXB7Z7O.js → chunk-Z7MMKKIY.js} +1 -1
  19. package/dist/bundle/chunks/{cli-main-VMDAGZCA.js → cli-main-B4S4DGBX.js} +1 -1
  20. package/dist/bundle/chunks/{help-fast-path-JBQLYO7W.js → help-fast-path-EHRZEBRO.js} +1 -1
  21. package/dist/bundle/chunks/{host-command-HTYYQBSG.js → host-command-VATE7HRG.js} +1 -1
  22. package/dist/bundle/chunks/{host-lifecycle-XZF6IKKO.js → host-lifecycle-GC3GIR2N.js} +1 -1
  23. package/dist/bundle/chunks/{interactive-mode-U7IH4VMJ.js → interactive-mode-QOFA64JL.js} +1 -1
  24. package/dist/bundle/chunks/{multi-session-host-HHIC6N7C.js → multi-session-host-E5RDPWQN.js} +1 -1
  25. package/dist/bundle/chunks/{openai-completions-6HU7GIGD.js → openai-completions-Q2LEWXEC.js} +1 -1
  26. package/dist/bundle/chunks/{openai-responses-S4QYZXF3.js → openai-responses-DHGWSTZM.js} +1 -1
  27. package/dist/bundle/chunks/{package-manager-cli-2FXWPM2U.js → package-manager-cli-YGTWXRG5.js} +1 -1
  28. package/dist/bundle/chunks/{rotation-stream-ZJQ6I2RZ.js → rotation-stream-C5BM7TMM.js} +1 -1
  29. package/dist/bundle/chunks/{rpc-mode-K5YGBGQO.js → rpc-mode-HDAGQ4X3.js} +1 -1
  30. package/dist/bundle/chunks/{schedule-command-CVAPK2WQ.js → schedule-command-EQ4PQCRP.js} +1 -1
  31. package/dist/bundle/chunks/{session-control-endpoint-THEF3K7M.js → session-control-endpoint-NABTZHCZ.js} +2 -2
  32. package/dist/bundle/chunks/{session-picker-R5N2EKUS.js → session-picker-O7OESJWU.js} +1 -1
  33. package/dist/bundle/chunks/session-worker.js +70 -67
  34. package/dist/bundle/cli.js +1 -1
  35. package/dist/bundle/index.js +1 -1
  36. package/dist/bundle/rpc-entry.js +1 -1
  37. package/dist/bundle/runtime-manifest.json +1 -1
  38. package/dist/core/agent-session-runtime.d.ts +9 -0
  39. package/dist/core/agent-session-runtime.js +22 -0
  40. package/dist/core/agent-session.d.ts +14 -1
  41. package/dist/core/agent-session.js +56 -8
  42. package/dist/core/extensions/builtin/btw/panel.d.ts +3 -1
  43. package/dist/core/extensions/builtin/btw/panel.js +14 -9
  44. package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts +5 -0
  45. package/dist/core/extensions/builtin/compaction/context-pipeline.js +1 -0
  46. package/dist/core/extensions/builtin/compaction/index.js +2 -1
  47. package/dist/core/extensions/builtin/compaction/lane-policy.d.ts +7 -0
  48. package/dist/core/extensions/builtin/compaction/lane-policy.js +28 -15
  49. package/dist/core/extensions/builtin/compaction/log.d.ts +2 -0
  50. package/dist/core/extensions/builtin/compaction/log.js +2 -1
  51. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +14 -8
  52. package/dist/core/extensions/builtin/goal/cache-warm.d.ts +4 -2
  53. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +1 -1
  54. package/dist/core/extensions/builtin/goal/monitor-continuation.js +9 -1
  55. package/dist/core/extensions/builtin/goal/prompt.d.ts +6 -1
  56. package/dist/core/extensions/builtin/goal/prompt.js +32 -1
  57. package/dist/core/extensions/builtin/mcp/commands.js +21 -26
  58. package/dist/core/extensions/builtin/mcp/config-edit.d.ts +2 -0
  59. package/dist/core/extensions/builtin/mcp/config-edit.js +5 -2
  60. package/dist/core/extensions/builtin/mcp/manager-view.d.ts +34 -0
  61. package/dist/core/extensions/builtin/mcp/manager-view.js +136 -0
  62. package/dist/core/extensions/builtin/mcp/manager.d.ts +8 -0
  63. package/dist/core/extensions/builtin/mcp/manager.js +193 -0
  64. package/dist/core/extensions/builtin/mcp/service.d.ts +3 -1
  65. package/dist/core/extensions/builtin/mcp/service.js +4 -0
  66. package/dist/core/extensions/builtin/rules/rules/finder.js +8 -3
  67. package/dist/core/extensions/builtin/websearch/websearch/config.js +2 -0
  68. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +1 -0
  69. package/dist/core/extensions/builtin/websearch/websearch/providers/keenable.d.ts +3 -0
  70. package/dist/core/extensions/builtin/websearch/websearch/providers/keenable.js +55 -0
  71. package/dist/core/extensions/builtin/websearch/websearch/providers.js +2 -0
  72. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +1 -1
  73. package/dist/core/model-config-schema.d.ts +5 -0
  74. package/dist/core/model-config-schema.js +1 -0
  75. package/dist/core/provider-composer.js +5 -1
  76. package/dist/core/provider-timeout-retry.d.ts +7 -1
  77. package/dist/core/provider-timeout-retry.js +23 -12
  78. package/dist/core/reload-veto.d.ts +1 -1
  79. package/dist/core/reload-veto.js +7 -1
  80. package/dist/core/retry-fallback/expansion.js +9 -3
  81. package/dist/core/sdk.js +7 -3
  82. package/dist/core/thinking-levels.d.ts +23 -1
  83. package/dist/core/thinking-levels.js +37 -0
  84. package/dist/core/trust-manager.js +50 -0
  85. package/dist/main.js +12 -13
  86. package/dist/modes/interactive/interactive-mode.js +8 -0
  87. package/dist/modes/interactive/session-control-endpoint.js +33 -8
  88. package/dist/modes/interactive/session-control-registry.js +3 -1
  89. package/dist/modes/interactive/session-control-wake.d.ts +11 -5
  90. package/dist/modes/interactive/session-control-wake.js +38 -16
  91. package/dist/modes/rpc/connection-handler.d.ts +5 -0
  92. package/dist/modes/rpc/connection-handler.js +30 -3
  93. package/dist/modes/rpc/custom-capability.d.ts +6 -0
  94. package/dist/modes/rpc/custom-capability.js +6 -0
  95. package/dist/modes/rpc/host-daemon-paths.d.ts +5 -4
  96. package/dist/modes/rpc/host-daemon-paths.js +17 -9
  97. package/dist/modes/rpc/host-daemon-registration.d.ts +6 -1
  98. package/dist/modes/rpc/host-daemon-registration.js +6 -2
  99. package/dist/modes/rpc/host-session-control.js +6 -4
  100. package/dist/modes/rpc/rpc-client.d.ts +5 -0
  101. package/dist/modes/rpc/rpc-client.js +7 -0
  102. package/dist/modes/rpc/rpc-mode.js +1 -1
  103. package/dist/modes/rpc/rpc-types.d.ts +9 -0
  104. package/docs/json.md +3 -0
  105. package/docs/mcp.md +16 -1
  106. package/docs/models.md +34 -0
  107. package/docs/rpc.md +36 -1
  108. package/docs/web-search.md +3 -1
  109. package/package.json +6 -6
  110. package/dist/bundle/chunks/chunk-6SMU7ANE.js +0 -3
  111. package/dist/bundle/chunks/chunk-M3BQ2PAQ.js +0 -14
  112. package/dist/bundle/chunks/chunk-VJJ53ORU.js +0 -2
  113. package/dist/bundle/chunks/chunk-YSPHACIN.js +0 -2
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{HOST_DAEMON_LAYOUT,ProcessIdentityUnreadableError,canonicalEndpointPath,claimOwnerIsLive,createHostDaemonPaths,generationPaths,hostDaemonDirectoryPaths,parseDaemonPidFile,parseJson,processMatchesPidFile,readFileOrUndefined,readSessionPathClaims,readSocketSecret,resolveSocketTransportAddress,socketNamesDirectory,socketSecretPath}from"./chunk-LUWWM7GA.js";import{readdir}from"node:fs/promises";import{basename as basename2,join}from"node:path";import{createHash}from"node:crypto";import{basename}from"node:path";var TUI_SOCKET_NAME=/^t-[0-9a-f]{16}\.sock$/;function tuiSocketName(instanceId){return`t-${createHash("sha256").update(instanceId,"utf8").digest("hex").slice(0,16)}.sock`}function isTuiControlSocket(socket){return TUI_SOCKET_NAME.test(basename(socket))}function socketNeedsHandshake(socket,platform=process.platform){return platform==="win32"||isTuiControlSocket(socket)}var ENDPOINT_DIRECTORY_NAME=/^[0-9a-f]{16}$/;async function listHostEndpoints(agentDir){let flatDir=join(agentDir,"rpc-host-daemon");if(parseJson(await readFileOrUndefined(join(flatDir,"layout.json")).catch(()=>{}))?.layout!==HOST_DAEMON_LAYOUT)return[];let dirs=(await readdir(flatDir,{withFileTypes:!0}).catch(()=>[])).filter(entry=>entry.isDirectory()&&ENDPOINT_DIRECTORY_NAME.test(entry.name)).map(entry=>join(flatDir,entry.name)).sort(),endpoints=[];for(let dir of dirs)endpoints.push(await identifyEndpoint(dir));return endpoints}async function identifyEndpoint(dir){let paths=hostDaemonDirectoryPaths(dir),named=await recordNaming(paths.endpointFile,dir);if(named!==void 0)return{socket:named.socket,dir,identity:"endpoint",endpoint_kind:endpointKindOf(named.record)};let booted=await recordNaming(paths.settingsFile,dir);if(booted!==void 0)return{socket:booted.socket,dir,identity:"settings",endpoint_kind:"rpc_host"};let generations=await readdir(paths.generationsDir).catch(()=>[]);for(let instanceId of generations.sort()){let recorded=await recordNaming(join(paths.generationsDir,instanceId,"settings.json"),dir);if(recorded!==void 0)return{socket:recorded.socket,dir,identity:"generation-settings",endpoint_kind:"rpc_host"}}return{socket:null,dir,identity:"unknown",endpoint_kind:"rpc_host"}}async function endpointKindOfSocket(socket,agentDir){if(isTuiControlSocket(socket))return"tui";let paths=createHostDaemonPaths({socket,agentDir}),named=await recordNaming(paths.endpointFile,paths.dir);return named===void 0?"rpc_host":endpointKindOf(named.record)}function endpointKindOf(record){return record.endpoint_kind==="tui"?"tui":"rpc_host"}async function recordNaming(file,dir){let record=parseJson(await readFileOrUndefined(file).catch(()=>{})),socket=record?.socket;if(!(record===void 0||typeof socket!="string"||socket===""))return socketNamesDirectory(socket,basename2(dir))?{socket,record}:void 0}import{lstat as lstat2,rm}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{createHash as createHash2}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname,join as join2}from"node:path";import{stat}from"node:fs/promises";var LegacyLockArtifactError=class extends Error{constructor(lockPath){super(`Legacy lock directory is present at ${lockPath}`),this.code="ELEGACY_LOCK_ARTIFACT",this.name="LegacyLockArtifactError",this.lockPath=lockPath}},DEFAULT_RETRIES={retries:100,minTimeout:20,maxTimeout:100};async function openLockDatabase(lockPath){if(typeof globalThis.Bun<"u"){let{Database}=await import("bun:sqlite"),database2=new Database(lockPath,{create:!0});return{exec:sql=>database2.exec(sql),close:()=>database2.close(!1)}}let{DatabaseSync}=await import("node:sqlite"),database=new DatabaseSync(lockPath);return{exec:sql=>database.exec(sql),close:()=>database.close()}}async function acquireOwnershipSafeLock(lockPath,options={}){let retries=options.retries??DEFAULT_RETRIES,deadline=Date.now()+retries.retries*retries.maxTimeout;for(;;){await rejectLegacyDirectory(lockPath);let busyMs=Math.max(1,Math.min(retries.maxTimeout,deadline-Date.now())),database;try{database=await openLockDatabase(lockPath),database.exec(`PRAGMA busy_timeout = ${busyMs}; BEGIN EXCLUSIVE;`);let released=!1,held=database;return async()=>{if(!released){released=!0;try{held.exec("COMMIT;")}finally{held.close()}}}}catch(error){try{database?.close()}catch{}if(await rejectLegacyDirectory(lockPath),isBusy(error)&&Date.now()<deadline){await new Promise(resolve=>setTimeout(resolve,Math.min(retries.minTimeout,Math.max(1,deadline-Date.now()))));continue}throw error}}}async function rejectLegacyDirectory(lockPath){try{if((await stat(lockPath)).isDirectory())throw new LegacyLockArtifactError(lockPath)}catch(error){if(error instanceof LegacyLockArtifactError||error.code!=="ENOENT")throw error}}function isBusy(error){let message=error instanceof Error?error.message:String(error);return/busy|locked/i.test(message)||error?.code==="SQLITE_BUSY"}var LOCK_BUSY_WAIT_MS=100;function hostEnsureLockTarget(socket){return join2(tmpdir(),"senpi-rpc-host-locks",createSocketLockName(socket))}async function acquireHostEnsureLock(socket,waitMs){let lockTarget=hostEnsureLockTarget(socket);return await mkdir(dirname(lockTarget),{recursive:!0}),await writeFile(lockTarget,"",{flag:"a",mode:384}),acquireOwnershipSafeLock(`${lockTarget}.lock`,hostEnsureLockOptions(waitMs))}function hostEnsureLockOptions(waitMs){return{retries:{retries:Math.ceil(waitMs/LOCK_BUSY_WAIT_MS),minTimeout:20,maxTimeout:LOCK_BUSY_WAIT_MS}}}function createSocketLockName(socket){return createHash2("sha256").update(socketLockAddress(socket),"utf8").digest("hex").slice(0,32)}function socketLockAddress(socket){return process.platform==="win32"||socket.startsWith("\0")?resolveSocketTransportAddress(socket,process.platform):canonicalEndpointPath(socket)}import{lstat,readdir as readdir2}from"node:fs/promises";import{createConnection}from"node:net";import{basename as basename3,dirname as dirname2,join as join3}from"node:path";var SOCKET_PROBE_TIMEOUT_MS=2e3;async function endpointInUse(paths,socket){if(await anyGenerationLive(paths))return{inUse:"live_generation"};for(let claim of await readSessionPathClaims(paths.reservationsDir))if(await claimOwnerIsLive(claim.owner))return{inUse:"live_claim"};let silence=await socketSilence(socket);if(silence===void 0)return{inUse:"reachable"};let successors=(await socketSiblings(socket)).filter(name=>name.startsWith(`${basename3(socket)}.next-`));for(let successor of successors)if(await socketSilence(join3(dirname2(socket),successor))===void 0)return{inUse:"reachable"};return{inUse:void 0,silence}}async function socketSiblings(socket){let name=basename3(socket);return(await readdir2(dirname2(socket)).catch(()=>[])).filter(entry=>entry.startsWith(`${name}.next-`)||entry.startsWith(`${name}.shield-`))}async function anyGenerationLive(paths){for(let instanceId of await readdir2(paths.generationsDir).catch(()=>[])){let record=generationRecord(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(record!==void 0&&await recordIsLive(record))return!0}return!1}function generationRecord(text){if(text===void 0)return;let record=parseDaemonPidFile(text);if(record!==void 0)return record;let pid=parseJson(text)?.pid;return typeof pid=="number"&&Number.isInteger(pid)&&pid>0?{pid,processStartTime:null}:void 0}async function recordIsLive(record){try{return await processMatchesPidFile(record)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}}async function socketSilence(socket){let secret;return process.platform==="win32"&&(secret=await readSocketSecret(socketSecretPath(socket)).catch(()=>{}),secret===void 0)?"socket_absent":new Promise(resolveProbe=>{let connection=createConnection(resolveSocketTransportAddress(socket,process.platform,secret)),finish=value=>{clearTimeout(timeout),connection.destroy(),resolveProbe(value)},timeout=setTimeout(()=>finish(void 0),SOCKET_PROBE_TIMEOUT_MS);connection.once("connect",()=>finish(void 0)),connection.once("error",error=>{error.code==="ECONNREFUSED"?refusedBySocket(socket).then(finish):error.code==="ENOENT"?finish("socket_absent"):finish(void 0)})})}async function refusedBySocket(socket){if(process.platform==="win32"||socket.startsWith("\0"))return"socket_refused";try{return(await lstat(socket)).isSocket()?"socket_refused":void 0}catch(error){return error instanceof Error&&"code"in error&&error.code==="ENOENT"?"socket_absent":void 0}}var GC_LOCK_WAIT_MS=2e3;async function gcHostEndpoints(agentDir,options={}){let removed=[],kept=[],wanted=kind=>options.kinds===void 0||options.kinds.includes(kind),legacy=wanted("rpc_host")?await legacyFlatDirectory(agentDir):void 0;legacy!==void 0&&kept.push({socket:null,dir:legacy,reason:"legacy_layout"});for(let endpoint of await listHostEndpoints(agentDir)){if(!wanted(endpoint.endpoint_kind))continue;if(endpoint.socket===null){kept.push({socket:null,dir:endpoint.dir,reason:"unknown_identity"});continue}let entry={socket:endpoint.socket,dir:endpoint.dir};try{let outcome=await gcEndpoint(endpoint.socket,endpoint.dir,options);outcome.removed?outcome.skipped.length===0?removed.push({...entry,reason:outcome.reason}):removed.push({...entry,reason:outcome.reason,skipped:outcome.skipped}):kept.push({...entry,reason:outcome.reason})}catch(error){kept.push({...entry,reason:"failed",error:error instanceof Error?error.message:String(error)})}}return{removed,kept}}async function gcEndpoint(socket,dir,options){let release=await acquireEnsureLock(socket);if(release===void 0)return{removed:!1,reason:"locked"};try{await options._test?.afterLockAcquired?.(socket);let evidence=await endpointInUse(hostDaemonDirectoryPaths(dir),socket);if(evidence.inUse!==void 0)return{removed:!1,reason:evidence.inUse};let skipped=await removeEndpoint(socket,dir);return{removed:!0,reason:evidence.silence,skipped}}finally{await release()}}async function removeEndpoint(socket,dir){let skipped=[];for(let sibling of await socketSiblings(socket)){let path=join4(dirname3(socket),sibling),entry=await lstat2(path).catch(error=>{if(!(error instanceof Error&&"code"in error&&error.code==="ENOENT"))throw error});entry?.isDirectory()?skipped.push({path,type:"directory"}):entry!==void 0&&await rm(path,{force:!0})}return await rm(socket,{force:!0}),await rm(dir,{recursive:!0,force:!0}),skipped}async function acquireEnsureLock(socket){return acquireHostEnsureLock(socket,GC_LOCK_WAIT_MS).catch(()=>{})}async function legacyFlatDirectory(agentDir){let flatDir=join4(agentDir,"rpc-host-daemon");return parseJson(await readFileOrUndefined(join4(flatDir,"layout.json")).catch(()=>{}))?.layout===HOST_DAEMON_LAYOUT?void 0:await readFileOrUndefined(join4(flatDir,"host.pid")).catch(()=>{})!==void 0?flatDir:void 0}export{tuiSocketName,socketNeedsHandshake,listHostEndpoints,endpointKindOfSocket,acquireOwnershipSafeLock,hostEnsureLockTarget,acquireHostEnsureLock,hostEnsureLockOptions,anyGenerationLive,gcHostEndpoints,gcEndpoint};
2
+ import{HOST_DAEMON_LAYOUT,ProcessIdentityUnreadableError,canonicalEndpointPath,claimOwnerIsLive,createHostDaemonPaths,generationPaths,hostDaemonDirectoryPaths,parseDaemonPidFile,parseJson,processMatchesPidFile,readFileOrUndefined,readSessionPathClaims,readSocketSecret,resolveSocketTransportAddress,socketNamesDirectory,socketSecretPath}from"./chunk-RADHRQ4K.js";import{readdir}from"node:fs/promises";import{basename as basename2,join}from"node:path";import{createHash}from"node:crypto";import{basename}from"node:path";var TUI_SOCKET_NAME=/^t-[0-9a-f]{16}\.sock$/;function tuiSocketName(instanceId){return`t-${createHash("sha256").update(instanceId,"utf8").digest("hex").slice(0,16)}.sock`}function isTuiControlSocket(socket){return TUI_SOCKET_NAME.test(basename(socket))}function socketNeedsHandshake(socket,platform=process.platform){return platform==="win32"||isTuiControlSocket(socket)}var ENDPOINT_DIRECTORY_NAME=/^[0-9a-f]{16}$/;async function listHostEndpoints(agentDir){let flatDir=join(agentDir,"rpc-host-daemon");if(parseJson(await readFileOrUndefined(join(flatDir,"layout.json")).catch(()=>{}))?.layout!==HOST_DAEMON_LAYOUT)return[];let dirs=(await readdir(flatDir,{withFileTypes:!0}).catch(()=>[])).filter(entry=>entry.isDirectory()&&ENDPOINT_DIRECTORY_NAME.test(entry.name)).map(entry=>join(flatDir,entry.name)).sort(),endpoints=[];for(let dir of dirs)endpoints.push(await identifyEndpoint(dir));return endpoints}async function identifyEndpoint(dir){let paths=hostDaemonDirectoryPaths(dir),named=await recordNaming(paths.endpointFile,dir);if(named!==void 0)return{socket:named.socket,dir,identity:"endpoint",endpoint_kind:endpointKindOf(named.record)};let booted=await recordNaming(paths.settingsFile,dir);if(booted!==void 0)return{socket:booted.socket,dir,identity:"settings",endpoint_kind:"rpc_host"};let generations=await readdir(paths.generationsDir).catch(()=>[]);for(let instanceId of generations.sort()){let recorded=await recordNaming(join(paths.generationsDir,instanceId,"settings.json"),dir);if(recorded!==void 0)return{socket:recorded.socket,dir,identity:"generation-settings",endpoint_kind:"rpc_host"}}return{socket:null,dir,identity:"unknown",endpoint_kind:"rpc_host"}}async function endpointKindOfSocket(socket,agentDir){if(isTuiControlSocket(socket))return"tui";let paths=createHostDaemonPaths({socket,agentDir}),named=await recordNaming(paths.endpointFile,paths.dir);return named===void 0?"rpc_host":endpointKindOf(named.record)}function endpointKindOf(record){return record.endpoint_kind==="tui"?"tui":"rpc_host"}async function recordNaming(file,dir){let record=parseJson(await readFileOrUndefined(file).catch(()=>{})),socket=record?.socket;if(!(record===void 0||typeof socket!="string"||socket===""))return socketNamesDirectory(socket,basename2(dir))?{socket,record}:void 0}import{lstat as lstat2,rm}from"node:fs/promises";import{dirname as dirname3,join as join4}from"node:path";import{createHash as createHash2}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{tmpdir}from"node:os";import{dirname,join as join2}from"node:path";import{stat}from"node:fs/promises";var LegacyLockArtifactError=class extends Error{constructor(lockPath){super(`Legacy lock directory is present at ${lockPath}`),this.code="ELEGACY_LOCK_ARTIFACT",this.name="LegacyLockArtifactError",this.lockPath=lockPath}},DEFAULT_RETRIES={retries:100,minTimeout:20,maxTimeout:100};async function openLockDatabase(lockPath){if(typeof globalThis.Bun<"u"){let{Database}=await import("bun:sqlite"),database2=new Database(lockPath,{create:!0});return{exec:sql=>database2.exec(sql),close:()=>database2.close(!1)}}let{DatabaseSync}=await import("node:sqlite"),database=new DatabaseSync(lockPath);return{exec:sql=>database.exec(sql),close:()=>database.close()}}async function acquireOwnershipSafeLock(lockPath,options={}){let retries=options.retries??DEFAULT_RETRIES,deadline=Date.now()+retries.retries*retries.maxTimeout;for(;;){await rejectLegacyDirectory(lockPath);let busyMs=Math.max(1,Math.min(retries.maxTimeout,deadline-Date.now())),database;try{database=await openLockDatabase(lockPath),database.exec(`PRAGMA busy_timeout = ${busyMs}; BEGIN EXCLUSIVE;`);let released=!1,held=database;return async()=>{if(!released){released=!0;try{held.exec("COMMIT;")}finally{held.close()}}}}catch(error){try{database?.close()}catch{}if(await rejectLegacyDirectory(lockPath),isBusy(error)&&Date.now()<deadline){await new Promise(resolve=>setTimeout(resolve,Math.min(retries.minTimeout,Math.max(1,deadline-Date.now()))));continue}throw error}}}async function rejectLegacyDirectory(lockPath){try{if((await stat(lockPath)).isDirectory())throw new LegacyLockArtifactError(lockPath)}catch(error){if(error instanceof LegacyLockArtifactError||error.code!=="ENOENT")throw error}}function isBusy(error){let message=error instanceof Error?error.message:String(error);return/busy|locked/i.test(message)||error?.code==="SQLITE_BUSY"}var LOCK_BUSY_WAIT_MS=100;function hostEnsureLockTarget(socket){return join2(tmpdir(),"senpi-rpc-host-locks",createSocketLockName(socket))}async function acquireHostEnsureLock(socket,waitMs){let lockTarget=hostEnsureLockTarget(socket);return await mkdir(dirname(lockTarget),{recursive:!0}),await writeFile(lockTarget,"",{flag:"a",mode:384}),acquireOwnershipSafeLock(`${lockTarget}.lock`,hostEnsureLockOptions(waitMs))}function hostEnsureLockOptions(waitMs){return{retries:{retries:Math.ceil(waitMs/LOCK_BUSY_WAIT_MS),minTimeout:20,maxTimeout:LOCK_BUSY_WAIT_MS}}}function createSocketLockName(socket){return createHash2("sha256").update(socketLockAddress(socket),"utf8").digest("hex").slice(0,32)}function socketLockAddress(socket){return process.platform==="win32"||socket.startsWith("\0")?resolveSocketTransportAddress(socket,process.platform):canonicalEndpointPath(socket)}import{lstat,readdir as readdir2}from"node:fs/promises";import{createConnection}from"node:net";import{basename as basename3,dirname as dirname2,join as join3}from"node:path";var SOCKET_PROBE_TIMEOUT_MS=2e3;async function endpointInUse(paths,socket){if(await anyGenerationLive(paths))return{inUse:"live_generation"};for(let claim of await readSessionPathClaims(paths.reservationsDir))if(await claimOwnerIsLive(claim.owner))return{inUse:"live_claim"};let silence=await socketSilence(socket);if(silence===void 0)return{inUse:"reachable"};let successors=(await socketSiblings(socket)).filter(name=>name.startsWith(`${basename3(socket)}.next-`));for(let successor of successors)if(await socketSilence(join3(dirname2(socket),successor))===void 0)return{inUse:"reachable"};return{inUse:void 0,silence}}async function socketSiblings(socket){let name=basename3(socket);return(await readdir2(dirname2(socket)).catch(()=>[])).filter(entry=>entry.startsWith(`${name}.next-`)||entry.startsWith(`${name}.shield-`))}async function anyGenerationLive(paths){for(let instanceId of await readdir2(paths.generationsDir).catch(()=>[])){let record=generationRecord(await readFileOrUndefined(generationPaths(paths,instanceId).pidFile));if(record!==void 0&&await recordIsLive(record))return!0}return!1}function generationRecord(text){if(text===void 0)return;let record=parseDaemonPidFile(text);if(record!==void 0)return record;let pid=parseJson(text)?.pid;return typeof pid=="number"&&Number.isInteger(pid)&&pid>0?{pid,processStartTime:null}:void 0}async function recordIsLive(record){try{return await processMatchesPidFile(record)}catch(error){if(error instanceof ProcessIdentityUnreadableError)return!0;throw error}}async function socketSilence(socket){let secret;return process.platform==="win32"&&(secret=await readSocketSecret(socketSecretPath(socket)).catch(()=>{}),secret===void 0)?"socket_absent":new Promise(resolveProbe=>{let connection=createConnection(resolveSocketTransportAddress(socket,process.platform,secret)),finish=value=>{clearTimeout(timeout),connection.destroy(),resolveProbe(value)},timeout=setTimeout(()=>finish(void 0),SOCKET_PROBE_TIMEOUT_MS);connection.once("connect",()=>finish(void 0)),connection.once("error",error=>{error.code==="ECONNREFUSED"?refusedBySocket(socket).then(finish):error.code==="ENOENT"?finish("socket_absent"):finish(void 0)})})}async function refusedBySocket(socket){if(process.platform==="win32"||socket.startsWith("\0"))return"socket_refused";try{return(await lstat(socket)).isSocket()?"socket_refused":void 0}catch(error){return error instanceof Error&&"code"in error&&error.code==="ENOENT"?"socket_absent":void 0}}var GC_LOCK_WAIT_MS=2e3;async function gcHostEndpoints(agentDir,options={}){let removed=[],kept=[],wanted=kind=>options.kinds===void 0||options.kinds.includes(kind),legacy=wanted("rpc_host")?await legacyFlatDirectory(agentDir):void 0;legacy!==void 0&&kept.push({socket:null,dir:legacy,reason:"legacy_layout"});for(let endpoint of await listHostEndpoints(agentDir)){if(!wanted(endpoint.endpoint_kind))continue;if(endpoint.socket===null){kept.push({socket:null,dir:endpoint.dir,reason:"unknown_identity"});continue}let entry={socket:endpoint.socket,dir:endpoint.dir};try{let outcome=await gcEndpoint(endpoint.socket,endpoint.dir,options);outcome.removed?outcome.skipped.length===0?removed.push({...entry,reason:outcome.reason}):removed.push({...entry,reason:outcome.reason,skipped:outcome.skipped}):kept.push({...entry,reason:outcome.reason})}catch(error){kept.push({...entry,reason:"failed",error:error instanceof Error?error.message:String(error)})}}return{removed,kept}}async function gcEndpoint(socket,dir,options){let release=await acquireEnsureLock(socket);if(release===void 0)return{removed:!1,reason:"locked"};try{await options._test?.afterLockAcquired?.(socket);let evidence=await endpointInUse(hostDaemonDirectoryPaths(dir),socket);if(evidence.inUse!==void 0)return{removed:!1,reason:evidence.inUse};let skipped=await removeEndpoint(socket,dir);return{removed:!0,reason:evidence.silence,skipped}}finally{await release()}}async function removeEndpoint(socket,dir){let skipped=[];for(let sibling of await socketSiblings(socket)){let path=join4(dirname3(socket),sibling),entry=await lstat2(path).catch(error=>{if(!(error instanceof Error&&"code"in error&&error.code==="ENOENT"))throw error});entry?.isDirectory()?skipped.push({path,type:"directory"}):entry!==void 0&&await rm(path,{force:!0})}return await rm(socket,{force:!0}),await rm(dir,{recursive:!0,force:!0}),skipped}async function acquireEnsureLock(socket){return acquireHostEnsureLock(socket,GC_LOCK_WAIT_MS).catch(()=>{})}async function legacyFlatDirectory(agentDir){let flatDir=join4(agentDir,"rpc-host-daemon");return parseJson(await readFileOrUndefined(join4(flatDir,"layout.json")).catch(()=>{}))?.layout===HOST_DAEMON_LAYOUT?void 0:await readFileOrUndefined(join4(flatDir,"host.pid")).catch(()=>{})!==void 0?flatDir:void 0}export{tuiSocketName,socketNeedsHandshake,listHostEndpoints,endpointKindOfSocket,acquireOwnershipSafeLock,hostEnsureLockTarget,acquireHostEnsureLock,hostEnsureLockOptions,anyGenerationLive,gcHostEndpoints,gcEndpoint};
@@ -0,0 +1,2 @@
1
+ import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
+ var forcedToolChoiceRefusals=new Set;function isRecord(value){return typeof value=="object"&&value!==null}function extractHttpStatus(error){if(!isRecord(error))return;let status=error.status;if(typeof status=="number")return status;let response=error.response;if(isRecord(response)&&typeof response.status=="number")return response.status}function errorMessage(error){return error instanceof Error?error.message:typeof error=="string"?error:String(error)}var IN_BAND_BEFORE_CONTENT=Symbol.for("senpi.forcedToolChoice.inBandBeforeContent");function isInBandBeforeContent(error){return isRecord(error)&&error[IN_BAND_BEFORE_CONTENT]===!0}function markInBandBeforeContent(error){let marked=isRecord(error)?error:new Error(errorMessage(error));try{Object.defineProperty(marked,IN_BAND_BEFORE_CONTENT,{value:!0})}catch{}return marked}function isRequestRefusal(error){let status=extractHttpStatus(error);return status===400||status===void 0&&isInBandBeforeContent(error)}async function primeStreamUntilContent(stream,hasContent,maxBuffered=64){let iterator=stream[Symbol.asyncIterator](),buffered=[],ended=!1;try{for(;buffered.length<maxBuffered;){let next=await iterator.next();if(next.done){ended=!0;break}if(buffered.push(next.value),hasContent(next.value))break}}catch(error){throw markInBandBeforeContent(error)}return{async*[Symbol.asyncIterator](){try{if(yield*buffered,ended)return;for(;;){let next=await iterator.next();if(next.done)return;yield next.value}}finally{ended||await iterator.return?.()}}}}function isForcedToolChoiceUnsupportedError(error,sentForcedToolChoice){if(!sentForcedToolChoice||!isRequestRefusal(error))return!1;let message=errorMessage(error);return/tool[_\s-]?choices?\b.*?(not\s+(?:currently\s+)?compatible|incompatible|not\s+(?:currently\s+)?supported|unsupported)/is.test(message)||/forces?\s+tool\s+use.*?(not\s+(?:currently\s+)?compatible|incompatible|not\s+(?:currently\s+)?supported|unsupported)/is.test(message)||/does\s+not\s+support\s+forced\s+tool[_\s-]?choices?/is.test(message)||/\bonly\s+[`"]*auto(?:matic)?[`"]*\s.{0,40}?tool[_\s-]?choice/is.test(message)||/thinking\s+may\s+not\s+be\s+enabled\s+when\s+tool[_\s-]?choice\s+forces\s+tool\s+use/is.test(message)||/tool[_\s-]?choice\s+cannot\s+force\s+tool\s+use/is.test(message)}function forcedToolName(toolChoice){if(!isRecord(toolChoice))return;let named=isRecord(toolChoice.function)?toolChoice.function.name:toolChoice.name;return typeof named=="string"&&named.length>0?named:void 0}function toolNames(tools){return Array.isArray(tools)?tools.map(tool=>{if(!isRecord(tool))return;let named=isRecord(tool.function)?tool.function.name:tool.name;return typeof named=="string"?named:void 0}):[]}function escapeRegExp(text){return text.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function refusalNamesForcedTool(error,params){if(!isRequestRefusal(error))return!1;let name=forcedToolName(params.tool_choice);if(name===void 0)return!1;let message=errorMessage(error),index=toolNames(params.tools).indexOf(name);return index>=0&&new RegExp(`\\btools(?:\\.${index}|\\[${index}\\])(?!\\d)`).test(message)?!0:new RegExp(`['"\`]${escapeRegExp(name)}['"\`]`).test(message)}function omitToolChoiceParam(params){let nextParams={...params};return delete nextParams.tool_choice,nextParams}function refusalKey(target){return JSON.stringify([target.api,target.provider,target.baseUrl,target.id])}function hasRefusedForcedToolChoice(target){return forcedToolChoiceRefusals.has(refusalKey(target))}async function sendWithForcedToolChoiceFallback(request){let forced=request.isForced(request.params.tool_choice);if(forced&&(!request.acceptsForcedToolChoice||hasRefusedForcedToolChoice(request.target))){let params=omitToolChoiceParam(request.params);return{params,result:await request.send(params)}}try{return{params:request.params,result:await request.send(request.params)}}catch(error){if(!isForcedToolChoiceUnsupportedError(error,forced)&&!(forced&&refusalNamesForcedTool(error,request.params)))throw error;let params=omitToolChoiceParam(request.params),result=await request.send(params);return/thinking/i.test(errorMessage(error))||forcedToolChoiceRefusals.add(refusalKey(request.target)),{params,result}}}export{primeStreamUntilContent,hasRefusedForcedToolChoice,sendWithForcedToolChoiceFallback};
@@ -0,0 +1,2 @@
1
+ import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
+ import{engineBuildIdentity}from"./chunk-ZJHRDQCH.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV}from"./chunk-CIRZTP7W.js";import{parseArgs,resolveSessionRuntime}from"./chunk-MH2BFYGN.js";import*as crypto from"node:crypto";var CUSTOM_UNSUPPORTED_CAPABILITY="custom_unsupported",EXTENSION_EVENTS_CAPABILITY="extension_events",AUTO_TITLE_SESSIONS_CAPABILITY="auto_title_sessions",CONTINUE_FROM_LEAF_CAPABILITY="continue_from_leaf",MEDIA_PLACEHOLDERS_CAPABILITY="media_placeholders",QUESTION_CAPABILITY="question",RETAIN_ON_DISCONNECT_CAPABILITY="retain_on_disconnect",SESSION_CONTEXT_CAPABILITY="session_context",SESSION_KIND_CAPABILITY="session_kind",AUTO_TITLE_PER_SESSION_CAPABILITY="auto_title_per_session",WARM_CAPABILITY="warm",DURABLE_SESSION_ID_CAPABILITY="durable_session_id",PROMPT_SURFACE_CAPABILITY="prompt_surface",BROWSER_ENGINE_CAPABILITY="browser_engine",RETRY_FALLBACK_PROFILE_CAPABILITY="retry_fallback_profile",RETRY_FALLBACK_COMMAND_CAPABILITY="retry_fallback_command",PROMPT_SURFACE_CHAT_CAPABILITY="prompt_surface_chat",RPC_CLIENT_CAPABILITIES_ENV="SENPI_RPC_CLIENT_CAPABILITIES";function parseClientCapabilities(value){return value?value.split(",").map(part=>part.trim()).filter(part=>part.length>0):[]}var DEFAULT_CUSTOM_EXTENSION_LABEL="custom UI component";function buildCustomUnsupportedRequest(capabilities,extensionName){if(!capabilities?.includes(CUSTOM_UNSUPPORTED_CAPABILITY))return;let name=extensionName.trim()||DEFAULT_CUSTOM_EXTENSION_LABEL;return{type:"extension_ui_request",id:crypto.randomUUID(),method:"custom_unsupported",extensionName:name}}import{createHash,randomUUID as randomUUID2}from"node:crypto";import{resolve}from"node:path";var INSTANCE_ID=resolveInstanceId(process.env[HOST_INSTANCE_ID_ENV]);function resolveInstanceId(value){return value!==void 0&&value.trim()!==""?value:randomUUID2()}function hostInstanceId(){return INSTANCE_ID}var cachedProfile;function hostGeneration(env){let value=env[HOST_GENERATION_ENV];return value!==void 0&&/^\d+$/.test(value)?Number(value):0}function hostLaunchProfile(argv,cwd){let parsed=parseArgs([...argv],{grokNeoEnabled:!1}),core={extensions:[...new Set((parsed.extensions??[]).map(path=>resolve(cwd,path)))].sort(),multi_session:parsed.multiSession===!0,session_runtime:resolveSessionRuntime(parsed)},canonical=JSON.stringify({extensions:core.extensions,multi_session:core.multi_session,session_runtime:core.session_runtime});return{profile_id:createHash("sha256").update(canonical).digest("hex"),core}}function socketHostLaunchProfile(hostArgs,cwd){return hostLaunchProfile(["--mode","rpc","--multi-session","--listen","unix://",...hostArgs],cwd)}function protocolIdentity(){cachedProfile??=hostLaunchProfile(process.argv.slice(2),process.cwd());let build=engineBuildIdentity();return{instanceId:INSTANCE_ID,generation:hostGeneration(process.env),engineVersion:build.text,engineOrdinal:build.ordinal,launch_profile:cachedProfile}}export{CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,AUTO_TITLE_SESSIONS_CAPABILITY,CONTINUE_FROM_LEAF_CAPABILITY,MEDIA_PLACEHOLDERS_CAPABILITY,QUESTION_CAPABILITY,RETAIN_ON_DISCONNECT_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,AUTO_TITLE_PER_SESSION_CAPABILITY,WARM_CAPABILITY,DURABLE_SESSION_ID_CAPABILITY,PROMPT_SURFACE_CAPABILITY,BROWSER_ENGINE_CAPABILITY,RETRY_FALLBACK_PROFILE_CAPABILITY,RETRY_FALLBACK_COMMAND_CAPABILITY,PROMPT_SURFACE_CHAT_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,parseClientCapabilities,DEFAULT_CUSTOM_EXTENSION_LABEL,buildCustomUnsupportedRequest,hostInstanceId,hostGeneration,hostLaunchProfile,socketHostLaunchProfile,protocolIdentity};