grix-connector 3.26.7 → 3.26.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/claude/skill-scanner.js +2 -2
- package/dist/adapter/deepseek-harness/audit-boundary.js +2 -0
- package/dist/adapter/deepseek-harness/bridge-installer.js +5 -0
- package/dist/adapter/deepseek-harness/bridge-session-reliability.js +1 -0
- package/dist/adapter/deepseek-harness/dsh-provider-config.js +8 -0
- package/dist/adapter/deepseek-harness/dsml-text-filter.js +1 -0
- package/dist/adapter/deepseek-harness/event-mapper.js +1 -0
- package/dist/adapter/deepseek-harness/grix-jsonrpc.cordis.yml +61 -0
- package/dist/adapter/deepseek-harness/index.js +1 -0
- package/dist/adapter/deepseek-harness/jsonrpc-adapter.js +3 -0
- package/dist/adapter/deepseek-harness/jsonrpc-client.js +4 -0
- package/dist/adapter/deepseek-harness/plugin-manager.js +2 -0
- package/dist/adapter/deepseek-harness/probe.js +1 -0
- package/dist/adapter/deepseek-harness/process-runtime.js +1 -0
- package/dist/adapter/deepseek-harness/profile-bridge-protocol.js +1 -0
- package/dist/adapter/deepseek-harness/profile-catalog.js +1 -0
- package/dist/adapter/deepseek-harness/profile-resolver.js +1 -0
- package/dist/adapter/deepseek-harness/profile-runtime.js +3 -0
- package/dist/adapter/deepseek-harness/profile-supervisor.js +2 -0
- package/dist/adapter/deepseek-harness/prompt-builder.js +5 -0
- package/dist/adapter/deepseek-harness/runtime.js +0 -0
- package/dist/adapter/deepseek-harness/system-prompt.js +2 -0
- package/dist/adapter/deepseek-harness/toolbar-actions.js +1 -0
- package/dist/adapter/deepseek-harness/toolbar-state.js +1 -0
- package/dist/adapter/deepseek-harness/turn-correlator.js +1 -0
- package/dist/adapter/deepseek-harness/types.js +0 -0
- package/dist/adapter/deepseek-harness/usage.js +1 -0
- package/dist/assets/dsh-bridge/grix-dsh-bridge-3.26.12.tgz +0 -0
- package/dist/assets/dsh-bridge/manifest.json +9 -0
- package/dist/audit/adapters/deepseek-harness/deepseek-harness-audit-adapter.js +2 -0
- package/dist/audit/core/audit-state.js +1 -1
- package/dist/audit/worker/audit-recorder-worker-entry.js +1 -1
- package/dist/bridge/bridge.js +9 -9
- package/dist/bridge/deferred-events.js +1 -1
- package/dist/bridge/native-provider-sweep.js +1 -1
- package/dist/bridge/send-controller.js +1 -1
- package/dist/bridge/tool-card-utils.js +1 -1
- package/dist/core/aibot/binding-card-meta-cache.js +1 -1
- package/dist/core/config/provider-env.js +1 -1
- package/dist/core/installer/installer.js +9 -9
- package/dist/core/installer/manual-guide.js +2 -2
- package/dist/core/installer/registry.js +1 -1
- package/dist/core/persistence/session-binding-store.js +2 -2
- package/dist/core/skill-sync/enable-roots.js +1 -1
- package/dist/default-skills/index.js +1 -1
- package/dist/manager.js +2 -2
- package/dist/mcp/stream-http/security.js +1 -1
- package/package.json +5 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readdirSync as
|
|
2
|
-
`)){const u=
|
|
1
|
+
import{readdirSync as j,readFileSync as g,existsSync as m,statSync as D}from"node:fs";import{dirname as x,join as t,resolve as O}from"node:path";import{homedir as _}from"node:os";import{log as E}from"../../core/log/index.js";const y=".grix-managed";function S(i){const e=i.trim();if(!e.startsWith("---"))return{name:"",description:""};const r=e.indexOf("---",3);if(r===-1)return{name:"",description:""};const s=e.slice(3,r).trim();let c="",o="",a;for(const p of s.split(`
|
|
2
|
+
`)){const u=p.indexOf(":");if(u===-1)continue;const f=p.slice(0,u).trim();let l=p.slice(u+1).trim();(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),f==="name"?c=l:f==="description"?o=l:f==="trigger"&&(a=l)}return{name:c,description:o,trigger:a}}function v(i,e,r){if(!m(i))return[];const s=[];try{for(const c of j(i,{withFileTypes:!0})){const o=t(i,c.name);if(!w(c,o)||c.name.startsWith("."))continue;const a=t(o,"SKILL.md");if(m(a))try{const p=g(a,"utf-8"),u=S(p);u.name&&s.push({name:u.name,description:u.description,trigger:u.trigger,source:e,pluginName:r,filePath:a,managed:m(t(o,y))})}catch{}}}catch{}return s}function n(i,e,r){if(!m(i))return[];const s=r?.maxDepth??6,c=r?.includeHiddenDirs??!1,o=[],a=(p,u)=>{if(u>s)return;let f;try{f=j(p,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(const l of f){const d=t(p,l.name);if(!w(l,d)||!c&&l.name.startsWith("."))continue;const h=t(d,"SKILL.md");if(m(h))try{const M=g(h,"utf-8"),k=S(M);k.name&&o.push({name:k.name,description:k.description,trigger:k.trigger,source:e,pluginName:r?.pluginName,filePath:h,managed:m(t(d,y))})}catch{}a(d,u+1)}};return a(i,0),o}function b(i){return i.map(e=>({...e,managed:!0}))}function w(i,e){if(i.isDirectory())return!0;if(!i.isSymbolicLink())return!1;try{return D(e).isDirectory()}catch{return!1}}function H(i){const e=[],r=new Set;for(const s of i){const c=s.name.trim().toLowerCase();r.has(c)||(r.add(c),e.push(s))}return e}function L(i){const e=i.filePath?.trim();if(!e)return 0;try{const r=D(e).mtimeMs,s=D(x(e)).mtimeMs;return Math.max(r,s)}catch{return 0}}function A(i){return i.map((e,r)=>({entry:e,index:r,timeMs:L(e)})).sort((e,r)=>e.timeMs!==r.timeMs?r.timeMs-e.timeMs:e.index-r.index).map(e=>e.entry)}function I(i){const e=[],r=new Set;let s=O(i);for(;;){r.has(s)||(e.push(s),r.add(s));const c=x(s);if(c===s)break;s=c}return e}function C(i){const e=t(i,".claude","plugins","installed_plugins.json");if(!m(e))return[];const r=[];try{const s=g(e,"utf-8"),o=JSON.parse(s)?.plugins;if(!o||typeof o!="object")return r;for(const[a,p]of Object.entries(o))if(Array.isArray(p))for(const u of p){const f=u?.installPath;if(!f||!m(f))continue;const l=t(f,"skills"),d=a.split("@")[0],h=b(v(l,"plugin",d));r.push(...h)}}catch{}return r}function W(i,e){const r=(i??"").trim().toLowerCase(),s=(e??"").trim().toLowerCase();return r==="claude"?"claude":r==="codex"?"codex":r==="pi"?"pi":r==="cursor"?"cursor":r==="codewhale"?"codewhale":r==="opencode"?"opencode":r==="agy"?"gemini":r==="openhuman"?"none":r==="deepseek-harness"?"deepseek":s==="kiro"?"kiro":s==="qwen"?"qwen":s==="reasonix"?"reasonix":s==="kimi"?"kimi":s==="hermes"||s==="copilot"?"none":"gemini"}function K(i){const e=[],r=i.homeDir??_();switch(i.mode){case"claude":{const c=t(r,".claude","skills");e.push(...n(c,"global")),i.projectDir&&e.push(...n(t(i.projectDir,".claude","skills"),"project")),e.push(...C(r));break}case"codex":{const c=process.env.CODEX_HOME?.trim()||t(r,".codex"),o=i.includeSharedAgentSkills??/^(1|true|yes|on)$/i.test(process.env.GRIX_CODEX_INCLUDE_SHARED_AGENT_SKILLS??"");if(i.projectDir)for(const a of I(i.projectDir))e.push(...n(t(a,".agents","skills"),"project")),e.push(...n(t(a,".codex","skills"),"project"));o&&e.push(...n(t(r,".agents","skills"),"codex")),e.push(...n(t(c,"skills"),"codex")),e.push(...b(n(t(c,"skills",".system"),"codex")));break}case"gemini":{e.push(...n(t(r,".gemini","skills"),"gemini")),e.push(...n(t(r,".agents","skills"),"gemini")),i.projectDir&&(e.push(...n(t(i.projectDir,".gemini","skills"),"project")),e.push(...n(t(i.projectDir,".agents","skills"),"project")));break}case"pi":{e.push(...n(t(r,".pi","agent","skills"),"pi")),i.projectDir&&e.push(...n(t(i.projectDir,".pi","skills"),"project"));break}case"kiro":{e.push(...n(t(r,".kiro","skills"),"kiro")),i.projectDir&&e.push(...n(t(i.projectDir,".kiro","skills"),"project"));break}case"qwen":{e.push(...n(t(r,".qwen","skills"),"global")),i.projectDir&&e.push(...n(t(i.projectDir,".qwen","skills"),"project"));break}case"cursor":{e.push(...n(t(r,".cursor","skills"),"global")),i.projectDir&&e.push(...n(t(i.projectDir,".cursor","skills"),"project"));break}case"codewhale":{e.push(...n(t(r,".codewhale","skills"),"global")),i.projectDir&&e.push(...n(t(i.projectDir,".codewhale","skills"),"project"));break}case"opencode":{const c=process.env.XDG_CONFIG_HOME?.trim()||t(r,".config");e.push(...n(t(c,"opencode","skills"),"global"));break}case"reasonix":{e.push(...n(t(r,".reasonix","skills"),"global"));break}case"kimi":{const c=process.env.KIMI_CODE_HOME?.trim()||t(r,".kimi-code");e.push(...n(t(c,"skills"),"global"));break}case"deepseek":{const o=(i.env??process.env).DSH_HOME?.trim()||t(r,".dsh");e.push(...n(t(o,"skills"),"global")),e.push(...n(t(r,".agents","skills"),"global")),i.projectDir&&(e.push(...n(t(i.projectDir,".dsh","skills"),"project")),e.push(...n(t(i.projectDir,".agents","skills"),"project")));break}case"none":break}const s=H(A(e));return E.info("skill-scanner",`Scanned skills: mode=${i.mode} count=${s.length}`),s}export{y as MANAGED_MARKER,H as dedupeSkills,b as markManaged,S as parseSkillFrontmatter,W as resolveSkillScanMode,n as scanSkillTree,K as scanSkills,A as sortSkillsByRecentTime};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createHash as p}from"node:crypto";import{chmodSync as y,closeSync as u,mkdirSync as g,openSync as S,statSync as q,writeSync as O}from"node:fs";import{dirname as I}from"node:path";function i(s){return!!s&&typeof s=="object"&&!Array.isArray(s)}function f(s){return{redacted:!0,length:s.length,sha256:p("sha256").update(s).digest("hex")}}function P(s,e){if(s==="request/header"){const t=i(e.header)?{...e.header}:void 0;if(!t)return e;let r=!1;typeof t.system=="string"&&(t.system=f(t.system),r=!0);const n=i(t.config)?{...t.config}:void 0;return n&&typeof n.system=="string"&&(t.config={...n,system:f(n.system)},r=!0),r?{...e,header:t}:e}return s==="session/title-llm-request"&&typeof e.system=="string"?{...e,system:f(e.system)}:e}function w(s){if(!i(s))return s;const e=i(s.params)?s.params:void 0;if(!e)return s;if(s.method==="bridge/initialize"){const t=i(e.auth)?e.auth:void 0;return t?{...s,params:{...e,auth:{...t,proof:"[REDACTED]"}}}:s}if(s.method==="session/create"){const t={...e};typeof t.systemPrompt=="string"&&(t.systemPrompt=f(t.systemPrompt));const r=i(t.managedProvider)?{...t.managedProvider}:void 0;return r&&typeof r.apiKey=="string"&&(r.apiKey=f(r.apiKey),t.managedProvider=r),{...s,params:t}}if(s.method==="session.event"){const t=i(e.event)?e.event:e,r=String(t.type??t.eventType??""),n=i(t.data)?t.data:void 0;if(!n)return s;const o=P(r,n);return o===n?s:i(e.event)?{...s,params:{...e,event:{...t,data:o}}}:{...s,params:{...e,data:o}}}return s}class x{path;fd;seqOffsets=[];children=new Set;constructor(e){this.path=e,g(I(e),{recursive:!0,mode:448}),this.fd=S(e,"a",384);try{y(e,384)}catch{}}get offset(){return q(this.path).size}append(e,t){const r=w(t),n={at:Date.now(),direction:e,frame:r},o=`${JSON.stringify(n)}
|
|
2
|
+
`;O(this.fd,o,void 0,"utf8");const d=this.offset,a=r,c=a?.params,h=c?.event,m=Number(a?.seq??c?.seq??h?.seq);return Number.isSafeInteger(m)&&this.seqOffsets.push({endOffset:d,seq:m}),d}addChild(e){e&&this.children.add(e)}boundary(e){const t=this.offset,r=this.seqOffsets.filter(n=>n.endOffset>e.startOffset&&n.endOffset<=t).map(n=>n.seq);return{adapterType:"deepseek-harness",runtimeSessionId:e.runtimeSessionId,rootSessionId:e.rootSessionId,wirePath:this.path,wireStartOffset:e.startOffset,wireEndOffset:t,...e.turn!==void 0?{turn:e.turn}:{},...e.messageId?{messageId:e.messageId}:{},...r.length>0?{firstSeq:r[0],lastSeq:r.at(-1)}:{},childSessionIds:[...this.children],rawProviderBodyCaptureGap:!0}}close(){try{u(this.fd)}catch{}}}export{x as DshWireCapture,w as redactFrameForCapture};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{execFile as E}from"node:child_process";import{createHash as R,randomUUID as O}from"node:crypto";import{closeSync as A,copyFileSync as m,cpSync as S,existsSync as a,mkdirSync as b,openSync as N,readFileSync as f,rmSync as u,statSync as y,writeFileSync as B}from"node:fs";import{join as o,resolve as D}from"node:path";import{fileURLToPath as I}from"node:url";import{promisify as C}from"node:util";import{resolveCliPath as _}from"../../core/util/cli-probe.js";import{COMPATIBLE_DSH_VERSIONS as P,isCompatibleDshVersion as w}from"./bridge-session-reliability.js";import{bridgeDiscoveryDirectory as G,discoverDshBridgeEndpoints as J,resolveDshProfileIdentity as M}from"./profile-resolver.js";const F=C(E),L=2*1024*1024,p="@grix/dsh-bridge";class ee{options;command;identity;constructor(e={}){this.options=e,this.command=e.command?.trim()||"dsh",this.identity=M({dshHome:e.dshHome,profileName:e.profileName})}async status(){const e=await _(this.command),r=this.bridgeAsset(),i=this.readInstalledBridgeVersion(),s=r.version,n=J(this.identity),l=n.length===1?n[0].bridgeVersion:null,c=n.length===1?n[0].dshVersion:null,g=e?await j(e,this.options.dshHome):null;let d;return e?!w(g)||c!==null&&!w(c)?d="bridge_incompatible":a(this.identity.profileRoot)?i?i!==s||this.installedBridgeContentStale(r)?d="bridge_update_required":n.length===0?d="profile_restart_required":n.length!==1?d="bridge_incompatible":l!==i||this.runningBridgePredatesInstalledContent(n[0])?d="profile_restart_required":d="ready":d="bridge_missing":d="profile_missing":d="dsh_missing",{readiness:d,command:this.command,commandPath:e,dshVersion:g,runningDshVersion:c,identity:this.identity,installedBridgeVersion:i,bundledBridgeVersion:s,runningBridgeVersion:l,endpointCount:n.length,compatibleDshVersions:P}}async install(){const e=await _(this.command);if(!e)throw Object.assign(new Error(`${this.command} not found`),{code:"dsh_missing"});const r=await j(e,this.options.dshHome);if(!w(r))throw Object.assign(new Error(`DSH ${r??"unknown"} is outside the verified Bridge compatibility matrix (${P.join(", ")})`),{code:"bridge_incompatible"});const i=this.bridgeAsset();return x(this.identity,async()=>{await h(e,["--profile",this.identity.profileName,"--dump-config"],this.options.dshHome);const s=this.readInstalledBridgeVersion();if(s===i.version&&!this.installedBridgeContentStale(i))return this.status();const n=o(this.identity.dshHome,"assets","grix-dsh-bridge");b(n,{recursive:!0,mode:448});const l=this.captureInstallBackup(n,s),c=o(n,`grix-dsh-bridge-${i.version}.tgz`);m(i.tarball,c);try{if(s===i.version&&a(this.bridgePackageRoot())&&(await h(e,["plugin","--profile",this.identity.profileName,"remove",p],this.options.dshHome),a(this.bridgePackageRoot())))throw Object.assign(new Error(`dsh plugin remove left ${p} in place; refusing to attest an unverified reinstall`),{code:"bridge_install_failed"});await h(e,["plugin","--profile",this.identity.profileName,"add",c],this.options.dshHome),await h(e,["--profile",this.identity.profileName,"--dump-config"],this.options.dshHome);const g=this.readInstalledBridgeVersion();if(g!==i.version)throw Object.assign(new Error(`Bridge package did not land on disk (installed ${g??"none"}, expected ${i.version})`),{code:"bridge_install_failed"});this.writeInstalledBridgeIntegrity(i.integrity)}catch(g){await this.rollbackInstall(e,n,l,s);try{u(c,{force:!0})}catch{}throw Object.assign(new Error(`Bridge install failed: ${k(g)}`),{code:"bridge_install_failed"})}return this.discardInstallBackup(l),this.status()})}async uninstall(){const e=await _(this.command);if(!e)throw Object.assign(new Error(`${this.command} not found`),{code:"dsh_missing"});return x(this.identity,async()=>(this.readInstalledBridgeVersion()&&await h(e,["plugin","--profile",this.identity.profileName,"remove",p],this.options.dshHome),this.status()))}bridgePackageRoot(){return o(this.identity.profileRoot,"node_modules","@grix","dsh-bridge")}profilePackageJsonPath(){return o(this.identity.profileRoot,"package.json")}captureInstallBackup(e,r){const i=o(e,"rollback",`${Date.now()}-${O()}`);b(i,{recursive:!0,mode:448});const s=this.bridgePackageRoot(),n=a(s);n&&S(s,o(i,"dsh-bridge"),{recursive:!0});const l=this.profilePackageJsonPath(),c=a(l);c&&m(l,o(i,"package.json"));const g=["pnpm-lock.yaml","package-lock.json","yarn.lock"];for(const d of g){const v=o(this.identity.profileRoot,d);a(v)&&m(v,o(i,d))}return B(o(i,"manifest.json"),`${JSON.stringify({priorVersion:r,hadBridge:n,hadPackageJson:c})}
|
|
2
|
+
`,{mode:384}),{root:i,priorVersion:r,hadBridge:n,hadPackageJson:c}}async rollbackInstall(e,r,i,s){const n=s?o(r,`grix-dsh-bridge-${s}.tgz`):null;if(n&&a(n)&&await h(e,["plugin","--profile",this.identity.profileName,"add",n],this.options.dshHome).then(()=>!0).catch(()=>!1)){this.discardInstallBackup(i);return}if(i.hadBridge&&a(o(i.root,"dsh-bridge"))){this.restoreFilesystemBackup(i),this.discardInstallBackup(i);return}s?i.hadPackageJson&&this.restoreFilesystemBackup(i):(await h(e,["plugin","--profile",this.identity.profileName,"remove",p],this.options.dshHome).catch(()=>{}),this.cleanHalfInstalledBridge()),this.discardInstallBackup(i)}restoreFilesystemBackup(e){const r=this.bridgePackageRoot(),i=o(e.root,"dsh-bridge");e.hadBridge&&a(i)&&(u(r,{recursive:!0,force:!0}),b(o(this.identity.profileRoot,"node_modules","@grix"),{recursive:!0,mode:448}),S(i,r,{recursive:!0})),e.hadPackageJson&&a(o(e.root,"package.json"))&&m(o(e.root,"package.json"),this.profilePackageJsonPath());for(const s of["pnpm-lock.yaml","package-lock.json","yarn.lock"]){const n=o(e.root,s);a(n)&&m(n,o(this.identity.profileRoot,s))}}cleanHalfInstalledBridge(){try{u(this.bridgePackageRoot(),{recursive:!0,force:!0})}catch{}const e=this.profilePackageJsonPath();if(a(e))try{const r=JSON.parse(f(e,"utf8"));let i=!1;for(const s of["dependencies","devDependencies","optionalDependencies","peerDependencies"]){const n=r[s];n&&typeof n=="object"&&!Array.isArray(n)&&p in n&&(delete n[p],i=!0)}i&&B(e,`${JSON.stringify(r,null,2)}
|
|
3
|
+
`,{mode:384})}catch{}}discardInstallBackup(e){try{u(e.root,{recursive:!0,force:!0})}catch{}}readInstalledBridgeVersion(){const e=o(this.bridgePackageRoot(),"package.json");try{const r=JSON.parse(f(e,"utf8"));return typeof r.version=="string"?r.version:null}catch{return null}}installedIntegrityPath(){return o(this.bridgePackageRoot(),".grix-bridge-integrity")}readInstalledBridgeIntegrity(){try{const e=f(this.installedIntegrityPath(),"utf8").trim();return e.startsWith("sha512-")?e:null}catch{return null}}writeInstalledBridgeIntegrity(e){B(this.installedIntegrityPath(),`${e}
|
|
4
|
+
`,{encoding:"utf8",mode:384})}installedBridgeContentStale(e=this.bridgeAsset()){return a(this.bridgePackageRoot())?this.readInstalledBridgeIntegrity()!==e.integrity:!0}runningBridgePredatesInstalledContent(e){try{const r=y(this.installedIntegrityPath()).mtimeMs,i=Date.parse(e.startedAt);return Number.isFinite(i)?r>i:!0}catch{return!1}}bridgeAsset(){return this.options.tarballPath?H(D(this.options.tarballPath)):$()}}function ie(t){if(t.readiness==="ready")return null;const e=t.identity.profileName,r=`dsh --profile ${e}`,i=t.endpointCount>0&&t.runningBridgeVersion&&t.installedBridgeVersion&&t.runningBridgeVersion!==t.installedBridgeVersion?`Grix Bridge in DSH profile "${e}" is running version ${t.runningBridgeVersion}, but ${t.installedBridgeVersion} is installed on disk. dsh does not hot-load plugin upgrades: stop the running profile process, then start it again with: ${r}`:`Grix Bridge is installed in DSH profile "${e}", but no live Bridge endpoint is available. dsh does not hot-load plugins: stop the running profile process, then start it again with: ${r}`,s={dsh_missing:"dsh is not installed or not on PATH. Install DeepSeek Harness (dsh), then retry.",profile_missing:`DSH profile "${e}" does not exist yet. Create/boot it once with: ${r}`,bridge_missing:`Grix Bridge is not installed in DSH profile "${e}". Install it from the DeepSeek Harness toolbar (or the dsh_install_bridge action), then restart the profile if it is already running.`,bridge_update_required:`Grix Bridge in DSH profile "${e}" needs an update (installed ${t.installedBridgeVersion??"none"}, expected ${t.bundledBridgeVersion}${t.installedBridgeVersion===t.bundledBridgeVersion?", content hash mismatch":""}). Update from the toolbar, then restart the profile \u2014 dsh does not hot-load plugin upgrades.`,profile_restart_required:i,bridge_incompatible:`DSH / Grix Bridge versions are incompatible for profile "${e}" (dsh=${t.dshVersion??"unknown"}, running=${t.runningDshVersion??"none"}, bridge=${t.runningBridgeVersion??t.installedBridgeVersion??"none"}). Supported DSH: ${t.compatibleDshVersions.join(", ")}.`};return Object.assign(new Error(s[t.readiness]),{code:t.readiness})}function te(){return $().tarball}function $(){const t=[I(new URL("../../assets/dsh-bridge/",import.meta.url)),I(new URL("../../../dist/assets/dsh-bridge/",import.meta.url))].find(i=>a(o(i,"manifest.json")));if(!t)throw Object.assign(new Error("Bundled Grix DSH Bridge asset is unavailable; run the Connector build first"),{code:"bridge_asset_missing"});const e=JSON.parse(f(o(t,"manifest.json"),"utf8"));if(typeof e.tarball!="string"||!e.tarball||typeof e.bridgeVersion!="string"||!e.bridgeVersion)throw Object.assign(new Error("Invalid Grix DSH Bridge asset manifest"),{code:"bridge_asset_invalid"});const r=H(o(t,e.tarball),e.bridgeVersion);if(Number(e.size)!==y(r.tarball).size)throw Object.assign(new Error("Grix DSH Bridge asset size mismatch"),{code:"bridge_asset_invalid"});if(typeof e.integrity=="string"&&e.integrity.startsWith("sha512-")&&e.integrity!==r.integrity)throw Object.assign(new Error("Grix DSH Bridge asset integrity mismatch"),{code:"bridge_asset_invalid"});return r}function H(t,e){if(!a(t)||!y(t).isFile())throw Object.assign(new Error(`Grix DSH Bridge asset is missing: ${t}`),{code:"bridge_asset_missing"});if(y(t).size>L)throw Object.assign(new Error("Grix DSH Bridge asset exceeds the 2 MiB safety limit"),{code:"bridge_asset_invalid"});const r=e??/grix-dsh-bridge-([0-9A-Za-z.+-]+)\.tgz$/.exec(t)?.[1];if(!r)throw Object.assign(new Error("Cannot determine Grix DSH Bridge version"),{code:"bridge_asset_invalid"});const i=`sha512-${R("sha512").update(f(t)).digest("base64")}`;return{tarball:t,version:r,integrity:i}}async function x(t,e){const r=G(t);b(r,{recursive:!0,mode:448});const i=o(r,"install.lock");let s=V(i);if(s===null){let n=0;try{n=Number(f(i,"utf8").trim())}catch{}let l=!1;try{l=n===0&&Date.now()-y(i).mtimeMs>5*6e4}catch{}if(l||Number.isSafeInteger(n)&&n>0&&!T(n)){try{u(i,{force:!0})}catch{}s=V(i)}}if(s===null)throw Object.assign(new Error(`Another Grix DSH Bridge install is active for profile ${t.profileName}`),{code:"bridge_install_busy"});try{return B(s,`${process.pid}
|
|
5
|
+
`,"utf8"),await e()}finally{A(s);try{u(i,{force:!0})}catch{}}}function V(t){try{return N(t,"wx",384)}catch(e){if(e.code==="EEXIST")return null;throw Object.assign(new Error(`Cannot acquire Grix DSH Bridge install lock: ${k(e)}`),{code:"bridge_install_failed"})}}function T(t){try{return process.kill(t,0),!0}catch(e){return e.code==="EPERM"}}async function j(t,e){try{return(await h(t,["--version"],e)).trim().split(/\s+/)[0]||null}catch{return null}}async function h(t,e,r){try{return(await F(t,e,{env:{...process.env,...r?{DSH_HOME:D(r)}:{}},timeout:6e4,maxBuffer:8388608})).stdout}catch(i){throw Object.assign(new Error(k(i)),{code:"dsh_command_failed"})}}function k(t){const e=t&&typeof t=="object"?t:{};return String(e.stderr??e.message??t??"unknown error").replace(/(api[_-]?key|authorization|bearer)\s*[:=]\s*\S+/gi,"$1=[REDACTED]").replace(/[\r\n]+/g," ").slice(0,1024)}export{ee as DshBridgeInstaller,te as defaultBridgeTarball,ie as errorForDshBridgeReadiness};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function r(e){const n=Number(e);return Number.isSafeInteger(n)&&n>=0?n:0}function c(e){return r(e)+1}function o(e,n){return Math.max(r(e),r(n))}function i(e,n){return e!==void 0&&r(n)+1<e}async function u(e){e.cancel({kind:"user"},{keepInbox:!1}),await e.whenIdle()}const t=Object.freeze(["0.1.0-rc.5","0.1.0-rc.6"]);function s(e){return e?t.includes(e.trim()):!1}export{t as COMPATIBLE_DSH_VERSIONS,u as cancelUntilIdle,o as effectiveAckCursor,s as isCompatibleDshVersion,i as isReplayWindowExceeded,c as nextCursorAfterAck,r as normalizeCursor};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{mkdir as Y,readFile as F,writeFile as g}from"node:fs/promises";import{join as $}from"node:path";import{log as S}from"../../core/log/index.js";import{DEFAULT_DSH_MODELS as K}from"./toolbar-state.js";const M="grix",y="GRIX_PROVIDER_API_KEY",D="settings.yaml",L=".credentials.yaml",E="dsh-provider",w="llm-pi-ai",O=new Map;function j(t,n){const r=(O.get(t)??Promise.resolve()).then(n,n);return O.set(t,r.catch(()=>{})),r}function l(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}class p extends Error{code="yaml_incomplete";constructor(n){super(n),this.name="IncompleteYamlError"}}async function W(t){try{return l(G(await F(t,"utf8")))}catch(n){if(n.code==="ENOENT")return{};throw n}}function P(t){const n=t.baseUrl?.trim(),r=t.model?.trim();if(!n||!r)return;const o=new Map;o.set(r,{id:r,name:r,contextWindow:1e6});for(const e of K)o.has(e.id)||o.set(e.id,{id:e.id,name:e.displayName,contextWindow:e.contextWindow});return{displayName:"Grix",apiKeyEnv:y,api:"openai-completions",baseURL:n,compat:{thinkingFormat:"deepseek"},models:[...o.values()]}}function A(t){return l(t).apiKeyEnv===y}function k(t,n){const r=l(t);if(r.displayName!==n.displayName||r.apiKeyEnv!==n.apiKeyEnv||r.api!==n.api||r.baseURL!==n.baseURL||l(r.compat).thinkingFormat!==l(n.compat).thinkingFormat)return!1;const o=Array.isArray(n.models)?n.models:[],e=Array.isArray(r.models)?r.models:[];if(o.length!==e.length)return!1;const s=new Map(e.map(i=>[String(i.id??""),i]));return o.every(i=>{const c=s.get(String(i.id??""));return!!c&&c.name===i.name&&Number(c.contextWindow)===Number(i.contextWindow)})}function z(t){const n=P(t),r=t.apiKey?.trim();if(!n||!r)return;const o=Array.isArray(n.models)?n.models:[];return{id:M,displayName:String(n.displayName??"Grix"),baseURL:String(n.baseURL),apiKey:r,models:o}}async function B(t,n,r){const o=P(r),e=r.apiKey?.trim();if(!o||!e||!n.trim())return"skipped";const s=$(t,D),i=$(t,L);return j(s,async()=>{let c,a;try{c=await W(s),a=await W(i)}catch(f){if(f instanceof p)return S.warn(E,`Refusing to rewrite incomplete DSH YAML: ${f.message}`),"skipped";throw f}const d=l(c[w]),h=l(d.providers),u=h[n];return u!==void 0&&!A(u)?"skipped":A(u)&&k(u,o)&&a[y]===e?"unchanged":(h[n]=o,d.providers=h,c[w]=d,a[y]=e,await Y(t,{recursive:!0,mode:448}),await g(s,b(c),{encoding:"utf8",mode:384}),await g(i,b(a),{encoding:"utf8",mode:384}),S.info(E,`Wrote Grix provider providerId=${n} baseURL=${o.baseURL} api=openai-completions apiKeyEnv=${y} path=${s}`),"written")})}async function q(t,n){const r=$(t,D),o=$(t,L);return j(r,async()=>{let e,s;try{e=await W(r),s=await W(o)}catch(a){if(a instanceof p)return S.warn(E,`Refusing to rewrite incomplete DSH YAML: ${a.message}`),!1;throw a}const i=l(e[w]),c=l(i.providers);return A(c[n])?(delete c[n],i.providers=c,e[w]=i,delete s[y],await g(r,b(e),{encoding:"utf8",mode:384}),await g(o,b(s),{encoding:"utf8",mode:384}),!0):!1})}function G(t){const n=t.replace(/^\uFEFF/,"");U(n);const r=T(n,0);return l(r.value)}function U(t){const n=t.split(/\r?\n/);for(let r=0;r<n.length;r++){const o=n[r]??"";if(o.includes(" "))throw new p(`tab indent at line ${r+1}`);const e=o.trim();if(!e||e.startsWith("#"))continue;if(e==="---"||e==="..."||e.startsWith("%"))throw new p(`document marker at line ${r+1}`);if((o.length-o.trimStart().length)%2!==0)throw new p(`odd indent at line ${r+1}`);const i=e.startsWith("- ")?e.slice(2):e;if(i.startsWith("&")||i.startsWith("*")||i.startsWith("!!")||i.startsWith("|")||i.startsWith(">"))throw new p(`unsupported yaml construct at line ${r+1}`);const c=i.indexOf(":");if(!e.startsWith("- ")&&c===-1)throw new p(`non-mapping line ${r+1}`);const a=c===-1?i:i.slice(c+1).trim();if(a&&a!=="[]"&&a!=="{}"&&!(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a.startsWith("{")||a.startsWith("[")||a.startsWith("|")||a.startsWith(">")||a.startsWith("&")||a.startsWith("*")||a.startsWith("!!")))throw new p(`unsupported inline yaml at line ${r+1}`)}}function b(t){const n=m(t,0);return n?`${n}
|
|
2
|
+
`:""}function T(t,n){const r=t.split(/\r?\n/),o=[];for(let s=n;s<r.length;s++){const i=r[s]??"";if(!i.trim()||i.trimStart().startsWith("#"))continue;const c=i.length-i.trimStart().length;o.push({indent:c,content:i.trim()})}if(o.length===0)return{value:{},nextLine:r.length};const e=x(o,0,o[0].indent);if(e.next<o.length)throw new p("unconsumed yaml lines");return{value:e.value,nextLine:r.length}}function x(t,n,r){if(n>=t.length||t[n].indent<r)return{value:{},next:n};if(t[n].content.startsWith("- ")){const s=[];let i=n;for(;i<t.length&&t[i].indent===r&&t[i].content.startsWith("- ");){const c=t[i].content.slice(2),a=c.indexOf(":");if(a===-1){s.push(_(c)),i+=1;continue}const d=c.slice(0,a).trim(),h=c.slice(a+1).trim(),u=r+2;if(h){const N=x(t,i+1,u),R=l(N.value);R[d]=_(h),s.push(R),i=N.next;continue}const f=x(t,i+1,u);s.push({[d]:f.value}),i=f.next}return{value:s,next:i}}const o={};let e=n;for(;e<t.length&&t[e].indent===r&&!t[e].content.startsWith("- ");){const s=t[e].content.indexOf(":");if(s===-1)throw new p(`non-mapping entry: ${t[e].content}`);const i=t[e].content.slice(0,s).trim(),c=t[e].content.slice(s+1).trim();if(c){o[i]=_(c),e+=1;continue}const a=x(t,e+1,r+2);o[i]=a.value,e=a.next}return{value:o,next:e}}function _(t){return t==="~"||t==="null"?null:t==="true"?!0:t==="false"?!1:t==="[]"?[]:t==="{}"?{}:t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\"/g,'"'):/^-?\d+(?:\.\d+)?$/.test(t)?Number(t):t}function m(t,n){if(t==null)return"null";if(typeof t=="boolean"||typeof t=="number")return String(t);if(typeof t=="string")return V(t);if(Array.isArray(t))return t.length===0?"[]":t.map(e=>{if(e&&typeof e=="object"&&!Array.isArray(e)){const s=Object.entries(e);if(s.length===0)return`${" ".repeat(n)}- {}`;const[i,c]=s[0],d=I(c)?`${" ".repeat(n)}- ${i}: ${m(c,0)}`:`${" ".repeat(n)}- ${i}:
|
|
3
|
+
${m(c,n+4)}`,h=s.slice(1).map(([u,f])=>I(f)?`${" ".repeat(n+2)}${u}: ${m(f,0)}`:`${" ".repeat(n+2)}${u}:
|
|
4
|
+
${m(f,n+4)}`);return[d,...h].join(`
|
|
5
|
+
`)}return`${" ".repeat(n)}- ${m(e,0)}`}).join(`
|
|
6
|
+
`);const r=l(t),o=Object.keys(r);return o.length===0?"{}":o.map(e=>{const s=r[e];if(I(s))return`${" ".repeat(n)}${e}: ${m(s,0)}`;const i=m(s,n+2);return`${" ".repeat(n)}${e}:
|
|
7
|
+
${i}`}).join(`
|
|
8
|
+
`)}function I(t){return t==null||typeof t=="string"||typeof t=="number"||typeof t=="boolean"||Array.isArray(t)&&t.length===0?!0:!!t&&typeof t=="object"&&!Array.isArray(t)&&Object.keys(t).length===0}function V(t){return t===""||/[:#{}[\],&*!|>'"%@`]|^\s|\s$|^(?:true|false|null|~)$/i.test(t)||/^-?\d+(?:\.\d+)?$/.test(t)?JSON.stringify(t):t}export{L as DSH_CREDENTIALS_FILE,y as DSH_GRIX_API_KEY_ENV,M as DSH_GRIX_PROVIDER_ID,D as DSH_SETTINGS_FILE,p as IncompleteYamlError,z as buildDshManagedProvider,G as parseYamlMapping,q as removeDshGrixProvider,b as stringifyYamlMapping,B as writeDshGrixProvider};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const p=["<||DSML||tool_calls>","<|DSML|tool_calls>","<||DSML||tools_commands_exec>","<|DSML|tools_commands_exec>","<||DSML||:","<|DSML|:"];function h(e){return e.replaceAll("\uFF5C","|")}function f(e){return e.replaceAll(""",'"').replaceAll("'","'").replaceAll("'","'").replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function x(e){const c=h(e),n=Math.min(c.length,Math.max(...p.map(t=>t.length-1)));for(let t=n;t>0;t-=1){const s=c.slice(-t);if(p.some(l=>l.startsWith(s)))return t}return 0}function M(e){const c=p.map(n=>e.indexOf(n)).filter(n=>n>=0);return c.length>0?Math.min(...c):-1}function _(e,c,n){const t=c.slice(n),s=/^<\|{1,2}DSML\|{1,2}:([\s\S]*?)<\/\|{1,2}DSML\|{1,2}>/.exec(t);if(s){const o=f(s[1].trim());return{end:n+s[0].length,calls:o?[{name:"exec_command",arguments:JSON.stringify({cmd:o})}]:[]}}const l=/^<\|{1,2}DSML\|{1,2}tools_commands_exec>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tools_commands_exec>/.exec(t);if(l){const o=/<\|{1,2}DSML\|{1,2}tools_commands_exec_cmd>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tools_commands_exec_cmd>/.exec(l[1]),r=o?f(o[1].trim()):"";return{end:n+l[0].length,calls:r?[{name:"exec_command",arguments:JSON.stringify({cmd:r})}]:[]}}const a=/^<\|{1,2}DSML\|{1,2}tool_calls>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tool_calls>/.exec(t);if(!a)return null;const m=[],u=/<\|{1,2}DSML\|{1,2}invoke\b([^>]*)>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}invoke>/g;for(const o of a[1].matchAll(u)){const r=/\bname\s*=\s*["']([^"']+)["']/.exec(o[1])?.[1]?.trim();if(!r)continue;const i={},D=/<\|{1,2}DSML\|{1,2}parameter\b([^>]*)>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}parameter>/g;for(const S of o[2].matchAll(D)){const d=/\bname\s*=\s*["']([^"']+)["']/.exec(S[1])?.[1]?.trim();if(!d)continue;const g=f(S[2].trim());if(/\bstring\s*=\s*["']true["']/i.test(S[1])){i[d]=g;continue}try{i[d]=JSON.parse(g)}catch{i[d]=g}}m.push({name:f(r),arguments:JSON.stringify(i)})}return{end:n+a[0].length,calls:m}}function A(e,c={}){const n=c.finalize===!0;if(!e)return{visible:"",suppressedToolCalls:[],holding:!1};const t=[];let s="",l=0;const a=h(e);for(;l<e.length;){const m=M(a.slice(l));if(m<0){const r=e.slice(l),i=x(r);return s+=r.slice(0,r.length-i),{visible:s,suppressedToolCalls:t,holding:!n&&i>0}}const u=l+m;s+=e.slice(l,u);const o=_(e,a,u);if(!o)return n?{visible:s,suppressedToolCalls:t,holding:!1}:{visible:s,suppressedToolCalls:t,holding:!0};t.push(...o.calls),l=o.end}return{visible:s,suppressedToolCalls:t,holding:!1}}function b(e){return`${e.name}\0${e.arguments}`}export{b as dsmlToolCallKey,A as projectVisibleDsmlText};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function a(e){return e.data&&typeof e.data=="object"?e.data:{}}function f(e){const t=a(e),n=t.chunk&&typeof t.chunk=="object"?t.chunk:t,r=String(n.type??t.chunkType??"").toLowerCase();if(e.type==="assistant/chunk:text-delta"||e.type==="assistant/chunk"&&r==="text-delta")return{kind:"text",text:String(n.delta??n.text??"")};if(e.type==="assistant/chunk:reasoning-delta"||e.type==="assistant/chunk"&&r==="reasoning-delta")return{kind:"thinking",text:String(n.delta??n.text??"")};if(e.type==="assistant/chunk:usage"||e.type==="assistant/chunk"&&r==="usage")return{kind:"usage",usage:n.usage??n};if(e.type==="assistant/message"){const o=t.message&&typeof t.message=="object"?t.message:t;return{kind:"text",text:Array.isArray(o.content)?o.content.filter(i=>i&&typeof i=="object"&&String(i.type??"")==="text").map(i=>String(i.text??"")).join(""):String(o.content??o.text??""),usage:o.usage??t.usage,payload:{committed:!0}}}if(e.type==="request/context")return{kind:"context",payload:{provider:String(t.provider??""),model:String(t.model??""),...Number.isFinite(Number(t.contextWindow))?{contextWindow:Number(t.contextWindow)}:{}}};if(e.type==="tool/call")return{kind:"tool_call",callId:String(t.callId??t.id??""),name:String(t.name??t.toolName??"tool"),input:u(t.arguments??t.input),payload:t};if(e.type==="tool/result")return{kind:"tool_result",callId:String(t.callId??t.id??""),output:p(t.result??t.output??t.message),payload:t};if(e.type==="todo/write")return{kind:"todo",payload:t};if(e.type.startsWith("compaction/"))return{kind:"compaction",payload:{eventType:e.type,...t}};if(e.type==="turn/end"){const o=t.reason,s=c(o),i=d(o);return{kind:"turn_end",reason:s,...i?{detail:i}:{},payload:t}}return{kind:"unknown",payload:t}}function c(e){if(typeof e=="string"&&e)return e;if(e&&typeof e=="object"){const t=e.kind;if(typeof t=="string"&&t)return t}return"completed"}function d(e){if(typeof e=="string"||!e||typeof e!="object")return;const t=e,n=t.error;if(typeof n=="string"&&n.trim())return n.trim().slice(0,500);if(n&&typeof n=="object"){const r=n.message;if(typeof r=="string"&&r.trim())return r.trim().slice(0,500)}if(typeof t.message=="string"&&t.message.trim())return t.message.trim().slice(0,500)}function u(e){if(typeof e!="string")return e;try{return JSON.parse(e)}catch{return e}}function p(e){if(!e||typeof e!="object")return e;const t=e;return Array.isArray(t.content)?t.content.filter(r=>r&&typeof r=="object"&&String(r.type??"")==="text").map(r=>String(r.text??"")).join("")||e:t.content??e}function y(e){if(!e||typeof e!="object")return null;const t=e,n=t.event&&typeof t.event=="object"?t.event:t,r=String(n.type??n.eventType??"").trim();return r?{...n,type:r,sessionId:String(n.sessionId??t.sessionId??"").trim()||void 0,data:n.data&&typeof n.data=="object"?n.data:n}:null}export{d as finishReasonDetail,c as finishReasonKind,f as mapDshSessionEvent,y as unwrapDshSessionEvent};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
- id: sdk-jsonrpc-server
|
|
2
|
+
name: '@deepseek-ai/dsh-sdk-jsonrpc-server'
|
|
3
|
+
config:
|
|
4
|
+
maxTokensAsSuccess: true
|
|
5
|
+
- id: llm-deepseek
|
|
6
|
+
name: '@deepseek-ai/dsh-llm-deepseek'
|
|
7
|
+
config:
|
|
8
|
+
thinking: enabled
|
|
9
|
+
reasoningEffort: max
|
|
10
|
+
- id: sandbox
|
|
11
|
+
name: '@deepseek-ai/dsh-sandbox-local'
|
|
12
|
+
- id: sandbox-policy
|
|
13
|
+
name: '@deepseek-ai/dsh-sandbox-policy'
|
|
14
|
+
config:
|
|
15
|
+
mode: !!js process.env.DSH_PERMISSION_MODE ?? 'workspace-write'
|
|
16
|
+
workspaceRoot: !!js process.env.DSH_CWD
|
|
17
|
+
- id: subprocess
|
|
18
|
+
name: '@deepseek-ai/dsh-subprocess-local'
|
|
19
|
+
- id: bash
|
|
20
|
+
name: '@deepseek-ai/dsh-bash-sandbox'
|
|
21
|
+
config:
|
|
22
|
+
timeoutMs: 60000
|
|
23
|
+
- id: approval
|
|
24
|
+
name: '@deepseek-ai/dsh-user-approval'
|
|
25
|
+
config:
|
|
26
|
+
policy: !!js "(process.env.DSH_PERMISSION_MODE ?? 'workspace-write') === 'danger-full-access' ? 'never' : 'ask'"
|
|
27
|
+
- id: agent-spine
|
|
28
|
+
name: '@deepseek-ai/dsh-agent-spine-demo'
|
|
29
|
+
config:
|
|
30
|
+
persona: !!js process.env.DSH_SYSTEM_PROMPT
|
|
31
|
+
workspaceContext:
|
|
32
|
+
maxBytes: 65536
|
|
33
|
+
skills:
|
|
34
|
+
enabled: false
|
|
35
|
+
toolBash:
|
|
36
|
+
enableRunInBackground: false
|
|
37
|
+
toolJobs: false
|
|
38
|
+
- id: sessions
|
|
39
|
+
name: '@deepseek-ai/dsh-session-persistence-jsonl'
|
|
40
|
+
config:
|
|
41
|
+
root: !!js process.env.DSH_SESSION_ROOT
|
|
42
|
+
compression: zstd
|
|
43
|
+
- id: session-checkpoints
|
|
44
|
+
name: '@deepseek-ai/dsh-session-checkpoint-policy'
|
|
45
|
+
- id: fs-sandbox
|
|
46
|
+
name: '@deepseek-ai/dsh-fs-sandbox'
|
|
47
|
+
config:
|
|
48
|
+
cwd: !!js process.env.DSH_CWD
|
|
49
|
+
- id: fs-observation-policy
|
|
50
|
+
name: '@deepseek-ai/dsh-fs-observation-policy'
|
|
51
|
+
- id: tool-fs
|
|
52
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
53
|
+
- id: token-meter
|
|
54
|
+
name: '@deepseek-ai/dsh-token-meter'
|
|
55
|
+
- id: compaction
|
|
56
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
57
|
+
config:
|
|
58
|
+
thresholdRatio: 0.8
|
|
59
|
+
retainRatio: 0.16
|
|
60
|
+
maxTokens: 8192
|
|
61
|
+
compactionRetries: 1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DshJsonRpcAdapter as o}from"./jsonrpc-adapter.js";import{buildDshBindingToolbarMeta as t,DEFAULT_DSH_PRESET_ID as i,DEFAULT_DSH_PRESETS as D}from"./toolbar-state.js";import{buildDshSystemPrompt as d,describeDshSystemPrompt as h}from"./system-prompt.js";import{buildDshUserPrompt as a,extractQuotedMessageMarker as m}from"./prompt-builder.js";import{TurnCorrelator as p}from"./turn-correlator.js";import{DshJsonRpcClient as x}from"./jsonrpc-client.js";import{runDshProtocolProbe as b}from"./probe.js";import{DshBridgeInstaller as _,defaultBridgeTarball as g}from"./bridge-installer.js";import{DEFAULT_DSH_PROFILE_NAME as S,discoverDshBridgeEndpoints as c,listDshProfiles as v,resolveDshConnectorProfileDataDir as T,resolveDshProfileIdentity as I,resolveDshSelectedProfileName as A}from"./profile-resolver.js";import{createDshWebProfile as B}from"./profile-catalog.js";import{DSH_GRIX_PROVIDER_ID as H,buildDshManagedProvider as L,writeDshGrixProvider as U,removeDshGrixProvider as y}from"./dsh-provider-config.js";import{disableDshPlugin as G,enableDshPlugin as J,isDshPluginRestartRequired as N,listDshPlugins as O}from"./plugin-manager.js";export{D as DEFAULT_DSH_PRESETS,i as DEFAULT_DSH_PRESET_ID,S as DEFAULT_DSH_PROFILE_NAME,H as DSH_GRIX_PROVIDER_ID,_ as DshBridgeInstaller,o as DshJsonRpcAdapter,x as DshJsonRpcClient,p as TurnCorrelator,t as buildDshBindingToolbarMeta,L as buildDshManagedProvider,d as buildDshSystemPrompt,a as buildDshUserPrompt,B as createDshWebProfile,g as defaultBridgeTarball,h as describeDshSystemPrompt,G as disableDshPlugin,c as discoverDshBridgeEndpoints,J as enableDshPlugin,m as extractQuotedMessageMarker,N as isDshPluginRestartRequired,O as listDshPlugins,v as listDshProfiles,y as removeDshGrixProvider,T as resolveDshConnectorProfileDataDir,I as resolveDshProfileIdentity,A as resolveDshSelectedProfileName,b as runDshProtocolProbe,U as writeDshGrixProvider};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{createHash as H,randomUUID as M}from"node:crypto";import{EventEmitter as B}from"node:events";import{copyFileSync as X,existsSync as $,mkdirSync as Y}from"node:fs";import{dirname as Z,join as P,resolve as q}from"node:path";import{fileURLToPath as N}from"node:url";import{log as f}from"../../core/log/index.js";import{syncDefaultSkillsToDir as ee}from"../../default-skills/index.js";import{resolveCliPath as te}from"../../core/util/cli-probe.js";import{DshWireCapture as ie}from"./audit-boundary.js";import{dsmlToolCallKey as se,projectVisibleDsmlText as oe}from"./dsml-text-filter.js";import{mapDshSessionEvent as re,unwrapDshSessionEvent as ne}from"./event-mapper.js";import{buildDshUserPrompt as j,extractQuotedMessageMarker as U}from"./prompt-builder.js";import{DshProcessRuntime as ae}from"./process-runtime.js";import{DshProfileRuntime as de}from"./profile-runtime.js";import{createDshWebProfile as le}from"./profile-catalog.js";import{disableDshPlugin as ce,enableDshPlugin as he,isDshPluginRestartRequired as ue,listDshPlugins as L,markDshPluginRestartRequired as pe}from"./plugin-manager.js";import{assertSelectableDshProfileName as ge,discoverDshBridgeEndpoints as fe,listDshProfiles as me,resolveDshConnectorProfileDataDir as ve,resolveDshHome as _e,resolveDshProfileIdentity as F,resolveDshSelectedProfileName as be}from"./profile-resolver.js";import{DshBridgeInstaller as D,errorForDshBridgeReadiness as O}from"./bridge-installer.js";import{awaitDshProfileIdle as Se,ensureDshBridgeReady as Ie,prepareDshProfileBridge as ke,restartManagedProfileIfOwned as we}from"./profile-supervisor.js";import{runDshProtocolProbe as Pe}from"./probe.js";import{buildDshSystemPrompt as ye,describeDshSystemPrompt as Ce}from"./system-prompt.js";import{DshActionCoordinator as De}from"./toolbar-actions.js";import{adoptDshProfileModels as xe,adoptLiveDshProviderSelection as Te,buildDshToolbarMeta as Me,DEFAULT_DSH_MAX_TOKENS as Re,DEFAULT_DSH_MODE as Ee,DEFAULT_DSH_MODELS as Ae,DEFAULT_DSH_PRESETS as He,DEFAULT_DSH_PROVIDER_ID as V,normalizeDshPresets as Be,normalizeDshProviders as $e,permissionModeFor as W,resolveDshAgentPreset as Q,resolveDshProviderId as qe,retainRequestedDshProvider as Ne}from"./toolbar-state.js";import{TurnCorrelator as je}from"./turn-correlator.js";import{getDshSessionUsageStore as Ue,normalizeDshUsage as z}from"./usage.js";import{DSH_GRIX_PROVIDER_ID as v,buildDshManagedProvider as G}from"./dsh-provider-config.js";const m="deepseek-harness-adapter",K=20*6e4;class Le extends B{adapterSessionId;cancelFn;constructor(e,t){super(),this.adapterSessionId=e,this.cancelFn=t}cancel(){return this.cancelFn()}}class St extends B{config;callbacks;type="deepseek-harness";alive=!1;stopped=!1;runtime=null;capture=null;runtimeGeneration=0;runtimeSessionId="";applied;active=null;correlator=null;timeoutTimer=null;activeTimeoutMs=K;intentionalRuntimeStop=!1;personaDirty=!1;profileRevision=0;appliedProfileRevision=-1;rebuildPromise=null;runtimeStartPromise=null;contextWindow=null;reportedContextCapacity=null;providerQuota=null;settingsState="applied";settingsErrorCode=null;injectedMessageIds=new Set;auditBoundaries=new Map;actionCoordinator=new De;activeWireStart=0;activeUsage=J();activeUsageSeq=-1;activeCommittedUsageSeqs=new Set;permissionHandler=null;quotedMessageId;cancelRequested=!1;runtimeReadiness="unknown";bridgeCapabilities=null;bridgeAckCursor=0;pendingFinalBridgeAck=null;finishingTurn=!1;pendingApprovals=new Map;options;models;providers;presets;catalogProviderId;constructor(e,t,i){super(),this.config=e,this.callbacks=t,this.options=i,this.models=i.models?.length?i.models:Ae,this.providers=[],this.presets=[...He]}async start(){this.alive=!0,this.stopped=!1,this.syncGrixProvider();const e=this.options.bindingStore.get(this.options.aibotSessionId);if(e?.cwd&&!this.options.bindingStore.getDshSettings(this.options.aibotSessionId)?.modelId&&this.options.bindingStore.updateDshSettings(this.options.aibotSessionId,{modelId:this.resolveDesiredSettings().modelId}),e&&await this.options.bindingStore.flush(),this.resolveIntegrationMode()==="profile_bridge")try{const t=await this.attachSelectedProfile();await this.healBridgeUpdate(t)}catch(t){this.runtimeReadiness=String(t?.code??"bridge_probe_failed"),this.settingsErrorCode=this.runtimeReadiness}else this.runtimeReadiness="ready";this.pushToolbarMeta(),this.refreshProviderQuota(!1)}async stop(){this.stopped=!0,this.clearPendingApprovals("cancelled"),this.clearTimeout(),this.active&&this.finishActive("canceled","connector shutdown"),this.applied=void 0,this.contextWindow=null,this.reportedContextCapacity=null,this.settingsState="pending",this.settingsErrorCode=null,this.pushToolbarMeta(),await this.rebuildPromise?.catch(()=>{}),await this.stopRuntime(!0),await this.usageStore().flush(),this.alive=!1}isAlive(){return this.alive&&!this.stopped}async createSession(e){return this.options.aibotSessionId}async resumeSession(e,t){}async destroySession(e){e===this.options.aibotSessionId&&(this.usageStore().delete(e),await this.usageStore().flush(),await this.stopRuntime(!0))}sendPrompt(e){const t=new Le(e.adapterSessionId,()=>this.cancel(e.adapterSessionId));return queueMicrotask(()=>t.emit("done",{status:"failed",error:"Use deliverInboundEvent for platform prompts"})),t}async cancel(e){await this.cancelActive("user canceled")}deliverInboundEvent(e){if(!this.isAlive()){this.failEvent(e,"adapter is not alive");return}if(e.attachments_json&&e.attachments_json!=="[]"){this.failEvent(e,"DeepSeek Harness first version supports text only; attachments must be materialized in the bound workspace");return}if(this.active){this.failEvent(e,"concurrent prompt rejected");return}this.runInboundEvent(e)}deliverStopEvent(e,t){this.active&&e===this.active.inbound.event_id&&(t&&t!==this.active.inbound.session_id||this.cancelActive("user canceled"))}async handleLocalAction(e){if(!["set_model","set_mode","set_provider","set_preset","set_profile","create_profile","get_session_usage","get_rate_limits","dsh_bridge_status","dsh_install_bridge","dsh_list_plugins","dsh_enable_plugin","dsh_disable_plugin","dsh_refresh_plugins","dsh_list_skills","dsh_list_mcp","dsh_list_tools","dsh_list_jobs","dsh_list_goals","exec_approve","exec_reject","permission_approve","permission_reject"].includes(e.action_type))return{handled:!1,kind:""};const t=await this.actionCoordinator.run(e.action_id,()=>this.executeLocalAction(e));return this.callbacks.sendLocalActionResult(e.action_id,t.status,t.result,t.errorCode,t.errorMsg),{handled:!0,kind:e.action_type}}setPermissionHandler(e){this.permissionHandler=e}async ping(e){return this.isAlive()&&(!this.runtime||this.runtime.isConnected())}getStatus(){return{alive:this.isAlive()&&!!this.runtime,busy:!!this.active||this.intentionalRuntimeStop||!!this.rebuildPromise||!!this.runtimeStartPromise,backgroundBusy:!1,sessions:this.runtime?1:0,details:{runtimeGeneration:this.runtimeGeneration,runtimeSessionId:this.runtimeSessionId||void 0}}}getActiveEventIds(){return this.active?[this.active.inbound.event_id]:[]}takeAuditBoundary(e){const t=this.auditBoundaries.get(e);return this.auditBoundaries.delete(e),t}clearActiveEventForShutdown(){this.active=null,this.correlator=null,this.clearTimeout()}getMcpConfig(){return null}async hasBackgroundWork(){return this.runtime?.hasBackgroundWork()??!1}onAgentProfileChanged(){this.profileRevision+=1,this.personaDirty=!0,!this.active&&this.runtime&&this.rebuildRuntime("persona_changed")}updateProviderQuotaSnapshot(e){this.providerQuota=e??null,this.pushToolbarMeta()}async probe(e={}){const t=this.resolveIntegrationMode(),i=t==="embedded_jsonrpc"?this.config.command||"dsh-jsonrpc-agent":"dsh",s=await te(i),o=!!s;let l={ok:e.conversation!==!0,latency:null};if(o&&e.conversation===!0&&s)if(t==="embedded_jsonrpc")try{const a=await Pe({command:s,args:this.config.args,cordisPath:q(this.options.cordisPath??N(new URL("./grix-jsonrpc.cordis.yml",import.meta.url))),settings:this.resolveDesiredSettings(),timeoutMs:e.timeoutMs});l={ok:!0,latency:a.latencyMs,serverName:a.serverName,serverVersion:a.serverVersion}}catch(a){l={ok:!1,latency:null,error:this.redactError(a)}}else{const a=Date.now();try{const d=new D({command:"dsh",dshHome:this.options.dshHome??this.config.env?.DSH_HOME,profileName:this.resolveSelectedProfile()}),g=await Ie({installer:d,autoStart:!1}),p=O(g);if(p)throw p;const r=fe(g.identity);if(r.length!==1)throw Object.assign(new Error(r.length===0?`No live Grix Bridge endpoint in DSH profile "${g.identity.profileName}"`:`Multiple live Grix Bridge endpoints for DSH profile "${g.identity.profileName}"`),{code:r.length===0?"bridge_missing":"profile_instance_ambiguous"});l={ok:!0,latency:Date.now()-a,serverName:"grix-dsh-profile-bridge",serverVersion:r[0].bridgeVersion}}catch(d){l={ok:!1,latency:null,error:this.redactError(d)}}}return{cli:{command:i,installed:o,path:s,version:null,...o?{}:{error:{code:"cli_not_found",message:`${i} not found`}}},conversation:{attempted:e.conversation===!0,ok:l.ok,latency_ms:l.latency,...l.ok?{}:{error:{code:"conversation_failed",message:l.error??"initialize/shutdown probe failed"}}},config:{model:this.resolveDesiredSettings().modelId,base_url:this.config.env?.DEEPSEEK_BASE_URL??null,source:{model:"config",base_url:this.config.env?.DEEPSEEK_BASE_URL?"env":"unknown"},extras:{protocol:t==="profile_bridge"?"grix-dsh/1":"jsonrpc-v1",profile:this.resolveSelectedProfile(),serverName:l.serverName,serverVersion:l.serverVersion}},process:{started:!!this.runtime,alive:this.runtime?.isConnected()??!1,busy:!!this.active}}}async runInboundEvent(e){const t={inbound:e,admitted:!1,claimed:!1,turnEnded:!1,rootIdle:!1,text:"",sentText:"",seq:0,startedAt:Date.now()};this.active=t,this.correlator=new je(t),this.activeUsage=J(),this.activeUsageSeq=-1,this.activeCommittedUsageSeqs.clear(),this.quotedMessageId=void 0,this.cancelRequested=!1,this.emit("eventStarted",e.event_id,e.session_id);try{const i=this.ensureRuntimeWithRetry();this.runtimeStartPromise=i;try{await i}finally{this.runtimeStartPromise===i&&(this.runtimeStartPromise=null)}if(this.cancelRequested||this.active!==t)return;this.activeWireStart=this.capture?.offset??0;const s=j(e,this.injectedMessageIds);this.startTimeout(e.timeoutMs);const o=await this.runtime.client.prompt({sessionId:this.runtimeSessionId,contentBlocks:[{type:"text",text:s.text}]});if(!o?.messageId)throw Object.assign(new Error("session/prompt response missing messageId"),{code:"protocol_invalid_prompt_result"});this.correlator.setPromptMessageId(o.messageId)}catch(i){const s=this.redactError(i,e.content);this.finishActive(this.cancelRequested?"canceled":"failed",this.cancelRequested?"user canceled":s)}}async ensureRuntime(){if(this.stopped)throw new Error("adapter stopped");if(this.runtime)return;this.syncGrixProvider();const t=this.options.bindingStore.get(this.options.aibotSessionId)?.cwd;if(!t)throw Object.assign(new Error("Session binding missing. Open a workspace first."),{code:"binding_missing"});this.projectConnectorSkills();let i=this.resolveDesiredSettings();const s=this.options.bindingStore.getDshSettings(this.options.aibotSessionId),o={};s?.modelId||(o.modelId=i.modelId),!s?.providerId&&i.providerId&&(o.providerId=i.providerId),(o.modelId||o.providerId)&&(this.options.bindingStore.updateDshSettings(this.options.aibotSessionId,o),await this.options.bindingStore.flush(),i=this.resolveDesiredSettings());const l=this.callbacks.getAgentProfile(),a=this.profileRevision,d=ye({...l,grixSessionId:this.options.aibotSessionId,agentId:this.callbacks.getAgentId()}),g=Ce(d);this.runtimeGeneration+=1;const p=this.resolveIntegrationMode(),r=this.resolveSelectedProfile();if(p==="profile_bridge")try{const u=await this.attachSelectedProfile(),y=await this.healBridgeUpdate(u),k=O(y);if(k)throw k;this.pushToolbarMeta()}catch(u){throw this.settingsState="failed",this.settingsErrorCode=String(u?.code??"runtime_initialize_failed"),this.runtimeReadiness=this.settingsErrorCode,this.pushToolbarMeta(),u}let n=p==="profile_bridge"?this.options.bindingStore.getDshProfileBinding(this.options.aibotSessionId,r):void 0;p==="profile_bridge"&&!n&&(n={profileName:r,sessionId:Ve(this.options.aibotSessionId),sessionCreated:!1,eventCursor:0},this.options.bindingStore.setDshProfileBinding(this.options.aibotSessionId,n),await this.options.bindingStore.flush()),this.runtimeSessionId=n?.sessionId??Oe(this.options.aibotSessionId,this.runtimeGeneration);const h=this.profileDataDir(r),_=P(h,"audit-source",`${this.runtimeSessionId}.jsonl`);this.capture=new ie(_);const b=p==="embedded_jsonrpc"?new ae({command:this.config.command||"dsh-jsonrpc-agent",args:this.config.args,cwd:t,cordisPath:q(this.options.cordisPath??N(new URL("./grix-jsonrpc.cordis.yml",import.meta.url))),home:h,sessionRoot:P(h,"sessions"),env:this.config.env,systemPrompt:d,settings:i,capture:this.capture,maxLineBytes:this.options.maxLineBytes}):new de({dshHome:this.options.dshHome??this.config.env?.DSH_HOME,profileName:r,cwd:t,ownerId:`${this.callbacks.getAgentId()}:${this.options.aibotSessionId}`,sessionId:this.runtimeSessionId,resumeSession:n?.sessionCreated===!0,lastAckCursor:n?.eventCursor??0,systemPrompt:d,settings:i,managedProvider:i.providerId===v?G(this.options.provider??{}):void 0,capture:this.capture,maxFrameBytes:this.options.maxLineBytes,onApproval:u=>this.handleBridgeApproval(u),onCursorAck:u=>{!n||u<=n.eventCursor||(n={...n,eventCursor:u},this.options.bindingStore.setDshProfileBinding(this.options.aibotSessionId,n))}});this.runtime=b,this.bridgeAckCursor=n?.eventCursor??0,this.pendingFinalBridgeAck=null,this.finishingTurn=!1,this.intentionalRuntimeStop=!1;try{const u=await b.start();if(!b.isConnected())throw Object.assign(new Error("Harness runtime disconnected immediately after initialize"),{code:"runtime_exited"});b.client?.on("notification",(S,I)=>this.onNotification(S,I)),b.client?.on("protocolError",S=>this.onProtocolError(S)),b.onExit(()=>this.onRuntimeExit()),b.client?.activateNotifications?.();let y=!1;if(p==="profile_bridge"){const S=$e(u.providers),I=Te({requestedProviderId:i.providerId,liveProviders:S,liveSelectedProvider:String(u.selectedProvider??"")});this.providers=Ne(S,I.providerId,this.providers),i={...i,providerId:I.providerId},y=I.persistFallback;const x=I.providerId,R=Object.prototype.hasOwnProperty.call(u,"models")?u.models:void 0,E=!!this.catalogProviderId&&!!x&&x!==this.catalogProviderId;this.models=xe({current:this.models,fetched:R,providerChanged:E}),(R!==void 0||E)&&(this.catalogProviderId=x||this.catalogProviderId);const T=String(u.selectedModel??"");T&&T!==i.modelId&&(i={...i,modelId:T});const A=Be(u.presets);A.length>0&&(this.presets=A);const C=String(u.selectedPreset??"");C&&C!==i.agentPreset&&(i={...i,agentPreset:C},this.options.bindingStore.getDshAgentPreset(this.options.aibotSessionId)||this.options.bindingStore.setDshAgentPreset(this.options.aibotSessionId,C))}const k=this.options.bindingStore.getDshSettings(this.options.aibotSessionId),w={};y&&(k?.providerId??"")!==(i.providerId??"")&&(w.providerId=i.providerId),(k?.modelId??"")!==i.modelId&&(w.modelId=i.modelId),(w.providerId||w.modelId)&&(i.revision=this.options.bindingStore.updateDshSettings(this.options.aibotSessionId,w)??i.revision,await this.options.bindingStore.flush(),f.warn(m,`replaced unavailable persisted DSH catalog selection provider=${i.providerId} model=${i.modelId}`)),this.applied={runtimeGeneration:this.runtimeGeneration,appliedRevision:i.revision,providerId:i.providerId??V,modelId:i.modelId,modeId:i.modeId},this.runtimeReadiness="ready",this.bridgeCapabilities=u.capabilities??null,p==="profile_bridge"&&n&&!n.sessionCreated&&(n={...n,sessionCreated:!0},this.options.bindingStore.setDshProfileBinding(this.options.aibotSessionId,n),await this.options.bindingStore.flush()),this.settingsState=this.resolveDesiredSettings().revision===i.revision?"applied":"pending",this.settingsErrorCode=null,this.appliedProfileRevision=a,this.personaDirty=this.appliedProfileRevision!==this.profileRevision,f.info(m,`runtime initialized generation=${this.runtimeGeneration} prompt_schema=${g.schemaVersion} prompt_sha256=${g.sha256} prompt_length=${g.length}`),this.pushToolbarMeta()}catch(u){throw this.settingsState="failed",this.settingsErrorCode=String(u?.code??"runtime_initialize_failed"),this.runtimeReadiness=this.settingsErrorCode,this.applied=void 0,this.pushToolbarMeta(),await this.stopRuntime(!0),u}}async ensureRuntimeWithRetry(){let e;for(let t=1;t<=2;t++)try{await this.ensureRuntime();return}catch(i){e=i;const s=String(i?.code??"");if(this.cancelRequested||s==="binding_missing"||s==="protocol_incompatible"||t===2)throw i;await this.stopRuntime(!0)}throw e}onNotification(e,t){const i=Fe(t);if(e==="session.event"){const s=ne(t);if(!s){this.onProtocolError(new Error("malformed session.event"));return}const o=this.onSessionEvent(s);this.advanceBridgeAck(i,o);return}if(e==="session.status"){const s=t&&typeof t=="object"?t:{};if(String(s.sessionId??"")===this.runtimeSessionId){this.touchActivity(),this.correlator?.markRootStatus(String(s.status??"")),s.status==="idle"&&this.active&&this.correlator&&f.debug(m,`turn correlation idle admitted=${this.active.admitted} claimed=${this.active.claimed} ended=${this.active.turnEnded} complete=${this.correlator.complete}`);const l=!!this.correlator?.complete;l&&this.finishFromTurnOutcome(),this.advanceBridgeAck(i,l)}else i>0&&this.advanceBridgeAck(i,!1);return}if(e==="subagent.started"||e==="subagent.finished"){this.touchActivity(3);const s=t&&typeof t=="object"?t:{},o=String(s.childSessionId??s.sessionId??"");o&&this.capture?.addChild(o),this.active&&this.callbacks.sendRawEventEnvelope(this.active.inbound.event_id,this.active.inbound.session_id,{type:e,payload:s},e==="subagent.started"?"[subagent started]":"[subagent finished]"),this.advanceBridgeAck(i,!1);return}this.onProtocolError(new Error(`unknown required JSON-RPC notification: ${e}`))}onSessionEvent(e){if(!this.active||!this.correlator)return!1;this.touchActivity(e.type==="tool/call"||e.type==="tool/result"?3:1);const t=re(e);if(t.kind==="unknown"&&!ze(e)&&e.ignorable!==!0)return this.onProtocolError(new Error(`unknown required SessionEvent: ${e.type}`)),!1;if(e.sessionId&&e.sessionId!==this.runtimeSessionId)return!1;const i=this.correlator.accept(e);if((e.type==="agent/inbox/spliced"||e.type==="user/message"||e.type==="turn/end")&&f.debug(m,`turn correlation event=${e.type} belongs=${i} admitted=${this.active.admitted} claimed=${this.active.claimed} ended=${this.active.turnEnded}`),e.type==="agent/inbox/spliced"&&this.active.admitted){const s=j(this.active.inbound,this.injectedMessageIds);for(const o of s.contextIds)this.injectedMessageIds.add(o);s.currentMessageId&&this.injectedMessageIds.add(s.currentMessageId)}return i?t.kind==="text"?(t.payload?.committed===!0?(this.applyCommittedText(t.text??""),t.usage&&this.collectCommittedUsage(t.usage,Number(e.seq??e.step??Date.now()))):this.applyTextDelta(t.text??""),!1):t.kind==="thinking"?(this.thinkingEnabled()&&this.callbacks.sendThinking(this.active.inbound.event_id,this.active.inbound.session_id,t.text??""),!1):t.kind==="tool_call"?(this.toolEventsEnabled()&&this.sendRaw("tool_call",{call_id:t.callId,tool_name:t.name,tool_input:t.input},`[tool] ${t.name}`),!1):t.kind==="tool_result"?(this.toolEventsEnabled()&&this.sendRaw("tool_result",{call_id:t.callId,result:t.output},`[tool result] ${t.callId??""}`),!1):t.kind==="todo"?(this.sendRaw("todo_snapshot",t.payload??{},"[todo updated]"),!1):t.kind==="compaction"?!1:t.kind==="context"?(this.updateContextCapacity(t.payload),!1):t.kind==="usage"?(this.updateContextWindow(t.usage),!1):t.kind==="turn_end"&&this.correlator.complete?(this.finishFromTurnOutcome(),!0):!1:!1}applyTextDelta(e){this.active.text+=e,this.flushVisibleText(!1)}applyCommittedText(e){const t=this.active;if(e.startsWith(t.text))t.text=e;else if(!t.text.startsWith(e)){f.warn(m,`committed assistant text diverged event=${t.inbound.event_id}`);const i=U(e).quotedMessageId;i&&(this.quotedMessageId=i),t.text=t.sentText}this.flushVisibleText(!1)}flushVisibleText(e,t={}){const i=this.active;if(!i)return;const s=U(i.text);s.quotedMessageId&&(this.quotedMessageId=s.quotedMessageId);const o=s.text.replace(/\[\[quoted_message_id:[^\]]*$/g,""),l=oe(o,{finalize:t.finalizeDsml===!0||e});this.surfaceSuppressedDsmlToolCalls(l.suppressedToolCalls);const a=l.visible;this.observeVisibleTextAfterToolCall(a);let d="";a.startsWith(i.sentText)?d=a.slice(i.sentText.length):(e||t.finalizeDsml)&&(d=a),!(!d&&!e)&&(i.seq+=1,this.callbacks.sendStreamChunk(i.inbound.event_id,i.inbound.session_id,d,i.seq,e,`${i.inbound.event_id}-dsh`,this.quotedMessageId),i.sentText=a)}surfaceSuppressedDsmlToolCalls(e){if(!this.active||e.length===0)return;const t=this.active.dsmlSuppressedKeys??new Set;this.active.dsmlSuppressedKeys=t;for(const i of e){const s=se(i);if(t.has(s)||(t.add(s),this.markToolCallAwaitingFinalText(),f.warn(m,`suppressed leaked DSML tool markup name=${i.name} event=${this.active.inbound.event_id}`),!this.toolEventsEnabled()))continue;let o=i.arguments;try{o=JSON.parse(i.arguments)}catch{}this.sendRaw("tool_call",{call_id:`dsml-${t.size}`,tool_name:i.name,tool_input:o,source:"dsml_text_leak",executed:!1},`[tool] ${i.name}`)}}markToolCallAwaitingFinalText(){const e=this.active;e&&(e.toolCallAwaitingFinalText=!0,e.toolCallVisibleTextLength=e.sentText.length)}observeVisibleTextAfterToolCall(e){const t=this.active;if(!t?.toolCallAwaitingFinalText)return;const i=t.toolCallVisibleTextLength??t.sentText.length;e.slice(i).trim().length!==0&&(t.toolCallAwaitingFinalText=!1,t.toolCallVisibleTextLength=void 0)}collectCommittedUsage(e,t){if(this.activeCommittedUsageSeqs.has(t))return;this.activeCommittedUsageSeqs.add(t);const i=z(e);this.activeUsage.inputTokens+=i.inputTokens,this.activeUsage.outputTokens+=i.outputTokens,this.activeUsage.cacheReadInputTokens+=i.cacheReadInputTokens,this.activeUsage.cacheCreationInputTokens+=i.cacheCreationInputTokens,this.activeUsage.reasoningTokens+=i.reasoningTokens,this.activeUsageSeq=Math.max(this.activeUsageSeq,t),this.updateContextWindow(i)}updateContextWindow(e){const t=z(e),i=this.resolveDesiredSettings(),s=this.models.find(l=>l.id===i.modelId),o=this.reportedContextCapacity??s?.contextWindow;if(o&&o>0){const l=t.inputTokens+t.cacheReadInputTokens+t.cacheCreationInputTokens;this.contextWindow={usedTokens:l,totalTokens:o,remainingTokens:Math.max(0,o-l),usedPercentage:l/o*100,remainingPercentage:Math.max(0,100-l/o*100)},this.pushToolbarMeta()}}updateContextCapacity(e){const t=Number(e?.contextWindow);if(!Number.isFinite(t)||t<=0)return;this.reportedContextCapacity=t;const i=this.contextWindow&&typeof this.contextWindow=="object"?this.contextWindow:{},s=Math.max(0,Number(i.usedTokens)||0);this.contextWindow={usedTokens:s,totalTokens:t,remainingTokens:Math.max(0,t-s),usedPercentage:s/t*100,remainingPercentage:Math.max(0,100-s/t*100)},this.pushToolbarMeta()}finishFromTurnOutcome(){if(!this.active)return;this.finishingTurn=!0;const e=this.active.outcome??"completed",t=this.active.outcomeDetail?.trim();e==="completed"?this.finishActive("responded"):e==="aborted"?this.finishActive("canceled"):e==="max-tokens"&&this.active.sentText?this.finishActive("responded","Response truncated at model token limit"):this.finishActive("failed",t?t.toLowerCase().includes(e.toLowerCase())?`Harness turn ended: ${t}`:`Harness turn ended: ${e}: ${t}`:`Harness turn ended: ${e}`)}finishActive(e,t){const i=this.active;if(!i)return;let s=e,o=t;this.finishingTurn=!0,this.clearTimeout(),this.flushVisibleText(!1,{finalizeDsml:!0}),s==="responded"&&i.toolCallAwaitingFinalText&&(s="failed",o="DeepSeek Harness ended after a tool call without returning final assistant text",f.warn(m,`${o} event=${i.inbound.event_id}`)),i.text=i.sentText;const l=s==="failed"&&!!o?.trim();l&&(i.text+=`
|
|
2
|
+
|
|
3
|
+
Error: ${o}`,this.flushVisibleText(!1,{finalizeDsml:!0})),s==="responded"&&this.activeUsageSeq>=0&&(this.usageStore().commit(i.inbound.session_id,this.runtimeSessionId,this.activeUsageSeq,this.applied?.modelId??this.resolveDesiredSettings().modelId,this.activeUsage),this.usageStore().flush()),i.inbound.audit?.enabled&&this.capture&&this.auditBoundaries.set(i.inbound.event_id,this.capture.boundary({runtimeSessionId:this.runtimeSessionId,rootSessionId:this.runtimeSessionId,startOffset:this.activeWireStart,turn:i.turn,messageId:i.messageId}));const a=this.personaDirty&&!!this.runtime;a&&this.emit("pauseIntake","barrier"),this.active=null,this.correlator=null;const d=`${i.inbound.event_id}-dsh`,g=(p,r,n=!1)=>{this.callbacks.sendEventResult(i.inbound.event_id,p,r,n),this.emit("eventDone",i.inbound.event_id),a&&this.rebuildRuntime("persona_changed")};this.callbacks.sendFinalStreamChunkReliable(i.inbound.event_id,i.inbound.session_id,d).then(async()=>{await this.flushPendingFinalBridgeAck(!0),g(s,o,l)},async p=>{await this.flushPendingFinalBridgeAck(!1),g(s==="responded"?"failed":s,s==="responded"?`Final output delivery failed: ${this.redactError(p,i.inbound.content)}`:o)})}advanceBridgeAck(e,t){if(!(e<=0)){if(t||this.finishingTurn||this.pendingFinalBridgeAck!==null){this.pendingFinalBridgeAck=Math.max(this.pendingFinalBridgeAck??0,e);return}this.ackBridgeCursor(e)}}async flushPendingFinalBridgeAck(e){const t=this.pendingFinalBridgeAck;this.pendingFinalBridgeAck=null,this.finishingTurn=!1,!(!e||t===null)&&await this.ackBridgeCursor(t)}async ackBridgeCursor(e){if(e<=this.bridgeAckCursor)return;const t=this.runtime?.client?.ack;if(!t){this.bridgeAckCursor=Math.max(this.bridgeAckCursor,e);return}try{await t.call(this.runtime.client,e),this.bridgeAckCursor=Math.max(this.bridgeAckCursor,e)}catch(i){this.onProtocolError(i instanceof Error?i:new Error(String(i)))}}async cancelActive(e){this.active&&(this.cancelRequested=!0,this.clearPendingApprovals("cancelled"),this.resolveIntegrationMode()==="embedded_jsonrpc"?(this.contextWindow=null,this.reportedContextCapacity=null,this.applied=void 0,this.settingsState="pending",this.pushToolbarMeta(),this.runtimeStartPromise&&this.runtime&&await this.runtime.terminate().catch(()=>{}),await this.runtimeStartPromise?.catch(()=>{}),await this.stopRuntime(!0)):(await this.runtimeStartPromise?.catch(()=>{}),await this.runtime?.cancel(this.runtimeSessionId).catch(()=>{}),this.runtime&&!this.runtime.isConnected()&&await this.stopRuntime(!0)),this.finishActive("canceled",e))}async handleBridgeApproval(e){const t=this.permissionHandler,i=String(e.interactionId??e.callId??M());if(t)try{return await t({adapterSessionId:this.options.aibotSessionId,requestId:i,description:String(e.reason??`Allow ${String(e.toolName??"operation")}?`),options:[{id:"allow_once",label:"Allow once",isAllow:!0},{id:"reject",label:"Reject",isAllow:!1}]})==="allow_once"?"allowed-once":"rejected"}catch{return"cancelled"}const s=this.active;return s?(this.callbacks.sendPermissionCard({eventId:s.inbound.event_id,sessionId:s.inbound.session_id,approvalId:i,toolName:String(e.toolName??"operation"),toolTitle:String(e.reason??`Allow ${String(e.toolName??"operation")}?`)}),new Promise(o=>{const l=setTimeout(()=>{this.pendingApprovals.delete(i),o("unavailable")},3e5);l.unref?.(),this.pendingApprovals.set(i,{resolve:o,timer:l})})):"unavailable"}projectConnectorSkills(){const e=_e(this.options.dshHome??this.config.env?.DSH_HOME,{...process.env,...this.config.env}),t=P(e,"skills"),i=ee(t);i.length>0&&f.info(m,`Synced connector skills to ${t}: [${i.join(", ")}]`)}rebuildRuntime(e){if(this.active)return Promise.resolve();if(this.rebuildPromise)return this.rebuildPromise;const t=(async()=>{this.emit("pauseIntake","barrier"),this.contextWindow=null,this.reportedContextCapacity=null,this.applied=void 0,this.settingsState="pending",this.pushToolbarMeta();try{await this.stopRuntime(!0),await this.ensureRuntime()}catch(i){f.warn(m,`${e} rebuild failed: ${this.redactError(i)}`)}finally{this.emit("resumeIntake","barrier")}})();return this.rebuildPromise=t.finally(()=>{this.rebuildPromise=null;const i=this.resolveDesiredSettings().revision;!this.stopped&&!this.active&&(this.personaDirty||this.applied&&this.applied.appliedRevision!==i)&&this.rebuildRuntime("coalesced_state_changed")}),this.rebuildPromise}async stopRuntime(e){const t=this.runtime;t&&(this.intentionalRuntimeStop=e,this.runtime=null,await t.shutdown().catch(()=>t.terminate()),this.capture?.close(),this.capture=null,this.intentionalRuntimeStop=!1)}onRuntimeExit(){this.intentionalRuntimeStop||this.stopped||(this.runtime=null,this.capture?.close(),this.capture=null,this.applied=void 0,this.contextWindow=null,this.reportedContextCapacity=null,this.settingsState="failed",this.settingsErrorCode="runtime_exited",this.pushToolbarMeta(),this.active&&this.finishActive("failed","Harness runtime exited; prompt was not replayed"),this.emit("exit",1))}onProtocolError(e){if(this.stopped||!this.runtime&&!this.active)return;const t=this.redactError(e,this.active?.inbound.content);this.clearPendingApprovals("unavailable"),this.contextWindow=null,this.reportedContextCapacity=null,this.settingsState="failed",this.settingsErrorCode="protocol_error",this.pushToolbarMeta();const i=this.runtime;this.runtime=null,this.intentionalRuntimeStop=!0,i?.client?.close(e),this.active&&this.finishActive("failed",`Harness protocol error: ${t}`),i?.terminate().finally(()=>{this.intentionalRuntimeStop=!1}),this.emit("exit",1)}async executeLocalAction(e){const t=e.params??{},i=String(t.session_id??"");if(!i||i!==this.options.aibotSessionId)return{status:"failed",errorCode:"binding_missing",errorMsg:"Session binding missing"};if(["exec_approve","exec_reject","permission_approve","permission_reject"].includes(e.action_type)){const r=String(t.approval_command_id??t.approval_id??t.request_id??"").trim(),n=this.pendingApprovals.get(r);if(!n)return{status:"failed",errorCode:"unknown_or_expired_approval_id",errorMsg:"That DSH approval request is no longer pending"};clearTimeout(n.timer),this.pendingApprovals.delete(r);const h=e.action_type==="exec_approve"||e.action_type==="permission_approve";return n.resolve(h?"allowed-once":"rejected"),{status:"ok",result:{approval_id:r,decision:h?"allow-once":"deny"}}}if(e.action_type==="get_session_usage")return{status:"ok",result:{adapterType:"deepseek-harness",available:!0,dsh_profile:this.resolveSelectedProfile(),...this.usageStore().get(i)}};if(e.action_type==="get_rate_limits"){this.providerQuota=null,this.pushToolbarMeta();try{this.providerQuota=await this.callbacks.queryProviderQuota(!0)??{provider:"deepseek",providerLabel:"DeepSeek",success:!1,error:"unavailable"}}catch(r){this.providerQuota={provider:"deepseek",providerLabel:"DeepSeek",success:!1,error:this.redactError(r)}}return this.pushToolbarMeta(),{status:"ok",result:{sampledAt:new Date().toISOString(),contextWindow:this.contextWindow,providerQuota:this.providerQuota}}}if(e.action_type==="dsh_bridge_status"||e.action_type==="dsh_install_bridge"){if(this.resolveIntegrationMode()!=="profile_bridge")return{status:"unsupported",errorCode:"capability_unavailable",errorMsg:"Bridge management requires Profile Bridge mode"};if(this.active||this.runtime)return{status:"failed",errorCode:"worker_busy",errorMsg:"Stop the active DSH session before changing its Profile plugin"};try{const r=new D({command:"dsh",dshHome:this.options.dshHome??this.config.env?.DSH_HOME,profileName:this.resolveSelectedProfile()}),n=e.action_type==="dsh_install_bridge"?await r.install():await r.status();return this.runtimeReadiness=n.readiness,this.settingsErrorCode=n.readiness==="ready"?null:n.readiness,this.pushToolbarMeta(),{status:"ok",result:We(n)}}catch(r){const n=String(r?.code??"bridge_install_failed");return this.runtimeReadiness=n,this.settingsErrorCode=n,this.pushToolbarMeta(),{status:"failed",errorCode:n,errorMsg:this.redactError(r)}}}if(e.action_type==="dsh_list_plugins"||e.action_type==="dsh_refresh_plugins"||e.action_type==="dsh_enable_plugin"||e.action_type==="dsh_disable_plugin")return this.executePluginAction(e.action_type,t,i);const o={dsh_list_skills:"skills/list",dsh_list_mcp:"mcp/list",dsh_list_tools:"tools/list",dsh_list_jobs:"jobs/list",dsh_list_goals:"goals/list"}[e.action_type];if(o){if(this.resolveIntegrationMode()!=="profile_bridge")return{status:"unsupported",errorCode:"capability_unavailable",errorMsg:"DSH resources require Profile Bridge mode"};if(this.active)return{status:"failed",errorCode:"worker_busy",errorMsg:"Cannot query DSH resources during an active turn"};try{return await this.ensureRuntimeWithRetry(),{status:"ok",result:await this.runtime?.client?.call(o,{cwd:this.options.bindingStore.get(i)?.cwd})}}catch(r){const n=String(r?.code??"resource_query_failed");return{status:n==="capability_unavailable"?"unsupported":"failed",errorCode:n,errorMsg:this.redactError(r)}}}if(e.action_type==="set_profile"||e.action_type==="create_profile"){if(this.active)return{status:"failed",errorCode:"worker_busy",errorMsg:"Cannot change DeepSeek Harness Profile during an active turn"};if(!this.options.bindingStore.get(i))return{status:"failed",errorCode:"binding_missing",errorMsg:"Session binding missing. Open a workspace first."};let r;try{r=ge(String(t.profile_id??t.dsh_profile??t.profile_name??t.name??""))}catch(h){return{status:"failed",errorCode:"profile_invalid",errorMsg:this.redactError(h)}}if(this.options.bindingStore.isDshProfileLocked(i)){const h=this.resolveSelectedProfile();return e.action_type==="create_profile"||h!==r?{status:"failed",errorCode:"profile_locked",errorMsg:"This conversation Profile is locked after the session is created"}:this.finishProfileSelection(r,!1)}if(e.action_type==="create_profile")try{const h=this.options.createDshProfile?await this.options.createDshProfile(r):await le({profileName:r,dshHome:this.options.dshHome??this.config.env?.DSH_HOME}),_=h.identity?.profileName??r;return this.persistSelectedProfile(_)?(await this.flushSelectedProfile(),this.finishProfileSelection(_,h.created)):{status:"failed",errorCode:"profile_locked",errorMsg:"This conversation Profile is locked after the session is created"}}catch(h){return{status:"failed",errorCode:String(h?.code??"profile_create_failed"),errorMsg:this.redactError(h)}}return this.listProfiles().some(h=>h.id===r)?this.persistSelectedProfile(r)?(await this.flushSelectedProfile(),this.finishProfileSelection(r,!1)):{status:"failed",errorCode:"profile_locked",errorMsg:"This conversation Profile is locked after the session is created"}:{status:"failed",errorCode:"profile_not_found",errorMsg:"Requested DSH profile is not in the local catalog"}}if(e.action_type==="set_preset"){if(this.active)return{status:"failed",errorCode:"worker_busy",errorMsg:"Cannot change DeepSeek Harness settings during an active turn"};if(!this.options.bindingStore.get(i)?.cwd)return{status:"failed",errorCode:"binding_missing",errorMsg:"Session binding missing. Open a workspace first."};const n=String(t.agent_preset_id??t.preset_id??"").trim();if(!this.presets.some(_=>_.id===n))return{status:"failed",errorCode:"preset_not_found",errorMsg:"Requested agent preset is not in the Harness catalog"};const h=Q(this.resolveDesiredSettings().agentPreset,this.presets);return this.options.bindingStore.isDshAgentPresetLocked(i)?h===n?{status:"ok",result:this.presetActionResult(n,!0)}:{status:"failed",errorCode:"agent_preset_locked",errorMsg:"This conversation scene is locked after the session is created"}:h===n?(this.options.bindingStore.setDshAgentPreset(i,n),await this.options.bindingStore.flush(),this.pushToolbarMeta(),{status:"ok",result:this.presetActionResult(n,!1)}):this.options.bindingStore.setDshAgentPreset(i,n)?(await this.options.bindingStore.flush(),this.pushToolbarMeta(),{status:"ok",result:this.presetActionResult(n,!1)}):{status:"failed",errorCode:"agent_preset_locked",errorMsg:"This conversation scene is locked after the session is created"}}if(this.active)return{status:"failed",errorCode:"worker_busy",errorMsg:"Cannot change DeepSeek Harness settings during an active turn"};if(!this.options.bindingStore.get(i)?.cwd)return{status:"failed",errorCode:"binding_missing",errorMsg:"Session binding missing. Open a workspace first."};const a=this.resolveDesiredSettings();let d;if(e.action_type==="set_provider"){const r=String(t.provider_id??"").trim();if(!this.providers.some(n=>n.id===r))return{status:"failed",errorCode:"provider_not_found",errorMsg:"Requested provider is not in the Harness catalog"};d={providerId:r}}else if(e.action_type==="set_model"){const r=String(t.model_id??"").trim();if(!this.models.some(n=>n.id===r))return{status:"failed",errorCode:"model_not_found",errorMsg:"Requested model is not in the Harness catalog"};d={modelId:r}}else{const r=String(t.mode_id??"").trim();if(r!=="approval"&&r!=="full_auto")return{status:"failed",errorCode:"mode_invalid",errorMsg:"mode_id must be approval or full_auto"};d={modeId:r}}if((d.providerId===void 0||d.providerId===a.providerId)&&(d.modelId===void 0||d.modelId===a.modelId)&&(d.modeId===void 0||d.modeId===a.modeId)&&this.applied?.appliedRevision===a.revision)return{status:"ok",result:this.settingsActionResult(e.action_type,d,a.revision,"already_applied",!0)};const p=this.options.bindingStore.updateDshSettings(i,d)??a.revision;if(await this.options.bindingStore.flush(),(d.providerId||d.modelId)&&(this.options.globalConfigStore?.set(this.options.agentName,{...d.providerId?{dshProviderId:d.providerId}:{},...d.modelId?{dshModelId:d.modelId}:{}}),await this.options.globalConfigStore?.flush()),this.contextWindow=null,this.reportedContextCapacity=null,this.settingsState="pending",this.settingsErrorCode=null,this.pushToolbarMeta(),!this.runtime)return{status:"ok",result:this.settingsActionResult(e.action_type,d,p,"pending",!1)};try{if(await this.rebuildRuntime("settings_changed"),!this.applied||this.applied.appliedRevision<p)throw new Error("new runtime did not apply requested revision");return this.refreshProviderQuota(!0),{status:"ok",result:this.settingsActionResult(e.action_type,d,p,"applied",!0)}}catch(r){return{status:"failed",result:this.settingsActionResult(e.action_type,d,p,"failed",!1,this.redactError(r)),errorCode:"settings_apply_failed",errorMsg:this.redactError(r)}}}async finishProfileSelection(e,t){if(this.resolveIntegrationMode()==="profile_bridge")try{await this.prepareSelectedProfile()}catch(i){const s=String(i?.code??"profile_start_failed");return this.runtimeReadiness=s,this.settingsErrorCode=s,this.pushToolbarMeta(),{status:"failed",errorCode:s,errorMsg:this.redactError(i)}}return this.pushToolbarMeta(),{status:"ok",result:this.profileActionResult(e,t)}}createBridgeInstaller(){const e=this.options.bridgeInstallerOptions??{};return new D({command:e.command??"dsh",dshHome:this.options.dshHome??this.config.env?.DSH_HOME,profileName:this.resolveSelectedProfile(),...e.tarballPath?{tarballPath:e.tarballPath}:{}})}async healBridgeUpdate(e){return e.readiness!=="bridge_update_required"||this.options.autoInstallBridge===!1?e:(f.info(m,`auto-updating stale Bridge profile=${e.identity.profileName} installed=${e.installedBridgeVersion??"none"} bundled=${e.bundledBridgeVersion}`),await this.prepareSelectedProfile(),this.attachSelectedProfile())}async attachSelectedProfile(){const t=await this.createBridgeInstaller().status();return this.runtimeReadiness=t.readiness,this.settingsErrorCode=t.readiness==="ready"?null:t.readiness,t}async prepareSelectedProfile(){const e=this.createBridgeInstaller(),t=await ke({installer:e,autoInstall:this.options.autoInstallBridge!==!1,autoStart:this.options.autoStartProfile!==!1});this.runtimeReadiness=t.readiness,this.settingsErrorCode=t.readiness==="ready"?null:t.readiness}profileActionResult(e,t){return{outcome:t?"profile_created":"profile_set",profile_id:e,dsh_profile:e,created:t,dsh_profile_locked:this.options.bindingStore.isDshProfileLocked(this.options.aibotSessionId),dsh_profile_create:!this.options.bindingStore.isDshProfileLocked(this.options.aibotSessionId),available_profiles:this.listProfiles(),session_context:{dsh_profile:e,dsh_profile_locked:this.options.bindingStore.isDshProfileLocked(this.options.aibotSessionId),dsh_profile_create:!this.options.bindingStore.isDshProfileLocked(this.options.aibotSessionId)}}}persistSelectedProfile(e){return this.options.bindingStore.setDshSelectedProfile(this.options.aibotSessionId,e)?(this.options.globalConfigStore?.set(this.options.agentName,{dshProfile:e}),!0):!1}async flushSelectedProfile(){await this.options.bindingStore.flush(),await this.options.globalConfigStore?.flush()}listProfiles(){return me({dshHome:this.options.dshHome??this.config.env?.DSH_HOME})}pluginCommandContext(){return{dshHome:this.options.dshHome??this.config.env?.DSH_HOME,profileName:this.resolveSelectedProfile(),run:this.options.runDshCommand}}currentPlugins(){try{return L(this.pluginCommandContext())}catch{return[]}}pluginRestartRequired(){try{return ue(F({dshHome:this.options.dshHome??this.config.env?.DSH_HOME,profileName:this.resolveSelectedProfile()}).profileKey)}catch{return!1}}async executePluginAction(e,t,i){if(this.resolveIntegrationMode()!=="profile_bridge")return{status:"unsupported",errorCode:"capability_unavailable",errorMsg:"DSH plugins require Profile Bridge mode"};if(this.active)return{status:"failed",errorCode:"worker_busy",errorMsg:"Cannot change DeepSeek plugins during an active turn"};if(!this.options.bindingStore.get(i))return{status:"failed",errorCode:"binding_missing",errorMsg:"Session binding missing. Open a workspace first."};const s=this.pluginCommandContext(),o=!!this.runtime;try{if(e==="dsh_list_plugins"||e==="dsh_refresh_plugins"){const g=L(s);return this.pushToolbarMeta(),{status:"ok",result:this.pluginActionResult(g,!1)}}o&&await this.stopRuntime(!0);const l=F({dshHome:s.dshHome,profileName:s.profileName});await Se(l);const a=e==="dsh_enable_plugin"?await he({...s,name:String(t.name??t.plugin_name??"")}):await ce({...s,name:String(t.name??t.plugin_name??"")});let d="skipped";return a.changed&&(d=this.options.restartManagedProfile?await this.options.restartManagedProfile(a.identity.profileName):await we(new D({command:"dsh",dshHome:s.dshHome,profileName:a.identity.profileName})),pe(a.identity.profileKey,d!=="restarted")),o&&await this.rebuildRuntime("plugin_changed"),this.pushToolbarMeta(),{status:"ok",result:this.pluginActionResult(a.plugins,a.changed,d)}}catch(l){return o&&!this.runtime&&!this.stopped&&await this.rebuildRuntime("plugin_changed_failed"),{status:"failed",errorCode:String(l?.code??"plugin_action_failed"),errorMsg:this.redactError(l)}}}pluginActionResult(e,t,i="skipped"){const s=this.resolveSelectedProfile(),o=this.pluginRestartRequired();return{outcome:t?i==="restarted"?"plugin_applied":"plugin_updated":"plugin_unchanged",dsh_profile:s,dsh_plugins:e,dsh_plugin_restart_required:o,restart:i,session_context:{dsh_profile:s,dsh_plugins:e,dsh_plugin_restart_required:o}}}resolveSelectedProfile(){const e=this.options.bindingStore.getDshSelectedProfile(this.options.aibotSessionId),t=be({binding:e,global:this.options.globalConfigStore?.get(this.options.agentName)?.dshProfile,adapter:this.options.dshProfile});return this.options.bindingStore.get(this.options.aibotSessionId)&&e!==t&&this.options.bindingStore.setDshSelectedProfile(this.options.aibotSessionId,t),t}profileDataDir(e=this.resolveSelectedProfile()){return ve(this.options.dataRoot,e)}usageStore(){const e=this.resolveSelectedProfile(),t=P(this.profileDataDir(e),"session-usage.json"),i=P(this.options.dataRoot,"session-usage.json");return!$(t)&&$(i)&&(Y(Z(t),{recursive:!0,mode:448}),X(i,t)),Ue(t)}presetActionResult(e,t){const i=this.resolveDesiredSettings();return{outcome:"preset_set",agentPreset:e,agent_preset_id:e,agent_preset_locked:t,available_presets:[...this.presets],session_context:{agent_preset_id:i.agentPreset??e,agent_preset_locked:t}}}settingsActionResult(e,t,i,s,o,l){const a=this.resolveDesiredSettings(),d=a.revision||i,g={provider_id:a.providerId,model_id:a.modelId,mode_id:a.modeId,applied_provider_id:this.applied?.providerId??null,applied_model_id:this.applied?.modelId??null,applied_mode_id:this.applied?.modeId??null,applied_settings_revision:this.applied?.appliedRevision??null,settings_state:this.settingsState,settings_revision:d};return e==="set_mode"&&(g.sandbox_mode=W(a.modeId),g.approval_policy=a.modeId==="full_auto"?"never":"ask"),{outcome:`${e==="set_provider"?"provider":e==="set_model"?"model":"mode"}_set${s==="pending"||s==="failed"?"_pending":""}`,...t.providerId?{providerId:t.providerId,provider_id:t.providerId}:{},...t.modelId?{modelId:t.modelId,model_id:t.modelId}:{},...t.modeId?{modeId:t.modeId,mode_id:t.modeId,sandbox_mode:W(t.modeId),approval_policy:t.modeId==="full_auto"?"never":"ask"}:{},settingsRevision:d,settings_revision:d,sessionAlive:o,available_providers:[...this.providers],available_models:[...this.models],session_context:g,...l?{error:l}:{}}}syncGrixProvider(){const e=G(this.options.provider??{});if(e){this.providers.some(o=>o.id===v)||(this.providers=[{id:v,displayName:e.displayName},...this.providers]);const t=this.options.bindingStore.getDshSettings(this.options.aibotSessionId),i=this.options.globalConfigStore?.get(this.options.agentName),s=t?.providerId??i?.dshProviderId;(!s||s===V||s===v)&&this.options.bindingStore.updateDshSettings(this.options.aibotSessionId,{providerId:v});return}this.providers=this.providers.filter(t=>t.id!==v)}resolveDesiredSettings(){const e=this.options.bindingStore.getDshSettings(this.options.aibotSessionId),t=this.options.globalConfigStore?.get(this.options.agentName),i=e?.providerId??t?.dshProviderId,s=this.providers.some(a=>a.id===v)?v:void 0,o=qe(i||s,this.providers),l=[e?.modelId,t?.dshModelId,this.options.defaultModel,this.models[0]?.id].find(a=>!!a&&this.models.some(d=>d.id===a))??"deepseek-chat";return{providerId:o,modelId:l,modeId:e?.modeId??Ee,agentPreset:Q(e?.agentPreset,this.presets),maxTokens:e?.maxTokens??this.options.maxTokens??Re,revision:e?.revision??0}}resolveIntegrationMode(){return this.options.integrationMode?this.options.integrationMode:(this.config.command||"").includes("dsh-jsonrpc-agent")?"embedded_jsonrpc":"profile_bridge"}pushToolbarMeta(){const e=this.options.bindingStore.get(this.options.aibotSessionId);this.callbacks.sendUpdateBindingCard(this.options.aibotSessionId,this.stopped?"stopped":this.active?"busy":"ready",e?.cwd,Me({desired:this.resolveDesiredSettings(),applied:this.applied,models:this.models,providers:this.providers,presets:this.presets,agentPresetLocked:this.options.bindingStore.isDshAgentPresetLocked(this.options.aibotSessionId),state:this.settingsState,errorCode:this.settingsErrorCode,contextWindow:this.contextWindow,providerQuota:this.providerQuota,integrationMode:this.resolveIntegrationMode(),profileName:this.resolveSelectedProfile(),profiles:this.listProfiles(),profileLocked:this.options.bindingStore.isDshProfileLocked(this.options.aibotSessionId),plugins:this.currentPlugins(),pluginRestartRequired:this.pluginRestartRequired(),runtimeReadiness:this.runtimeReadiness,bridgeCapabilities:this.bridgeCapabilities}))}async refreshProviderQuota(e){this.providerQuota=null,this.pushToolbarMeta();try{this.providerQuota=await this.callbacks.queryProviderQuota(e)??{provider:"deepseek",providerLabel:"DeepSeek",success:!1,error:"unavailable"}}catch{this.providerQuota={provider:"deepseek",providerLabel:"DeepSeek",success:!1,error:"unavailable"}}this.pushToolbarMeta()}clearPendingApprovals(e){for(const t of this.pendingApprovals.values())clearTimeout(t.timer),t.resolve(e);this.pendingApprovals.clear()}thinkingEnabled(){const e=this.active?.inbound.connector_runtime_config?.thinking_events??this.active?.inbound.connector_runtime_config?.thinkingEvents;return e!=="off"&&e!=="hidden"&&e!=="none"}toolEventsEnabled(){const e=this.active?.inbound.connector_runtime_config?.tool_events;return e!=="off"&&e!=="hidden"&&e!=="none"}sendRaw(e,t,i){this.active&&this.callbacks.sendRawEventEnvelope(this.active.inbound.event_id,this.active.inbound.session_id,{type:e,payload:t},i)}failEvent(e,t){this.callbacks.sendEventResult(e.event_id,"failed",t),this.emit("eventDone",e.event_id)}startTimeout(e){this.activeTimeoutMs=e??this.options.promptTimeoutMs??K,this.armTimeout(this.activeTimeoutMs)}touchActivity(e=1){!this.active||!this.timeoutTimer||this.armTimeout(Math.min(this.activeTimeoutMs*e,60*6e4))}armTimeout(e){this.clearTimeout(),this.timeoutTimer=setTimeout(()=>{this.handlePromptTimeout()},e),this.timeoutTimer.unref?.()}async handlePromptTimeout(){if(!this.active)return;const e=this.active;this.clearTimeout();const t=this.runtime;this.runtime=null,this.intentionalRuntimeStop=!0,this.contextWindow=null,this.reportedContextCapacity=null,this.applied=void 0,this.settingsState="pending",this.settingsErrorCode=null,this.pushToolbarMeta(),await t?.cancel(this.runtimeSessionId).catch(()=>{}),t&&!t.isConnected()&&await t.terminate().catch(()=>{}),this.intentionalRuntimeStop=!1,!(this.active!==e||this.stopped)&&(this.finishActive("failed","Harness prompt timed out and the runtime was terminated"),this.emit("exit",1))}clearTimeout(){this.timeoutTimer&&clearTimeout(this.timeoutTimer),this.timeoutTimer=null}redactError(e,t){let i=e instanceof Error?e.message:String(e);const s=this.config.env?.DEEPSEEK_API_KEY;return s&&(i=i.split(s).join("[REDACTED]")),i=i.replace(/(api[_-]?key|authorization|bearer)\s*[:=]\s*\S+/gi,"$1=[REDACTED]"),t&&t.length>=16&&i.includes(t)&&(i="Harness request failed (prompt echo redacted)"),(i.includes("[aibot-system-prompt]")||i.includes("[base-behavior]"))&&(i="Harness runtime failed (system prompt echo redacted)"),i.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g,"").slice(0,2e3)}}function Fe(c){const e=Number(c&&typeof c=="object"?c.cursor:0);return Number.isSafeInteger(e)&&e>0?e:0}function Oe(c,e){return`grix-${H("sha256").update(c).digest("hex").slice(0,12)}-${e}-${M().slice(0,8)}`}function Ve(c){return`grix-${H("sha256").update(c).digest("hex").slice(0,16)}-${M().slice(0,8)}`}function J(){return{inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0,reasoningTokens:0}}function We(c){return{readiness:c.readiness,profile:c.identity.profileName,dshVersion:c.dshVersion,runningDshVersion:c.runningDshVersion,installedBridgeVersion:c.installedBridgeVersion,bundledBridgeVersion:c.bundledBridgeVersion,runningBridgeVersion:c.runningBridgeVersion,endpointCount:c.endpointCount,requiresProfileRestart:c.readiness==="profile_restart_required",compatibleDshVersions:c.compatibleDshVersions}}const Qe=new Set(["turn/start","step/start","step/end","agent/inbox/spliced","user/message","request/header","session/title","session/title-llm-request","session/end-seed","web/deepseek-search-llm-request","assistant/chunk:tool-call-delta","permission/preset","sandbox/mode","approval/policy","approval/asked","approval/decided","plan/mode","agent-preset/selected","llm/retry","llm/retry-started","goal/change","schedule/change","feedback/record","hook/invoked","hook/result","command/run","command/done","subagent/descriptor","tool-workflow/agent-start","tool-workflow/agent-end","tool-workflow/run-start","tool-workflow/run-end","tool/code-dispatch","tool/code-dispatch-start"]);function ze(c){const e=c.data?.chunk&&typeof c.data.chunk=="object"?c.data.chunk:c.data,t=String(e?.type??"");return Qe.has(c.type)||c.type==="assistant/chunk"&&["block-start","block-end","tool-call-delta","finish"].includes(t)}export{St as DshJsonRpcAdapter};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{EventEmitter as a}from"node:events";class u extends a{readable;writable;options;nextId=1;pending=new Map;completedIds=new Set;buffer="";closed=!1;writeChain=Promise.resolve();maxLineBytes;constructor(t,e,r={}){super(),this.readable=t,this.writable=e,this.options=r,this.maxLineBytes=r.maxLineBytes??4*1024*1024,t.setEncoding("utf8"),t.on("data",i=>this.onData(i)),t.on("end",()=>this.close(new Error("JSON-RPC stdout ended"))),t.on("error",i=>this.protocolError(i)),e.on("error",i=>this.protocolError(i))}initialize(t,e){return this.call("initialize",t,e)}prompt(t,e){return this.call("session/prompt",t,e)}async shutdown(t){await this.call("shutdown",{},t)}async call(t,e,r){if(this.closed)throw new Error("JSON-RPC client closed");const i=this.nextId++,o=String(i),n={jsonrpc:"2.0",id:i,method:t,params:e??null};return new Promise((l,c)=>{const d={resolve:l,reject:c};if(r){const s=()=>{this.pending.delete(o),c(Object.assign(new Error("JSON-RPC call aborted"),{code:"aborted"}))};if(d.abort=()=>r.removeEventListener("abort",s),r.aborted){s();return}r.addEventListener("abort",s,{once:!0})}this.pending.set(o,d),this.write(n).catch(s=>{this.pending.delete(o),d.abort?.(),c(s)})})}close(t=new Error("JSON-RPC client closed")){if(!this.closed){this.closed=!0;for(const e of this.pending.values())e.abort?.(),e.reject(t);this.pending.clear(),this.emit("close",t)}}onData(t){if(this.closed)return;if(this.buffer+=t,Buffer.byteLength(this.buffer,"utf8")>this.maxLineBytes&&!this.buffer.includes(`
|
|
2
|
+
`)){this.protocolError(Object.assign(new Error("JSON-RPC line exceeds byte limit"),{code:"line_too_large"}));return}const e=this.buffer.split(`
|
|
3
|
+
`);if(this.buffer=e.pop()??"",Buffer.byteLength(this.buffer,"utf8")>this.maxLineBytes){this.protocolError(Object.assign(new Error("JSON-RPC line exceeds byte limit"),{code:"line_too_large"}));return}for(const r of e)if(r.trim()){if(Buffer.byteLength(r,"utf8")>this.maxLineBytes){this.protocolError(Object.assign(new Error("JSON-RPC line exceeds byte limit"),{code:"line_too_large"}));return}if(this.dispatch(r),this.closed)return}}dispatch(t){let e;try{e=JSON.parse(t)}catch{this.protocolError(Object.assign(new Error("stdout contains invalid JSON-RPC"),{code:"invalid_json"}));return}if(this.options.capture?.append("in",e),e.jsonrpc!=="2.0"){this.protocolError(new Error("unsupported JSON-RPC version"));return}if(e.id!==void 0&&typeof e.method!="string"){const r=String(e.id);if(this.completedIds.has(r)){this.protocolError(new Error(`duplicate JSON-RPC response id=${r}`));return}const i=this.pending.get(r);if(!i){this.protocolError(new Error(`unexpected JSON-RPC response id=${r}`));return}if(this.pending.delete(r),this.completedIds.add(r),this.completedIds.size>1024&&this.completedIds.delete(this.completedIds.values().next().value),i.abort?.(),e.error&&typeof e.error=="object"){const o=e.error;i.reject(Object.assign(new Error(String(o.message??"JSON-RPC error")),{code:o.code,data:o.data}))}else i.resolve(e.result);return}if(typeof e.method=="string"&&e.id===void 0){const r=e.method,i=e.params;setImmediate(()=>{this.closed||this.emit("notification",r,i)});return}this.protocolError(new Error("unsupported JSON-RPC server request/envelope"))}write(t){const e=`${JSON.stringify(t)}
|
|
4
|
+
`;if(Buffer.byteLength(e,"utf8")>this.maxLineBytes)return Promise.reject(new Error("outbound JSON-RPC line exceeds byte limit"));this.options.capture?.append("out",t);const r=this.writeChain.then(()=>new Promise((i,o)=>{this.writable.write(e,"utf8",n=>n?o(n):i())}));return this.writeChain=r.catch(()=>{}),r}protocolError(t){this.emit("protocolError",t),this.close(t)}}export{u as DshJsonRpcClient};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{existsSync as b,readdirSync as w,readFileSync as h,renameSync as O,statSync as p,writeFileSync as P}from"node:fs";import{join as l}from"node:path";import{resolveCliPath as R}from"../../core/util/cli-probe.js";import{runDshCommand as E}from"./profile-catalog.js";import{assertSelectableDshProfileName as B,resolveDshHome as H,resolveDshProfileIdentity as I}from"./profile-resolver.js";const M=Object.freeze(["@deepseek-ai/dsh-base","@deepseek-ai/dsh-web-app"]),q="@grix/dsh-bridge",f=new Map;function k(e){return M.includes(e)?"inbox":e===q?"grix_bridge":"user"}function _(e){if(e==="inbox")return"DeepSeek \u5185\u7F6E\u5C42\uFF0C\u4E0D\u80FD\u5F00\u5173";if(e==="grix_bridge")return"Grix Bridge \u7531\u8FDE\u63A5\u5668\u5B89\u88C5\uFF0C\u4E0D\u80FD\u5F00\u5173"}function S(e){const n=x(e),r=$(n.profileRoot),t=j(r),s=C(n.profileRoot),o=new Set([...t,...s.keys()]),d=[];for(const i of[...o].sort()){const a=s.get(i),u=k(i);if(u!=="user"||!a?.hasBundle)continue;const c=_(u);d.push({name:i,version:a.version,kind:u,enabled:t.includes(i),locked:!1,has_bundle:!0,...c?{lock_reason:c}:{}})}return d}function z(e){return f.get(e)===!0}function X(e,n){n?f.set(e,!0):f.delete(e)}function Q(){f.clear()}async function V(e){return D(e,(n,r)=>{if(r.kind!=="user")throw Object.assign(new Error(r.lock_reason||"This plugin cannot be toggled"),{code:"plugin_locked"});return n.includes(r.name)?n:[...n,r.name]})}async function Y(e){return D(e,(n,r)=>{if(r.kind!=="user")throw Object.assign(new Error(r.lock_reason||"This plugin cannot be toggled"),{code:"plugin_locked"});return n.filter(t=>t!==r.name)})}async function D(e,n){const r=x(e),t=String(e.name??"").trim();if(!t)throw Object.assign(new Error("Plugin name is required"),{code:"plugin_invalid"});const s=k(t),o=_(s);if(o)throw Object.assign(new Error(o),{code:"plugin_locked"});const d=S({...e,profileName:r.profileName}),i=d.find(m=>m.name===t);if(!i)throw Object.assign(new Error("Plugin is not installed in this Profile"),{code:"plugin_not_found"});const a=l(r.profileRoot,"package.json"),u=h(a,"utf8"),c=N(u),g=j(c),y=n(g,i);if(T(g,y))return{plugins:d,changed:!1,identity:r};G(a,{...c,dsh:{...c.dsh,profile:{...c.dsh?.profile,bundles:y}}});try{await A(e,r)}catch(m){throw P(a,u,{mode:420}),m}return{plugins:S({...e,profileName:r.profileName}),changed:!0,identity:r}}async function A(e,n){const r=e.run??E,t=e.run?e.command?.trim()||"dsh":await R(e.command?.trim()||"dsh");if(!t)throw Object.assign(new Error("dsh is not installed or not on PATH"),{code:"dsh_missing"});await r(t,["--profile",n.profileName,"--dump-config"],n.dshHome)}function x(e){return I({dshHome:H(e.dshHome),profileName:B(e.profileName)})}function $(e){const n=l(e,"package.json");if(!b(n))throw Object.assign(new Error("DSH Profile package.json is missing"),{code:"profile_missing"});return N(h(n,"utf8"))}function N(e){try{const n=JSON.parse(e);return n&&typeof n=="object"?n:{}}catch{throw Object.assign(new Error("DSH Profile package.json is invalid"),{code:"profile_invalid"})}}function G(e,n){const r=`${e}.${process.pid}.tmp`;P(r,`${JSON.stringify(n,null,2)}
|
|
2
|
+
`,{mode:420}),O(r,e)}function j(e){const n=e.dsh?.profile?.bundles;if(!Array.isArray(n))return[];const r=new Set,t=[];for(const s of n){const o=String(s??"").trim();!o||r.has(o)||(r.add(o),t.push(o))}return t}function T(e,n){return e.length===n.length&&e.every((r,t)=>r===n[t])}function C(e){const n=new Map,r=l(e,"node_modules");if(!b(r)||!p(r).isDirectory())return n;for(const t of w(r)){if(t.startsWith("."))continue;const s=l(r,t);try{if(!p(s).isDirectory())continue}catch{continue}if(t.startsWith("@")){for(const o of w(s))v(l(s,o),`${t}/${o}`,n);continue}v(s,t,n)}return n}function v(e,n,r){try{if(!p(e).isDirectory())return;const t=JSON.parse(h(l(e,"package.json"),"utf8"));r.set(n,{version:String(t.version??"").trim(),hasBundle:!!(t.dsh?.bundle&&t.dsh.bundle.patch)})}catch{}}export{q as DSH_BRIDGE_PLUGIN_NAME,M as DSH_INBOX_PLUGIN_NAMES,k as classifyDshPlugin,Y as disableDshPlugin,V as enableDshPlugin,z as isDshPluginRestartRequired,S as listDshPlugins,X as markDshPluginRestartRequired,_ as pluginLockReason,Q as resetDshPluginRestartRequiredForTests};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{mkdirSync as c,mkdtempSync as u,rmSync as d}from"node:fs";import{tmpdir as p}from"node:os";import{join as n}from"node:path";import{DshWireCapture as w}from"./audit-boundary.js";import{DshProcessRuntime as f}from"./process-runtime.js";async function g(o){const t=u(n(p(),"grix-dsh-probe-")),m=n(t,"workspace"),r=n(t,"state");c(m,{mode:448});const s=new w(n(r,"probe.jsonl")),e=new f({command:o.command,args:o.args,cwd:m,cordisPath:o.cordisPath,sessionRoot:n(r,"sessions"),home:r,env:{},systemPrompt:"You are a protocol probe. Do not perform model requests.",settings:o.settings,capture:s}),a=Date.now();try{const i=await l(e.start(),o.timeoutMs??8e3);return await e.shutdown(),{serverName:i.serverInfo.name,serverVersion:i.serverInfo.version,latencyMs:Date.now()-a}}finally{await e.terminate().catch(()=>{}),s.close(),d(t,{recursive:!0,force:!0})}}function l(o,t){return new Promise((m,r)=>{const s=setTimeout(()=>r(Object.assign(new Error("Harness protocol probe timed out"),{code:"conversation_timeout"})),t);o.then(e=>{clearTimeout(s),m(e)},e=>{clearTimeout(s),r(e)})})}export{g as runDshProtocolProbe};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{chmodSync as u,existsSync as m,mkdirSync as E,realpathSync as _,statSync as p}from"node:fs";import{isAbsolute as l,relative as f,resolve as d}from"node:path";import{log as R}from"../../core/log/index.js";import{hasChildProcesses as D,killProcessGroup as w,resolveCommandPath as I,spawnCommand as y}from"../../core/runtime/spawn.js";import{DshJsonRpcClient as O}from"./jsonrpc-client.js";import{permissionModeFor as v}from"./toolbar-state.js";const x="deepseek-harness-runtime",C="deepseek-harness-sdk-runtime",L=new Set(["0.0.1"]),A=15e3,H=["PATH","SystemRoot","COMSPEC","PATHEXT","WINDIR","LANG","LC_ALL","LC_CTYPE","TZ","TMPDIR","TMP","TEMP","HTTPS_PROXY","HTTP_PROXY","ALL_PROXY","NO_PROXY","https_proxy","http_proxy","all_proxy","no_proxy","SSL_CERT_FILE","SSL_CERT_DIR","NODE_EXTRA_CA_CERTS"],k=["DEEPSEEK_API_KEY","DEEPSEEK_BASE_URL"];function b(i,t){const s={};for(const e of H){const o=t?.[e]??i[e];o!==void 0&&(s[e]=o)}for(const e of k){const o=t?.[e];o!==void 0&&(s[e]=o)}return s}class W{options;process=null;client=null;stderrTail="";constructor(t){this.options=t}async start(){this.validatePaths(),E(this.options.home,{recursive:!0,mode:448}),E(this.options.sessionRoot,{recursive:!0,mode:448});try{u(this.options.home,448),u(this.options.sessionRoot,448)}catch{}const t={...b(process.env,this.options.env),HOME:this.options.home,DSH_CORDIS_CONFIG:this.options.cordisPath,DSH_HOME:this.options.home,DSH_CWD:this.options.cwd,DSH_SESSION_ROOT:this.options.sessionRoot,DSH_SYSTEM_PROMPT:this.options.systemPrompt,DSH_PERMISSION_MODE:v(this.options.settings.modeId),DSH_TELEMETRY_DISABLED:"1"},s=I(this.options.command,t.PATH),e=y(s,[this.options.cordisPath,...this.options.args??[]],{cwd:this.options.cwd,env:t,stdio:["pipe","pipe","pipe"],detached:!0});if(this.process=e.process,!this.process.stdout||!this.process.stdin)throw new Error("Harness stdio unavailable");this.client=new O(this.process.stdout,this.process.stdin,{maxLineBytes:this.options.maxLineBytes,capture:this.options.capture}),this.process.stderr?.setEncoding("utf8"),this.process.stderr?.on("data",h=>{this.stderrTail=M(`${this.stderrTail}${String(h)}`,t.DEEPSEEK_API_KEY).slice(-8192)});const o=new Promise((h,P)=>this.process?.once("error",P)),c=new AbortController,n=this.client.initialize({cwd:this.options.cwd,provider:"deepseek-official",model:this.options.settings.modelId,maxTokens:this.options.settings.maxTokens},c.signal),a=S(this.options.initializeTimeoutMs??A,"Harness initialize timed out",()=>c.abort()),r=await Promise.race([n,o,a.promise]).finally(a.cancel);if(r.serverInfo?.name!==C||!L.has(r.serverInfo?.version))throw await this.terminate(),Object.assign(new Error(`incompatible Harness server ${T(r.serverInfo?.name)}@${T(r.serverInfo?.version)}`),{code:"protocol_incompatible"});return R.info(x,`initialized server=${r.serverInfo.name}@${r.serverInfo.version} env_keys=${Object.keys(t).filter(h=>h.startsWith("DSH_")||h.startsWith("DEEPSEEK_")).join(",")}`),r}async shutdown(){if(!this.process)return;const s=this.waitForExit(1e3).then(()=>!0,()=>!1),e=S(2e3,"Harness shutdown timed out");try{await Promise.race([this.client?.shutdown(),e.promise])}catch{}finally{e.cancel()}await s||await this.terminate(),this.client?.close(),this.client=null,this.process=null}async terminate(){const t=this.process;if(!t)return;const s=this.waitForExit(3e3).then(()=>!0,()=>!1);w(t,"SIGTERM"),await s||w(t,"SIGKILL"),this.client?.close(new Error("Harness runtime terminated")),this.client=null,this.process=null}async cancel(t){await this.terminate()}isConnected(){return!!this.process&&this.process.exitCode===null&&!!this.client}onExit(t){const s=this.process;return s?(s.once("exit",t),()=>s.removeListener("exit",t)):()=>{}}async hasBackgroundWork(){return this.process?.pid?D(this.process.pid,[this.process.pid]):!1}validatePaths(){const t=_(d(this.options.cwd));if(!m(t)||!p(t).isDirectory())throw new Error("bound workspace does not exist or is not a directory");if(!l(this.options.cordisPath)||!m(this.options.cordisPath)||!p(this.options.cordisPath).isFile())throw new Error("Cordis path must be an existing absolute file");const s=f(t,_(d(this.options.cordisPath)));if(s===""||!s.startsWith("..")&&!l(s))throw new Error("Cordis deployment file must be outside the user workspace");if((p(this.options.cordisPath).mode&18)!==0)throw new Error("Cordis deployment file must not be group/world writable");const e=f(t,d(this.options.sessionRoot));if(e===""||!e.startsWith("..")&&!l(e))throw new Error("DSH_SESSION_ROOT must be outside the workspace")}waitForExit(t){const s=this.process;return!s||s.exitCode!==null?Promise.resolve():new Promise((e,o)=>{const c=setTimeout(()=>{a(),o(new Error("process exit timeout"))},t),n=()=>{a(),e()},a=()=>{clearTimeout(c),s.removeListener("exit",n)};s.once("exit",n)})}}function S(i,t,s){let e;return{promise:new Promise((c,n)=>{e=setTimeout(()=>{s?.(),n(Object.assign(new Error(t),{code:"runtime_timeout"}))},i),e.unref?.()}),cancel:()=>{e&&clearTimeout(e)}}}function M(i,t){let s=i.replace(/(api[_-]?key|authorization|bearer)\s*[:=]\s*\S+/gi,"$1=[REDACTED]");return t&&(s=s.split(t).join("[REDACTED]")),s}function T(i){return String(i??"unknown").replace(/[\u0000-\u001f\u007f]/g,"").slice(0,128)||"unknown"}export{W as DshProcessRuntime,b as sanitizeDshRuntimeEnv};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{EventEmitter as c}from"node:events";const l=1,u=1,a=16*1024*1024;class p extends c{stream;options;pending=new Map;abandoned=new Set;nextId=1;buffer=Buffer.alloc(0);closed=!1;writeChain=Promise.resolve();requestHandler=null;constructor(t,e={}){super(),this.stream=t,this.options=e,t.on("data",r=>this.onData(Buffer.isBuffer(r)?r:Buffer.from(r))),t.on("end",()=>this.close(new Error("DSH Bridge IPC ended"))),t.on("close",()=>this.close(new Error("DSH Bridge IPC closed"))),t.on("error",r=>this.protocolError(r))}get isOpen(){return!this.closed&&!this.stream.destroyed}setRequestHandler(t){this.requestHandler=t}call(t,e,r){if(!this.isOpen)return Promise.reject(new Error("DSH Bridge JSON-RPC peer closed"));const o=`${process.pid}-${this.nextId++}`;return new Promise((i,n)=>{const d={resolve:i,reject:n};if(r){const s=()=>{this.pending.delete(o),this.abandoned.add(o),this.abandoned.size>4096&&this.abandoned.delete(this.abandoned.values().next().value),n(Object.assign(new Error("DSH Bridge call aborted"),{code:"aborted"}))};if(d.cleanup=()=>r.removeEventListener("abort",s),r.aborted){s();return}r.addEventListener("abort",s,{once:!0})}this.pending.set(o,d),this.write({jsonrpc:"2.0",id:o,method:t,params:e??null}).catch(s=>{this.pending.delete(o),d.cleanup?.(),n(s)})})}notify(t,e){return this.write({jsonrpc:"2.0",method:t,params:e??null})}close(t=new Error("DSH Bridge JSON-RPC peer closed")){if(!this.closed){this.closed=!0;for(const e of this.pending.values())e.cleanup?.(),e.reject(t);this.pending.clear(),this.abandoned.clear(),this.stream.destroyed||this.stream.destroy(),this.emit("close",t)}}onData(t){if(this.closed)return;this.buffer=this.buffer.length===0?t:Buffer.concat([this.buffer,t]);const e=this.options.maxFrameBytes??a;for(;this.buffer.length>=4;){const r=this.buffer.readUInt32BE(0);if(r===0||r>e){this.protocolError(Object.assign(new Error(`DSH Bridge frame length ${r} is invalid`),{code:"frame_too_large"}));return}if(this.buffer.length<4+r)return;const o=this.buffer.subarray(4,4+r);if(this.buffer=this.buffer.subarray(4+r),this.dispatch(o),this.closed)return}this.buffer.length>e+4&&this.protocolError(new Error("DSH Bridge receive buffer exceeds limit"))}dispatch(t){let e;try{e=JSON.parse(t.toString("utf8"))}catch{this.protocolError(Object.assign(new Error("DSH Bridge frame contains invalid JSON"),{code:"invalid_json"}));return}if(this.options.capture?.append("in",e),e.jsonrpc!=="2.0"){this.protocolError(new Error("Unsupported JSON-RPC version"));return}if(e.id!==void 0&&typeof e.method!="string"){const r=String(e.id),o=this.pending.get(r);if(!o){if(this.abandoned.delete(r))return;this.protocolError(new Error(`Unexpected DSH Bridge response id=${r}`));return}if(this.pending.delete(r),o.cleanup?.(),e.error&&typeof e.error=="object"){const i=e.error,n=i.data&&typeof i.data=="object"?i.data:void 0;o.reject(Object.assign(new Error(String(i.message??"DSH Bridge request failed")),{code:n?.code??i.code,data:i.data}))}else o.resolve(e.result);return}if(typeof e.method=="string"&&e.id===void 0){this.emit("notification",e.method,e.params);return}if(typeof e.method=="string"&&e.id!==void 0){this.handleRequest(String(e.id),e.method,e.params);return}this.protocolError(new Error("Unsupported DSH Bridge JSON-RPC envelope"))}async handleRequest(t,e,r){if(!this.requestHandler){await this.write({jsonrpc:"2.0",id:t,error:{code:-32601,message:`Method not found: ${e}`}}).catch(()=>{});return}try{const o=await this.requestHandler(e,r);await this.write({jsonrpc:"2.0",id:t,result:o??null})}catch(o){const i=o;await this.write({jsonrpc:"2.0",id:t,error:{code:typeof i.code=="number"?i.code:-32e3,message:i.message||"Request failed",data:{code:typeof i.code=="string"?i.code:"bridge_request_failed"}}}).catch(()=>{})}}write(t){if(!this.isOpen)return Promise.reject(new Error("DSH Bridge JSON-RPC peer closed"));const e=Buffer.from(JSON.stringify(t),"utf8"),r=this.options.maxFrameBytes??a;if(e.length===0||e.length>r)return Promise.reject(Object.assign(new Error("Outbound DSH Bridge frame exceeds limit"),{code:"frame_too_large"}));const o=Buffer.allocUnsafe(4+e.length);o.writeUInt32BE(e.length,0),e.copy(o,4),this.options.capture?.append("out",t);const i=this.writeChain.then(()=>new Promise((n,d)=>{this.stream.write(o,s=>s?d(s):n())}));return this.writeChain=i.catch(()=>{}),i}protocolError(t){this.emit("protocolError",t),this.close(t)}}export{a as DEFAULT_DSH_BRIDGE_FRAME_BYTES,p as DshBridgeJsonRpcPeer,u as GRIX_DSH_PROTOCOL_MAX,l as GRIX_DSH_PROTOCOL_MIN};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as n}from"node:fs";import{execFile as i}from"node:child_process";import{promisify as a}from"node:util";import{resolveCliPath as c}from"../../core/util/cli-probe.js";import{assertSelectableDshProfileName as m,resolveDshHome as d,resolveDshProfileIdentity as l}from"./profile-resolver.js";const f=a(i),h="@deepseek-ai/dsh-web-app";async function g(e){const s=m(e.profileName),r=l({dshHome:e.dshHome,profileName:s});if(n(r.profileRoot))return{identity:r,created:!1};const o=e.run??p,t=e.run?e.command?.trim()||"dsh":await c(e.command?.trim()||"dsh");if(!t)throw Object.assign(new Error("dsh is not installed or not on PATH"),{code:"dsh_missing"});return await o(t,["plugin","--profile",s,"add",h],r.dshHome),{identity:r,created:!0}}async function p(e,s,r){try{return(await f(e,s,{env:{...process.env,...r?{DSH_HOME:d(r)}:{}},timeout:6e4,maxBuffer:8388608})).stdout}catch(o){const t=o&&typeof o=="object"?o:{};throw Object.assign(new Error(String(t.stderr??t.message??o??"unknown error").replace(/[\r\n]+/g," ").slice(0,1024)),{code:"dsh_command_failed"})}}export{g as createDshWebProfile,p as runDshCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as N}from"node:crypto";import{existsSync as f,readFileSync as h,readdirSync as g,realpathSync as y,statSync as p}from"node:fs";import{homedir as H}from"node:os";import{basename as m,dirname as c,join as s,resolve as a}from"node:path";import{fileURLToPath as P}from"node:url";function d(e,r=process.env){const t=e?.trim()||r.DSH_HOME?.trim()||s(H(),".dsh");return a(t)}const i="web",D="headless";function l(e){return A(String(e??"").trim())}function E(e){const r=l(e);if(r===D)throw Object.assign(new Error("headless is a one-shot DSH profile and cannot be used as a Grix Profile"),{code:"profile_invalid"});return r}function L(e,r){return s(a(e),"profiles",l(r))}function G(e={}){for(const r of[e.binding,e.global,e.adapter]){const t=String(r??"").trim();if(t)try{return E(t)}catch{continue}}return i}function S(e){return e===i?"web\uFF08\u63D2\u4EF6\u6258\u7BA1\uFF09":e}function w(e,r){if(r===i)return!0;try{const n=JSON.parse(h(s(e,"package.json"),"utf8")).dsh?.profile?.bundles;return Array.isArray(n)&&n.some(o=>String(o).includes("dsh-web-app"))}catch{return!1}}function J(e={}){const r=d(e.dshHome,e.env),t=new Map;t.set(i,{id:i,displayName:S(i),webApp:!0});const n=s(r,"profiles");if(!f(n)||!p(n).isDirectory())return[...t.values()];for(const o of g(n).sort()){if(o===D||o===i)continue;try{l(o)}catch{continue}const u=s(n,o);try{if(!p(u).isDirectory())continue}catch{continue}t.set(o,{id:o,displayName:S(o),webApp:w(u,o)})}return[...t.values()]}function R(e){const r=d(e.dshHome,e.env),t=l(e.profileName?.trim()||i),n=a(r,"profiles",t),o=f(n)?y(n):n;return{dshHome:r,profileName:t,profileRoot:o,profileKey:b(o)}}function b(e){return N("sha256").update(a(e)).digest("hex")}function _(e){return s(e.dshHome,"run","grix-dsh-bridge",e.profileKey)}function I(e){const r=_(e);if(!f(r)||!p(r).isDirectory())return[];const t=[];for(const n of g(r).filter(o=>o.endsWith(".json")).sort())try{const o=JSON.parse(h(s(r,n),"utf8"));if(!O(o)||o.profileKey!==e.profileKey||!M(o.pid)||!f(o.tokenPath)||!p(o.tokenPath).isFile())continue;t.push(o)}catch{}return t}function V(e){const r=I(e);if(r.length===0)throw Object.assign(new Error(`No live Grix Bridge endpoint in DSH profile "${e.profileName}". If Bridge is already installed, restart the profile (stop it, then: dsh --profile ${e.profileName}); otherwise install the Grix Bridge plugin first.`),{code:"bridge_missing"});if(r.length>1)throw Object.assign(new Error(`Multiple live Grix Bridge endpoints found for DSH profile "${e.profileName}". Stop extra profile processes so only one instance remains.`),{code:"profile_instance_ambiguous"});return r[0]}function $(e){let r=c(P(e)),t;for(;c(r)!==r;){const o=s(r,"package.json");if(f(o))try{if(JSON.parse(h(o,"utf8")).dsh?.profile)return x(r)}catch{}m(r)==="node_modules"&&(t=c(r)),r=c(r)}if(t)return x(t);const n=d();return R({dshHome:n,profileName:process.env.GRIX_DSH_PROFILE||i})}function x(e){const r=y(e),t=m(r),n=c(r);return{dshHome:m(n)==="profiles"?c(n):d(),profileName:t,profileRoot:r,profileKey:b(r)}}function A(e){if(!e||e==="."||e===".."||e.includes("/")||e.includes("\\")||e.includes("\0"))throw Object.assign(new Error("Invalid DSH profile name"),{code:"profile_invalid"});return e}function O(e){return e.schemaVersion===1&&(e.transport==="unix"||e.transport==="pipe")&&typeof e.address=="string"&&e.address.length>0&&Number.isSafeInteger(e.pid)&&Number(e.pid)>0&&typeof e.startedAt=="string"&&typeof e.profileKey=="string"&&typeof e.profileName=="string"&&typeof e.dshVersion=="string"&&typeof e.bridgeVersion=="string"&&Number.isSafeInteger(e.protocolMin)&&Number.isSafeInteger(e.protocolMax)&&typeof e.instanceId=="string"&&typeof e.tokenPath=="string"}function M(e){try{return process.kill(e,0),!0}catch(r){return r.code==="EPERM"}}export{i as DEFAULT_DSH_PROFILE_NAME,D as DSH_HEADLESS_PROFILE_NAME,E as assertSelectableDshProfileName,_ as bridgeDiscoveryDirectory,I as discoverDshBridgeEndpoints,S as dshProfileDisplayName,$ as inferProfileIdentityFromModule,J as listDshProfiles,l as parseDshProfileName,w as profileHasWebApp,b as profileKeyFor,L as resolveDshConnectorProfileDataDir,d as resolveDshHome,R as resolveDshProfileIdentity,G as resolveDshSelectedProfileName,V as selectDshBridgeEndpoint};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{createHmac as H,randomUUID as T}from"node:crypto";import{EventEmitter as x}from"node:events";import{readFileSync as j}from"node:fs";import{createConnection as $}from"node:net";import{isCompatibleDshVersion as C}from"./bridge-session-reliability.js";import{DshBridgeJsonRpcPeer as z,GRIX_DSH_PROTOCOL_MAX as O,GRIX_DSH_PROTOCOL_MIN as M}from"./profile-bridge-protocol.js";import{resolveDshProfileIdentity as q,selectDshBridgeEndpoint as G}from"./profile-resolver.js";import{DEFAULT_DSH_PRESETS as U,normalizeDshPresets as V,normalizeDshProviders as L,resolveDshAgentPreset as F,resolveDshProviderId as K}from"./toolbar-state.js";const X=T(),B=5e3,_=1e4,J=6e4;class W extends x{peer;sessionId;ownerId;onCursorAck;notificationsActive=!1;pendingNotifications=[];constructor(e,t,r,s){super(),this.peer=e,this.sessionId=t,this.ownerId=r,this.onCursorAck=s,e.on("notification",(o,l)=>{if(!this.notificationsActive){this.pendingNotifications.push({method:o,params:l});return}this.deliverNotification(o,l)}),e.on("protocolError",o=>this.emit("protocolError",o))}prompt(e,t){return this.peer.call("session/prompt",{sessionId:e.sessionId,ownerId:this.ownerId,contentBlocks:e.contentBlocks},t)}async shutdown(e){try{await this.peer.call("session/close",{sessionId:this.sessionId,ownerId:this.ownerId},u(e,5e3))}finally{this.peer.close()}}close(e){this.peer.close(e)}activateNotifications(){if(!this.notificationsActive){this.notificationsActive=!0;for(const e of this.pendingNotifications.splice(0))this.deliverNotification(e.method,e.params)}}call(e,t,r){const s=t&&typeof t=="object"?t:{};return this.peer.call(e,{sessionId:this.sessionId,ownerId:this.ownerId,...s},u(r,1e4))}async ack(e,t){if(!Number.isSafeInteger(e)||e<=0)throw Object.assign(new Error("Bridge ACK cursor must be a positive integer"),{code:"invalid_params"});const r=await this.peer.call("session/ack",{sessionId:this.sessionId,ownerId:this.ownerId,cursor:e},u(t,5e3));return await this.onCursorAck?.(e),r}cancel(e){return this.peer.call("session/cancel",{sessionId:this.sessionId,ownerId:this.ownerId},u(e,3e4))}setOptions(e,t){return this.peer.call("session/setOptions",{sessionId:this.sessionId,ownerId:this.ownerId,model:e.modelId,modeId:e.modeId},u(t,1e4))}deliverNotification(e,t){this.emit("notification",e,t)}}class re{options;client=null;peer=null;socket=null;exitEmitter=new x;intentionalClose=!1;constructor(e){this.options=e}async start(){const e=q({dshHome:this.options.dshHome,profileName:this.options.profileName}),t=G(e);if(t.protocolMax<M||t.protocolMin>O)throw Object.assign(new Error(`Incompatible Grix DSH Bridge protocol ${t.protocolMin}-${t.protocolMax}`),{code:"bridge_incompatible"});if(!C(t.dshVersion))throw Object.assign(new Error(`DSH Profile ${t.dshVersion||"unknown"} is outside the verified Bridge compatibility matrix`),{code:"bridge_incompatible"});const r=j(t.tokenPath,"utf8").trim();if(!r)throw Object.assign(new Error("DSH Bridge token file is empty"),{code:"auth_failed"});const s=await Z(t.address,this.options.connectTimeoutMs??B);this.socket=s;const o=new z(s,{maxFrameBytes:this.options.maxFrameBytes,capture:this.options.capture});this.peer=o,o.on("close",()=>{this.socket=null,this.peer=null,this.client=null,this.intentionalClose||this.exitEmitter.emit("exit")}),o.setRequestHandler(async(i,n)=>{if(i!=="interaction/requestApproval")throw Object.assign(new Error(`Unsupported Bridge request: ${i}`),{code:"capability_unavailable"});const a=n&&typeof n=="object"?n:{};return{outcome:await this.options.onApproval?.(a)??"unavailable"}});const l=T(),f=H("sha256",r).update(`${l}
|
|
2
|
+
${e.profileKey}
|
|
3
|
+
${t.instanceId}`).digest("hex"),g=AbortSignal.timeout(this.options.initializeTimeoutMs??this.options.connectTimeoutMs??B),c=await o.call("bridge/initialize",{protocol:{min:M,max:O},client:{name:"grix-connector",version:process.env.npm_package_version??"unknown",instanceId:X},profileKey:e.profileKey,requestedRole:"controller",auth:{nonce:l,proof:f}},g),N=c.profile&&typeof c.profile=="object"?c.profile:{},v=String(N.dshVersion??"");if(!C(v)||v!==t.dshVersion)throw o.close(new Error("DSH Profile version changed or is outside the verified Bridge compatibility matrix")),Object.assign(new Error(`DSH Profile version mismatch: discovery=${t.dshVersion||"unknown"} handshake=${v||"unknown"}`),{code:"bridge_incompatible"});const d=String(this.options.settings.providerId??"").trim(),I=this.options.managedProvider,b=!!I&&(!d||d===I.id);let h=[],y=!1;const P=b?0:this.options.catalogRefreshAttempts??4;for(let i=0;i<=P;i++){try{const n=AbortSignal.timeout(this.options.catalogTimeoutMs??_),a=await o.call("profile/listProviders",{},n),D=L(a.providers);if(y=!0,D.length>0&&(h=D),!d||h.some(R=>R.id===d)||b)break}catch{break}i<P&&await new Promise(n=>setTimeout(n,150))}const w=b&&I?I.id:y&&d&&!h.some(i=>i.id===d)?d:K(this.options.settings.providerId,h);let m;try{const i=AbortSignal.timeout(this.options.catalogTimeoutMs??_),n=await o.call("profile/listModels",{provider:w},i);m=Array.isArray(n.models)?n.models.filter(a=>!!a&&typeof a=="object"):[]}catch{}const E=(m??[]).some(i=>String(i.id??"")===this.options.settings.modelId)?this.options.settings.modelId:String(m?.[0]?.id??this.options.settings.modelId);let S=[...U];try{const i=AbortSignal.timeout(this.options.catalogTimeoutMs??_),n=await o.call("profile/listPresets",{},i),a=V(n.presets);a.length>0&&(S=a)}catch{}const k=F(this.options.settings.agentPreset,S);this.client=new W(o,this.options.sessionId,this.options.ownerId,this.options.onCursorAck);try{const i=AbortSignal.timeout(this.options.sessionCreateTimeoutMs??J);await o.call("session/create",{sessionId:this.options.sessionId,ownerId:this.options.ownerId,cwd:this.options.cwd,provider:w,model:E,maxTokens:this.options.settings.maxTokens,modeId:this.options.settings.modeId,agentPreset:k,systemPrompt:this.options.systemPrompt,resume:this.options.resumeSession===!0,lastAckCursor:this.options.lastAckCursor??0,...this.options.managedProvider&&w===this.options.managedProvider.id?{managedProvider:this.options.managedProvider}:{}},i)}catch(i){throw this.client.close(i instanceof Error?i:new Error(String(i))),this.client=null,i}const A=c.serverInfo&&typeof c.serverInfo=="object"?c.serverInfo:{};return{serverInfo:{name:String(A.name??"grix-dsh-profile-bridge"),version:String(A.version??"unknown")},profile:c.profile,capabilities:c.capabilities,...m!==void 0?{models:m}:{},selectedModel:E,providers:h,selectedProvider:w,presets:S,selectedPreset:k}}async shutdown(){this.intentionalClose=!0;try{await this.client?.shutdown()}finally{this.peer?.close(),this.client=null,this.peer=null,this.socket=null}}async terminate(){this.intentionalClose=!0,this.peer?.close(new Error("DSH Profile Bridge connection terminated")),this.client=null,this.peer=null,this.socket=null}async cancel(e){await this.client?.cancel()}async hasBackgroundWork(){return!1}isConnected(){return!!this.client&&!!this.peer?.isOpen}onExit(e){return this.exitEmitter.on("exit",e),()=>this.exitEmitter.off("exit",e)}}function u(p,e){return p??AbortSignal.timeout(e)}function Z(p,e){return new Promise((t,r)=>{const s=$(p),o=setTimeout(()=>{l(),s.destroy(),r(Object.assign(new Error("Timed out connecting to DSH Profile Bridge"),{code:"bridge_connect_timeout"}))},e);o.unref?.();const l=()=>{clearTimeout(o),s.off("connect",f),s.off("error",g)},f=()=>{l(),s.setNoDelay(!0),t(s)},g=c=>{l(),r(Object.assign(c,{code:"bridge_connect_failed"}))};s.once("connect",f),s.once("error",g)})}export{_ as BRIDGE_CATALOG_TIMEOUT_MS,B as BRIDGE_INITIALIZE_TIMEOUT_MS,J as BRIDGE_SESSION_CREATE_TIMEOUT_MS,re as DshProfileRuntime,W as DshProfileRuntimeClient};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createWriteStream as T,existsSync as k,mkdirSync as K,readFileSync as A,renameSync as C,rmSync as F,writeFileSync as H}from"node:fs";import{join as x}from"node:path";import{log as c}from"../../core/log/index.js";import{resolveCliPath as j}from"../../core/util/cli-probe.js";import{killProcessGroup as B,spawnCommand as G}from"../../core/runtime/spawn.js";import{errorForDshBridgeReadiness as R}from"./bridge-installer.js";import{bridgeDiscoveryDirectory as D,discoverDshBridgeEndpoints as y,profileHasWebApp as q}from"./profile-resolver.js";const f="deepseek-harness-profile-supervisor",I=45e3,U=500;function J(e){return{...process.env,DSH_HOME:e}}const m=new Map,u=new Map;function h(e,r,n="coalesce"){const t=m.get(e.profileKey);if(t&&n==="coalesce")return t.promise;const o=(t?t.promise.catch(()=>{}).then(()=>r()):r()).finally(()=>{m.get(e.profileKey)?.promise===o&&m.delete(e.profileKey)});return m.set(e.profileKey,{promise:o}),o}async function de(e){return h(e.installer.identity,()=>O(e))}async function ce(e){return h(e.installer.identity,()=>W(e))}async function W(e){const r=e.autoInstall!==!1;let n=await e.installer.status();return r&&["profile_missing","bridge_missing","bridge_update_required"].includes(n.readiness)&&(n=await e.installer.install()),n.readiness==="ready"&&!e.reloadManaged?n:O(e)}async function O(e){const r=e.installer,n=e.autoStart!==!1,t=e.readyTimeoutMs??I;let i=await r.status();if(e.reloadManaged&&(i=await Y(r,i,t),i.readiness==="ready")||i.readiness==="ready")return i;if(!n){const a=R(i);if(a)throw a;return i}if(i.readiness==="profile_restart_required"&&i.endpointCount===0)await b(r,i.identity),i=await _(a=>a.readiness==="ready"||a.readiness==="bridge_incompatible",r,t),i.readiness!=="ready"&&i.readiness!=="bridge_incompatible"&&await M(i.identity,"bridge endpoint did not appear");else if(i.readiness==="profile_restart_required"&&i.endpointCount===1&&i.runningBridgeVersion&&i.installedBridgeVersion){const a=y(i.identity)[0],s=g(i.identity);if(a&&s&&s.pid===a.pid&&l(s.pid)){const p=i.runningBridgeVersion!==i.installedBridgeVersion?"bridge upgrade":"bridge content refresh";c.info(f,`restarting connector-managed profile=${i.identity.profileName} pid=${s.pid} for ${p}`),await w(i.identity,s.pid),await b(r,i.identity),i=await _(S=>S.readiness==="ready"||S.readiness==="bridge_incompatible",r,t),i.readiness!=="ready"&&i.readiness!=="bridge_incompatible"&&await M(i.identity,"bridge endpoint did not appear after upgrade restart")}}if(i.readiness==="ready")return z(i),i;const o=R(i);if(o)throw o;return i}async function Y(e,r,n){const t=r.identity,i=g(t);if(!i||!l(i.pid))return r;const o=y(t);if(!o.some(p=>p.pid===i.pid)&&o.length>0)return r;c.info(f,`reloading connector-managed profile=${t.profileName} pid=${i.pid} after settings write`),await w(t,i.pid),await b(e,t);const s=await _(p=>p.readiness==="ready"||p.readiness==="bridge_incompatible",e,n);return s.readiness!=="ready"&&s.readiness!=="bridge_incompatible"&&await M(t,"bridge endpoint did not appear after settings reload"),s}function z(e){c.info(f,`bridge ready profile=${e.identity.profileName} endpoints=${e.endpointCount} bridge=${e.runningBridgeVersion}`)}async function b(e,r){const n=g(r);if(n&&l(n.pid)){if(y(r).some(E=>E.pid===n.pid)){c.info(f,`reusing connector-managed profile=${r.profileName} pid=${n.pid}`);return}c.warn(f,`restarting stuck connector-managed profile=${r.profileName} pid=${n.pid} (alive without endpoint)`),await w(r,n.pid)}else n&&P(r);const t=await j(e.command);if(!t)throw Object.assign(new Error("dsh is not installed or not on PATH"),{code:"dsh_missing"});const i=Q(r),o=D(r);K(o,{recursive:!0,mode:448});const a=x(o,"managed-profile.log"),s=T(a,{flags:"a",mode:384}),p=J(r.dshHome),d=G(t,i,{cwd:r.profileRoot,env:p,stdio:["ignore","pipe","pipe"],detached:!0}).process;if(!d.pid)throw s.end(),Object.assign(new Error(`Failed to start DSH profile "${r.profileName}"`),{code:"profile_start_failed"});d.stdout?.pipe(s,{end:!1}),d.stderr?.pipe(s,{end:!1}),d.once("exit",(N,v)=>{c.warn(f,`managed profile exited profile=${r.profileName} pid=${d.pid} code=${N} signal=${v}`),u.get(r.profileKey)===d&&u.delete(r.profileKey),g(r)?.pid===d.pid&&P(r);try{s.end()}catch{}}),d.unref(),u.set(r.profileKey,d),X(r,{schemaVersion:1,profileKey:r.profileKey,profileName:r.profileName,pid:d.pid,startedAt:new Date().toISOString(),command:t,args:i}),c.info(f,`started connector-managed profile=${r.profileName} pid=${d.pid} args=${i.join(" ")}`)}async function M(e,r){const n=g(e);n&&(c.warn(f,`stopping stuck connector-managed profile=${e.profileName} pid=${n.pid} reason=${r}`),await w(e,n.pid))}async function w(e,r){const n=u.get(e.profileKey);if(n?.pid===r){try{B(n,"SIGTERM")}catch{}u.delete(e.profileKey)}else if(l(r))try{process.kill(r,"SIGTERM")}catch{}const t=Date.now()+5e3;for(;Date.now()<t&&l(r);)await V(100);if(l(r))try{process.kill(r,"SIGKILL")}catch{}P(e)}function Q(e){return q(e.profileRoot,e.profileName)?["--profile",e.profileName,"--port","0"]:["--profile",e.profileName]}async function _(e,r,n){const t=Date.now()+n;let i=await r.status();for(;Date.now()<t;){if(e(i))return i;const o=g(r.identity);if(o&&!l(o.pid))throw P(r.identity),Object.assign(new Error(`Connector-managed DSH profile "${r.identity.profileName}" exited before Bridge became ready`),{code:"profile_start_failed"});await V(U),i=await r.status()}return i}function $(e){return x(D(e),"managed-profile.json")}function g(e){try{const r=JSON.parse(A($(e),"utf8"));return r.schemaVersion!==1||typeof r.pid!="number"||r.profileKey!==e.profileKey?null:r}catch{return null}}function X(e,r){const n=D(e);K(n,{recursive:!0,mode:448});const t=$(e),i=`${t}.${process.pid}.tmp`;H(i,`${JSON.stringify(r,null,2)}
|
|
2
|
+
`,{mode:384}),C(i,t)}function P(e){try{F($(e),{force:!0})}catch{}}function l(e){try{return process.kill(e,0),!0}catch(r){return r.code==="EPERM"}}function V(e){return new Promise(r=>setTimeout(r,e))}function fe(){m.clear();for(const e of u.values())try{e.pid&&B(e,"SIGKILL")}catch{}u.clear()}function pe(e){return k($(e))}async function le(e){const r=m.get(e.profileKey);r&&await r.promise.catch(()=>{})}async function ue(e,r=I){let n="failed";return await h(e.identity,async()=>(n=await Z(e,r),L(e,n==="restarted"?"ready":"profile_restart_required")),"queue"),n}async function Z(e,r){const n=e.identity,t=g(n);if(!t||!l(t.pid))return"not_managed";const i=y(n);if(i.length>0&&!i.some(o=>o.pid===t.pid))return"not_managed";try{return c.info(f,`restarting connector-managed profile=${n.profileName} pid=${t.pid} for plugin toggle`),await w(n,t.pid),await b(e,n),(await _(a=>a.readiness==="ready"||a.readiness==="bridge_incompatible",e,r)).readiness==="ready"?"restarted":"failed"}catch(o){return c.warn(f,`plugin-toggle restart failed profile=${n.profileName}: ${o instanceof Error?o.message:String(o)}`),"failed"}}function ge(e,r){return h(e.identity,async()=>(await r,L(e,"ready")))}function L(e,r){return{readiness:r,command:e.command,commandPath:null,dshVersion:null,runningDshVersion:null,identity:e.identity,installedBridgeVersion:null,bundledBridgeVersion:"",runningBridgeVersion:null,endpointCount:0,compatibleDshVersions:[]}}export{le as awaitDshProfileIdle,Q as buildDshProfileBootArgs,de as ensureDshBridgeReady,ge as holdDshProfileInflightForTests,pe as managedProfileRecordExists,J as managedProfileSpawnEnv,ce as prepareDshProfileBridge,fe as resetDshProfileSupervisorForTests,ue as restartManagedProfileIfOwned};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const f=30,l=48e3,S=1e6,_=/\[\[message_id:([^\]\r\n]+)\]\]/g,g=/\[\[quoted_message_id:([^\]\r\n]+)\]\]/g;function m(e){if(!e)return[];try{const r=JSON.parse(e);return Array.isArray(r)?r.slice(-30).flatMap(t=>{if(!t||typeof t!="object")return[];const n=t,s=String(n.content??n.text??"").trim();return s?[{msgId:String(n.msg_id??n.message_id??"").trim()||void 0,senderId:String(n.sender_id??n.user_id??"").trim()||void 0,content:a(s)}]:[]}):[]}catch{return[]}}function p(e,r){const t=[],n=[];let s=48e3;for(const o of m(e.context_messages_json).reverse()){if(o.msgId&&r.has(o.msgId))continue;const c=`[context sender=${JSON.stringify(o.senderId??"unknown")} message_id=${JSON.stringify(o.msgId??"")}]
|
|
2
|
+
${o.content}`;c.length>s||(t.unshift(c),s-=c.length,o.msgId&&n.push(o.msgId))}e.quoted_message_id&&t.push(`[quoted_message id=${JSON.stringify(e.quoted_message_id)}]
|
|
3
|
+
The current message explicitly replies to this platform message.`);const d=a(String(e.content??"")).trim();if(d.length>1e6)throw Object.assign(new Error("DeepSeek Harness prompt exceeds the connector memory limit"),{code:"prompt_too_large"});t.push(d);const i=u(e.msg_id);return i&&t.push(`[[message_id:${i}]]`),{text:t.filter(Boolean).join(`
|
|
4
|
+
|
|
5
|
+
`),contextIds:n,currentMessageId:i}}function E(e){let r;return{text:e.replace(/\[\[quoted_message_id:([^\]\r\n]+)\]\]/g,(n,s)=>(r||(r=u(s)),"")),quotedMessageId:r}}function a(e){return e.replace(_,"").replace(g,"")}function u(e){return String(e??"").replace(/[\u0000\r\n\[\]]/g,"").trim().slice(0,256)||void 0}export{p as buildDshUserPrompt,E as extractQuotedMessageMarker};
|
|
File without changes
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createHash as s}from"node:crypto";const r=1,i=200,n=4e3,a=64e3;function t(e,o){return String(e??"").replaceAll("\0","").slice(0,o)}function d(e){return["[base-behavior]","You are a coding agent operating through Grix.","Work in the configured workspace. Verify material changes with relevant tests.","Keep answers concise and factual. Do not bypass workspace restrictions.","Never print DSML/XML tool markup (for example <||DSML||tool_calls>). Use native DSH tools instead.","[/base-behavior]","[aibot-system-prompt]",t(e.systemPrompt,a),"[/aibot-system-prompt]","[system-identity]",`Your name is ${JSON.stringify(t(e.agentName,i))}.`,`Your self-introduction: ${t(e.introduction,n)}`,"Do not quote or repeat this block.","[/system-identity]","[system-context]",`Your current Grix session_id is ${JSON.stringify(t(e.grixSessionId,256))}.`,`Your current Grix agent_id is ${JSON.stringify(t(e.agentId,256))}.`,"Use these identifiers only when a tool or protocol requires them. Do not acknowledge or repeat this block.","[/system-context]","[grix-message-protocol]","[[message_id:<id>]] and [[quoted_message_id:<id>]] are metadata.","Never repeat them as ordinary prose. Use [[quoted_message_id:<id>]] only when intentionally threading a reply.","[/grix-message-protocol]","[workspace-policy]","The workspace is file-sandboxed. A sandbox access-denied result is policy, not a command failure.","Do not attempt to bypass it. Operations outside the workspace cannot be interactively approved in this runtime.","[/workspace-policy]"].join(`
|
|
2
|
+
`)}function l(e){return{schemaVersion:r,sha256:s("sha256").update(e).digest("hex"),length:e.length}}export{r as DSH_SYSTEM_PROMPT_SCHEMA_VERSION,d as buildDshSystemPrompt,l as describeDshSystemPrompt};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class o{ttlMs;chain=Promise.resolve();cache=new Map;constructor(e=10*6e4){this.ttlMs=e}run(e,s){const t=this.cache.get(e);if(t&&t.expiresAt>Date.now())return Promise.resolve(t.value);const c=this.chain.then(s,s);return this.chain=c.then(()=>{},()=>{}),c.then(h=>{if(this.cache.set(e,{expiresAt:Date.now()+this.ttlMs,value:h}),this.cache.size>128){const i=Date.now();for(const[n,a]of this.cache)a.expiresAt<=i&&this.cache.delete(n);for(;this.cache.size>256;)this.cache.delete(this.cache.keys().next().value)}return h})}}export{o as DshActionCoordinator};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DEFAULT_DSH_PROFILE_NAME as s,dshProfileDisplayName as _}from"./profile-resolver.js";const h="approval",D=16384,a="deepseek-official",v=Object.freeze([{id:"deepseek-v4-flash",displayName:"DeepSeek-V4-Flash",contextWindow:1e6},{id:"deepseek-v4-pro",displayName:"DeepSeek-V4-Pro",contextWindow:1e6}]),l="standard",p=Object.freeze([{id:"standard",displayName:"\u6807\u51C6\u6A21\u5F0F",description:"\u529F\u80FD\u5B8C\u6574\u7684\u7F16\u7801 Agent\uFF0C\u652F\u6301\u6587\u4EF6\u7F16\u8F91\u3001Shell\u3001\u6587\u4EF6\u4E0E\u7F51\u9875\u68C0\u7D22\u3001Skills\u3001\u8BA1\u5212\u3001\u76EE\u6807\u3001\u5B50\u4EE3\u7406\u548C\u5DE5\u4F5C\u6D41\u3002"},{id:"code",displayName:"PTC \u6A21\u5F0F",description:"\u5177\u5907\u6807\u51C6\u6A21\u5F0F\u7684\u5168\u90E8\u80FD\u529B\uFF0C\u5E76\u901A\u8FC7 Code Mode SDK \u5448\u73B0\u5DE5\u5177\uFF0C\u8BA9\u6A21\u578B\u7528\u4E00\u4E2A TypeScript \u7A0B\u5E8F\u7EC4\u5408\u591A\u6B65\u64CD\u4F5C\u3002"},{id:"minimal",displayName:"\u6781\u7B80\u6A21\u5F0F",description:"\u4EC5\u63D0\u4F9B\u6301\u4E45 bash \u4E0E str_replace_editor \u7684\u53CC\u5DE5\u5177\u7F16\u7801 Agent\u3002"},{id:"cordis",displayName:"\u521B\u9020\u6A21\u5F0F",description:"\u7528\u4E8E\u521B\u5EFA\u81EA\u5B9A\u4E49 Agent preset\uFF1A\u5177\u5907\u6807\u51C6\u6A21\u5F0F\u7684\u5168\u90E8\u80FD\u529B\uFF0C\u5E76\u63D0\u4F9B\u8FD0\u884C\u65F6\u68C0\u67E5\u3001\u63D2\u4EF6\u5B9E\u9A8C\u548C preset \u521B\u4F5C\u6307\u5BFC\u3002"}]);function x(e){return Array.isArray(e)?e.flatMap(r=>{if(!r||typeof r!="object")return[];const i=r,t=String(i.id??"").trim();return t?[{id:t,displayName:String(i.displayName??i.name??t)}]:[]}):[]}function b(e){return Array.isArray(e)?e.flatMap(r=>{if(!r||typeof r!="object")return[];const i=r,t=String(i.id??"").trim();if(!t)return[];const d=Number(i.contextWindow);return[{id:t,displayName:String(i.displayName??i.name??t),contextWindow:Number.isSafeInteger(d)&&d>0?d:1e6}]}):[]}function A(e){return e.fetched!==void 0?b(e.fetched):e.providerChanged?[]:[...e.current]}function P(e){return Array.isArray(e)?e.flatMap(r=>{if(!r||typeof r!="object")return[];const i=r,t=String(i.id??"").trim();if(!t||i.broken)return[];const d=String(i.description??"").trim();return[{id:t,displayName:String(i.displayName??i.name??t),...d?{description:d}:{}}]}):[]}const c=Object.freeze([{id:s,displayName:_(s),webApp:!0}]);function k(e){return Array.isArray(e)?e.flatMap(r=>{if(!r||typeof r!="object")return[];const i=r,t=String(i.id??"").trim();return t?[{id:t,displayName:String(i.displayName??i.name??_(t)),...i.webApp===!0?{webApp:!0}:{}}]:[]}):[]}function f(e,r){const i=String(e??"").trim();return i&&r.some(t=>t.id===i)?i:r.some(t=>t.id===l)?l:r[0]?.id||l}function u(e,r){const i=String(e??"").trim();return i&&r.some(t=>t.id===i)?i:r.some(t=>t.id===a)?a:r[0]?.id||a}function N(e){const r=String(e.requestedProviderId??"").trim();if(!!r&&e.liveProviders.some(o=>o.id===r))return{providerId:r,persistFallback:!1};if(r)return{providerId:r,persistFallback:!1};const t=String(e.liveSelectedProvider??"").trim();return{providerId:u(t||void 0,e.liveProviders),persistFallback:!0}}function y(e,r,i){const t=String(r??"").trim(),d=e.length>0?[...e]:[];if(t&&!d.some(o=>o.id===t)){const o=i.find(n=>n.id===t);o&&d.unshift(o)}return d}function I(e){const r=e.applied,i=e.state??(r?r.appliedRevision===e.desired.revision?"applied":"pending":"applied"),t=e.runtimeReadiness??"unknown",d=e.providers??[],o=e.presets??p,n=u(e.desired.providerId,d),m=f(e.desired.agentPreset,o),g=r!=null||i==="pending"||i==="failed";return{provider_id:n,model_id:e.desired.modelId,mode_id:e.desired.modeId,agent_preset_id:m,agent_preset_locked:e.agentPresetLocked===!0,available_providers:[...d],available_models:[...e.models??v],available_presets:[...o],available_modes:[{id:"approval",label:"\u5BA1\u6279\uFF08\u5DE5\u4F5C\u533A\u5185\u81EA\u52A8\uFF0C\u8D8A\u754C\u5931\u8D25\uFF09"},{id:"full_auto",label:"\u81EA\u52A8\uFF08\u5168\u6743\u9650\uFF09"}],settings_revision:e.desired.revision,...g?{applied_provider_id:r?.providerId??null,applied_model_id:r?.modelId??null,applied_mode_id:r?.modeId??null,applied_settings_revision:r?.appliedRevision??null}:{},settings_state:i,settings_error_code:e.errorCode??null,context_window:e.contextWindow??null,provider_quota:e.providerQuota??null,dsh_integration_mode:e.integrationMode??"profile_bridge",dsh_profile:e.profileName??s,available_profiles:[...e.profiles??c],dsh_profile_locked:e.profileLocked===!0,dsh_profile_create:e.profileLocked!==!0&&e.profileCreate!==!1,dsh_plugins:[...e.plugins??[]],dsh_plugin_restart_required:e.pluginRestartRequired===!0,dsh_runtime_readiness:t,dsh_bridge_action_required:["dsh_missing","profile_missing","bridge_missing","bridge_update_required"].includes(t)?"install_bridge":t==="profile_restart_required"?"restart_profile":null,dsh_profile_restart_required:t==="profile_restart_required",dsh_bridge_capabilities:e.bridgeCapabilities??null}}function E(e){return e==="full_auto"?"danger-full-access":"workspace-write"}function L(e){return{agent_preset_id:f(e.agentPreset,p),agent_preset_locked:e.agentPresetLocked===!0,available_presets:[...p],dsh_profile:e.profileName??s,available_profiles:[...e.profiles??c],dsh_profile_locked:e.profileLocked===!0,dsh_profile_create:e.profileLocked!==!0,dsh_plugins:[...e.plugins??[]],dsh_plugin_restart_required:e.pluginRestartRequired===!0}}export{D as DEFAULT_DSH_MAX_TOKENS,h as DEFAULT_DSH_MODE,v as DEFAULT_DSH_MODELS,p as DEFAULT_DSH_PRESETS,l as DEFAULT_DSH_PRESET_ID,c as DEFAULT_DSH_PROFILES,a as DEFAULT_DSH_PROVIDER_ID,A as adoptDshProfileModels,N as adoptLiveDshProviderSelection,L as buildDshBindingToolbarMeta,I as buildDshToolbarMeta,b as normalizeDshModels,P as normalizeDshPresets,k as normalizeDshProfiles,x as normalizeDshProviders,E as permissionModeFor,f as resolveDshAgentPreset,u as resolveDshProviderId,y as retainRequestedDshProvider};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{finishReasonDetail as n,finishReasonKind as d}from"./event-mapper.js";class u{active;observedAdmissionIds=new Set;constructor(t){this.active=t}setPromptMessageId(t){this.active.messageId=t,this.observedAdmissionIds.has(t)&&(this.active.admitted=!0)}accept(t){const i=t.data??{};if(t.type==="agent/inbox/spliced"){const e=Array.isArray(i.inserted)?i.inserted:[];for(const s of e){if(!s||typeof s!="object")continue;const r=String(s.id??"");r&&(this.observedAdmissionIds.size<1024&&this.observedAdmissionIds.add(r),r===this.active.messageId&&(this.active.admitted=!0))}return!1}if(t.type==="user/message"&&String(i.id??"")===this.active.messageId){this.active.claimed=!0;const e=Number(t.turn??i.turn);return Number.isSafeInteger(e)&&(this.active.turn=e),!1}if(!this.active.claimed)return!1;const a=Number(t.turn??i.turn);if(this.active.turn!==void 0&&Number.isSafeInteger(a)&&a!==this.active.turn)return!1;if(t.type==="turn/end"){this.active.turnEnded=!0;const e=i.reason??t.reason;this.active.outcome=d(e),this.active.outcomeDetail=n(e)}return!0}markRootStatus(t){t==="idle"&&(this.active.rootIdle=!0)}get complete(){return this.active.admitted&&this.active.claimed&&this.active.turnEnded&&this.active.rootIdle}}export{u as TurnCorrelator};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{chmodSync as d,mkdirSync as T}from"node:fs";import{dirname as f}from"node:path";import{readJSONFile as _,writeJSONFileAtomic as y}from"../../core/util/json-file.js";const m=()=>({inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0}),n=t=>Number.isFinite(Number(t))?Math.max(0,Number(t)):0;function S(t){const e=t&&typeof t=="object"?t:{};return{inputTokens:n(e.inputTokens??e.input_tokens??e.prompt_tokens),outputTokens:n(e.outputTokens??e.output_tokens??e.completion_tokens),cacheReadInputTokens:n(e.cacheReadInputTokens??e.cacheReadTokens??e.cache_read_input_tokens??e.prompt_cache_hit_tokens),cacheCreationInputTokens:n(e.cacheCreationInputTokens??e.cacheWriteTokens??e.cache_creation_input_tokens??e.prompt_cache_miss_tokens),reasoningTokens:n(e.reasoningTokens??e.reasoning_tokens)}}class g{filePath;values=new Map;writePromise=Promise.resolve();constructor(e){this.filePath=e}load(){const e=_(this.filePath);if(!(!e||typeof e!="object"||Array.isArray(e)))for(const[a,s]of Object.entries(e))s?.sessionId&&this.values.set(a,s)}get(e){return this.values.get(e)??{sessionId:e,turns:0,total:m(),models:{},lastCommittedSeqByGeneration:{},updatedAt:0}}commit(e,a,s,u,l){const h=a,o=this.get(e);if((o.lastCommittedSeqByGeneration[h]??-1)>=s)return!1;const i=S(l),p=r=>{r.inputTokens+=i.inputTokens,r.outputTokens+=i.outputTokens,r.cacheReadInputTokens+=i.cacheReadInputTokens,r.cacheCreationInputTokens+=i.cacheCreationInputTokens};p(o.total);const c=o.models[u]??{turns:0,total:m()};return p(c.total),c.turns+=1,o.models[u]=c,o.turns+=1,o.lastCommittedSeqByGeneration[h]=s,o.updatedAt=Date.now(),this.values.set(e,o),this.scheduleWrite(),!0}delete(e){this.values.delete(e),this.scheduleWrite()}async flush(){await this.writePromise}scheduleWrite(){this.writePromise=this.writePromise.then(async()=>{T(f(this.filePath),{recursive:!0,mode:448}),await y(this.filePath,Object.fromEntries(this.values));try{d(this.filePath,384)}catch{}})}}const k=new Map;function I(t){let e=k.get(t);return e||(e=new g(t),e.load(),k.set(t,e)),e}export{g as DshSessionUsageStore,I as getDshSessionUsageStore,S as normalizeDshUsage};
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"bridgeVersion": "3.26.12",
|
|
4
|
+
"tarball": "grix-dsh-bridge-3.26.12.tgz",
|
|
5
|
+
"size": 11973,
|
|
6
|
+
"unpackedSize": 46345,
|
|
7
|
+
"shasum": "2ac050f4b6c4ea3e8f7da3b898521296c48fea9f",
|
|
8
|
+
"integrity": "sha512-uwyk3pTGCtaC3QuUKWR+mLrIfad3BNeK+hHzLNsQ69/V4a5UmQGlZirCZWJ5CS2EBYtJVw8YWrbgWicgl8X7Ww=="
|
|
9
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{closeSync as M,openSync as P,readSync as $}from"node:fs";import{referenceCaptureContent as z}from"../../core/content-reference.js";import{appendUniqueReference as x,assessToolCallCompleteness as B,deduplicateGaps as E}from"../../core/tool-call-audit.js";import{mapDshSessionEvent as U,unwrapDshSessionEvent as F}from"../../../adapter/deepseek-harness/event-mapper.js";import{normalizeDshUsage as H}from"../../../adapter/deepseek-harness/usage.js";const b=Object.freeze({inputOutput:!0,tools:!0,subagents:!0,thinking:!0,rawProviderBody:!1});function O(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function L(e){return e.options?.enabled===!0?e.options.capture:b}function N(e,t){return Number.isFinite(e)?new Date(e).toISOString():t}function D(e){if(typeof e=="string")return e;try{const t=JSON.stringify(e);return t===void 0?"null":t}catch{return String(e)}}function S(e,t){if(t.value!==void 0)return e.push(t),z(t)}class Y{provider="deepseek-harness";async collect(t){const c=String(t.boundary.wirePath??""),i=Number(t.boundary.wireStartOffset??0),s=Number(t.boundary.wireEndOffset??i);if(!c||!Number.isSafeInteger(i)||!Number.isSafeInteger(s)||s<i||s-i>32*1024*1024)return[];let a;try{a=P(c,"r")}catch{return[]}try{const p=Buffer.alloc(s-i),d=$(a,p,0,p.length,i);return p.subarray(0,d).toString("utf8").split(`
|
|
2
|
+
`).flatMap(r=>{if(!r.trim())return[];try{return[JSON.parse(r)]}catch{return[]}})}finally{M(a)}}async normalize(t,c){const i=Array.isArray(c)?c:[],s=L(t),a=[],p=[],d=new Map,r=`deepseek-harness:${t.turnId}:turn`,l=[J(t,r)],_=l[0];let u=1,A,g;const R=String(t.boundary.rootSessionId??"");s.inputOutput&&t.input&&x(_.inputRefs,S(a,{...t.input,captureLevel:t.input.captureLevel??"runtime_exact"})),s.inputOutput&&t.finalOutput&&x(_.outputRefs,S(a,{...t.finalOutput,captureLevel:t.finalOutput.captureLevel??"runtime_exact"}));for(const f of i){const v=f.frame??{},k=String(v.method??"");if(f.direction==="out"&&k==="session/prompt"){if(s.inputOutput){const o=O(v.params)?v.params:{},h=(Array.isArray(o.contentBlocks)?o.contentBlocks:[]).map(y=>O(y)?y:{}).filter(y=>y.type==="text").map(y=>String(y.text??"")).join("");x(_.inputRefs,S(a,{role:"user_input",format:"text",value:h,captureLevel:"runtime_exact"}))}continue}if(f.direction!=="in")continue;if(k==="subagent.started"||k==="subagent.finished"){const o=O(v.params)?v.params:{},m=String(o.childSessionId??o.sessionId??u);l.push(C(t,r,u++,"subagent",k,f.at,{nativeId:m})),k==="subagent.finished"&&s.subagents&&o.lastAssistantMessage!==void 0&&S(a,{role:"subagent_result",format:"text",value:String(o.lastAssistantMessage),captureLevel:"runtime_exact"});continue}if(k==="session.status"){const o=O(v.params)?v.params:{};l.push(C(t,r,u++,"agent",`session.status:${String(o.status??"unknown")}`,f.at,{nativeId:String(o.sessionId??u)}));continue}if(k!=="session.event")continue;const I=F(v.params);if(!I)continue;const n=U(I),T=String(I.sessionId??""),w=!!T&&!!R&&T!==R,q=N(f.at,t.startedAt);if(n.kind==="thinking"){s.thinking&&n.text&&S(a,{role:"thinking",format:"text",value:n.text,captureLevel:"runtime_exact"});continue}if(n.kind==="context"){const o=String(n.payload?.provider??""),m=String(n.payload?.model??"");o&&(g=o),m&&(A=m);continue}if(n.kind!=="usage"){if(n.kind==="text"&&n.payload?.committed){s.inputOutput&&!w&&n.text?x(_.outputRefs,S(a,{role:"assistant_text",format:"text",value:n.text,captureLevel:"runtime_exact"})):s.subagents&&w&&n.text&&S(a,{role:"subagent_result",format:"text",value:n.text,captureLevel:"runtime_exact"}),n.usage&&l.push(G(t,r,u++,f.at,n.usage,Number(I.seq??u),A,g));continue}if(n.kind==="tool_call"){const o=n.callId||String(u),m=n.name||"tool",h=C(t,r,u++,"tool_call",m,f.at,{nativeId:o,toolCallId:o});h.status="running",s.tools&&x(h.inputRefs,S(a,{role:"tool_arguments",format:typeof n.input=="string"?"text":"json",value:D(n.input??{}),captureLevel:"runtime_exact"})),d.set(o,{span:h}),l.push(h);continue}if(n.kind==="tool_result"){const o=n.callId||"",m=o?d.get(o):void 0;if(!m){p.push({code:"dsh_tool_result_without_call",message:`No tool/call found for ${o||`seq-${I.seq??u}`}`,providerIds:o?{toolCallId:o}:void 0});continue}m.span.status="completed",m.span.endedAt=q;const h=Date.parse(m.span.startedAt),y=Date.parse(q);Number.isFinite(h)&&Number.isFinite(y)&&(m.span.durationMs=Math.max(0,y-h)),s.tools&&x(m.span.outputRefs,S(a,{role:"tool_result",format:typeof n.output=="string"?"text":"json",value:D(n.output??""),captureLevel:"runtime_exact"}));continue}if(n.kind==="compaction"){l.push(C(t,r,u++,"compaction",String(n.payload?.eventType??I.type),f.at,{nativeId:String(I.seq??u)}));continue}(n.kind==="todo"||n.kind==="turn_end")&&l.push(C(t,r,u++,"agent",n.kind==="todo"?"todo/write":`turn/end:${n.reason??"completed"}`,f.at,{nativeId:String(I.seq??u)}))}}for(const[f,v]of d)v.span.status==="running"&&p.push({code:"dsh_tool_result_missing",message:`Tool call ${f} has no result`,spanId:v.span.spanId,providerIds:{toolCallId:f}});return{spans:l,contents:a,anomalies:p,capture:s,recordCount:i.length}}async correlate(t,c){return c}validate(t,c){const i=c,s=i.capture??L(t),a=i.spans.filter(g=>g.kind==="llm_request"),p=i.spans.filter(g=>g.kind==="tool_call"),d=!s.inputOutput||!!t.input||i.contents.some(g=>g.role==="user_input"),r=!s.inputOutput||!!t.finalOutput||i.contents.some(g=>g.role==="assistant_text"),l=B(p,s.tools),_=a.length>0&&a.every(g=>g.usage?.completeness==="complete"),u=E([...l.gaps]);s.rawProviderBody&&u.push({category:"raw_provider_body",reason:"raw_capture_disabled",detail:"Harness JSON-RPC does not expose provider HTTP raw bodies"});const A=d&&r&&l.complete&&_&&!s.rawProviderBody&&u.length===0;return{status:i.recordCount===0?"metadata_only":A?"complete":"partial",inputComplete:d,outputComplete:r,toolCallsComplete:l.complete,subagentsComplete:!0,usageComplete:_,rawRequestsComplete:!1,gaps:u}}}function J(e,t){return{spanId:t,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,kind:"turn",name:"DeepSeek Harness turn",sequence:0,status:e.outcome==="completed"?"completed":e.outcome==="cancelled"?"cancelled":"failed",startedAt:e.startedAt,endedAt:e.endedAt,inputRefs:[],outputRefs:[],provider:{provider:"deepseek-harness",nativeIds:{runtimeSessionId:String(e.boundary.runtimeSessionId??""),messageId:String(e.boundary.messageId??"")}},provenance:{source:"provider_event",accuracy:"runtime_exact"}}}function C(e,t,c,i,s,a,p){const d=N(a,e.startedAt);return{spanId:`deepseek-harness:${e.turnId}:${c}`,traceId:e.traceId,turnId:e.turnId,sessionId:e.sessionId,parentSpanId:t,kind:i,name:s,sequence:c,status:"completed",startedAt:d,endedAt:d,inputRefs:[],outputRefs:[],provider:{provider:"deepseek-harness",nativeEventType:s,nativeIds:p},provenance:{source:"provider_event",accuracy:"runtime_exact"}}}function G(e,t,c,i,s,a,p,d){const r=H(s),l={input:{total:r.inputTokens,uncached:null,cacheRead:r.cacheReadInputTokens,cacheWrite:r.cacheCreationInputTokens,other:null},output:{total:r.outputTokens,reasoning:r.reasoningTokens,visible:Math.max(0,r.outputTokens-r.reasoningTokens)},totalProcessed:r.inputTokens+r.outputTokens,requestCount:1,accuracy:"provider_reported",completeness:"complete",provider:"deepseek-harness",providerUsageRaw:s,normalization:{adapter:"deepseek-harness-jsonrpc",version:1,formula:"provider committed assistant/message usage"}};return{...C(e,t,c,"llm_request","assistant/message",i,{nativeId:String(a),requestId:String(a),...p?{model:p}:{},...d?{providerId:d}:{}}),...p?{modelId:p}:{},usage:l}}export{Y as DeepSeekHarnessAuditAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AUDIT_ERROR_CODES as d}from"./types.js";const u=new Set(["claude","codex","acp","pi","codewhale","cursor","opencode"]);class s extends Error{code=d.turnScopeUnsupported;constructor(r){super(`Turn-scoped audit is not supported for provider ${r}`),this.name="AuditTurnScopeUnsupportedError"}}class t extends Error{code=d.preparationFailed;constructor(r){super(`Audit turn preparation failed: ${r}`),this.name="AuditPreparationFailedError"}}function a(e){if(!u.has(e))throw new s(e)}function
|
|
1
|
+
import{AUDIT_ERROR_CODES as d}from"./types.js";const u=new Set(["claude","codex","acp","pi","codewhale","cursor","opencode","deepseek-harness"]);class s extends Error{code=d.turnScopeUnsupported;constructor(r){super(`Turn-scoped audit is not supported for provider ${r}`),this.name="AuditTurnScopeUnsupportedError"}}class t extends Error{code=d.preparationFailed;constructor(r){super(`Audit turn preparation failed: ${r}`),this.name="AuditPreparationFailedError"}}function a(e){if(!u.has(e))throw new s(e)}function n(e,r){return{event_id:e.eventId,session_id:e.sessionId,state:e.state,...e.msgId===void 0?{}:{msg_id:e.msgId},...e.auditId===void 0?{}:{audit_id:e.auditId},...e.turnId===void 0?{}:{turn_id:e.turnId},...e.revision===void 0?{}:{revision:e.revision},...e.quality===void 0?{}:{quality:e.quality},...e.truncated===void 0?{}:{truncated:e.truncated},...e.errorCode===void 0?{}:{error_code:e.errorCode},...e.errorMessage===void 0?{}:{error_message:e.errorMessage},updated_at:r}}export{t as AuditPreparationFailedError,s as AuditTurnScopeUnsupportedError,u as TURN_SCOPE_SUPPORTED_PROVIDERS,a as assertTurnScopeSupported,n as buildAuditStatePayload};
|