@lqc123qwe/car-runtime 1.15.1 → 1.16.0

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/SHA256SUMS CHANGED
@@ -1 +1 @@
1
- 48c5733414a7f4027eb441a35b4db0f911b5a8b81d889ad212840401d8e2b752 car-runtime-1.15.1.tgz
1
+ fe50cba2f8b8eb9846eb19bae11362cde6134b6e30ce71992c70d77a5e962488 car-runtime-1.16.0.tgz
Binary file
@@ -0,0 +1 @@
1
+ {"base64Signature":"MEUCIADexj3Cyb9dBLWoNp6RTMBXhMCkdJEBbSTHwY4A/uJFAiEAxTXSfDSa6xRLw1SRb8c8qKczOyEXlLEm4yIEN8P8CJA=","cert":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUc1ekNDQm0yZ0F3SUJBZ0lVUHJJdVl0L1R1dkh3UThwbE5xcitEaXUvVCtvd0NnWUlLb1pJemowRUF3TXcKTnpFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUjR3SEFZRFZRUURFeFZ6YVdkemRHOXlaUzFwYm5SbApjbTFsWkdsaGRHVXdIaGNOTWpZeE1ESTBNRGN6TURNeFdoY05Nall4TURJME1EYzBNRE14V2pBQU1Ga3dFd1lICktvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUU1ODhCbTJ3MU5YRUkyTXg0L3hFb0hiNVNjeGNMZW1UZTNHdU0KRHNJeU1PSkVtTXN6NkIxWFVVYnk0UVdQZ29XYmd2STN0Mmw2WGVRdjNLMVVGS09YbzZPQ0JZd3dnZ1dJTUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREF6QWZCZ05WSFNNRUdEQVdnQlRmCjArblBWaVFSbHZtbzJPa29WYUxHTGhoa1B6QmlCZ05WSFJFQkFmOEVXREJXaGxSb2RIUndjem92TDJkcGRHaDEKWWk1amIyMHZiSEZqTmpJMEwyTmhjaTF5ZFc1MGFXMWxMeTVuYVhSb2RXSXZkMjl5YTJac2IzZHpMM0psYkdWaApjMlV1ZVcxc1FISmxabk12ZEdGbmN5OHhMakUyTGpBd09RWUtLd1lCQkFHRHZ6QUJBUVFyYUhSMGNITTZMeTkwCmIydGxiaTVoWTNScGIyNXpMbWRwZEdoMVluVnpaWEpqYjI1MFpXNTBMbU52YlRBVkJnb3JCZ0VFQVlPL01BRUMKQkFkeVpXeGxZWE5sTURZR0Npc0dBUVFCZzc4d0FRTUVLR000WmpZME56WTJaakE1TlRVeU9EVTBPVEV4T1RsawpOakprWVdVd05qTmtZalEzWkRrNE5qZ3dGUVlLS3dZQkJBR0R2ekFCQkFRSGNtVnNaV0Z6WlRBZ0Jnb3JCZ0VFCkFZTy9NQUVGQkJKc2NXTTJNalF2WTJGeUxYSjFiblJwYldVd0hnWUtLd1lCQkFHRHZ6QUJCZ1FRY21WbWN5OTAKWVdkekx6RXVNVFl1TURBN0Jnb3JCZ0VFQVlPL01BRUlCQzBNSzJoMGRIQnpPaTh2ZEc5clpXNHVZV04wYVc5dQpjeTVuYVhSb2RXSjFjMlZ5WTI5dWRHVnVkQzVqYjIwd1pBWUtLd1lCQkFHRHZ6QUJDUVJXREZSb2RIUndjem92CkwyZHBkR2gxWWk1amIyMHZiSEZqTmpJMEwyTmhjaTF5ZFc1MGFXMWxMeTVuYVhSb2RXSXZkMjl5YTJac2IzZHoKTDNKbGJHVmhjMlV1ZVcxc1FISmxabk12ZEdGbmN5OHhMakUyTGpBd09BWUtLd1lCQkFHRHZ6QUJDZ1FxRENoagpPR1kyTkRjMk5tWXdPVFUxTWpnMU5Ea3hNVGs1WkRZeVpHRmxNRFl6WkdJME4yUTVPRFk0TUIwR0Npc0dBUVFCCmc3OHdBUXNFRHd3TloybDBhSFZpTFdodmMzUmxaREExQmdvckJnRUVBWU8vTUFFTUJDY01KV2gwZEhCek9pOHYKWjJsMGFIVmlMbU52YlM5c2NXTTJNalF2WTJGeUxYSjFiblJwYldVd09BWUtLd1lCQkFHRHZ6QUJEUVFxRENoagpPR1kyTkRjMk5tWXdPVFUxTWpnMU5Ea3hNVGs1WkRZeVpHRmxNRFl6WkdJME4yUTVPRFk0TUNBR0Npc0dBUVFCCmc3OHdBUTRFRWd3UWNtVm1jeTkwWVdkekx6RXVNVFl1TURBYUJnb3JCZ0VFQVlPL01BRVBCQXdNQ2pFek5qRXgKT1RJM01UUXdLUVlLS3dZQkJBR0R2ekFCRUFRYkRCbG9kSFJ3Y3pvdkwyZHBkR2gxWWk1amIyMHZiSEZqTmpJMApNQmdHQ2lzR0FRUUJnNzh3QVJFRUNnd0lOamt5TXpRMU5qUXdaQVlLS3dZQkJBR0R2ekFCRWdSV0RGUm9kSFJ3CmN6b3ZMMmRwZEdoMVlpNWpiMjB2YkhGak5qSTBMMk5oY2kxeWRXNTBhVzFsTHk1bmFYUm9kV0l2ZDI5eWEyWnMKYjNkekwzSmxiR1ZoYzJVdWVXMXNRSEpsWm5NdmRHRm5jeTh4TGpFMkxqQXdPQVlLS3dZQkJBR0R2ekFCRXdRcQpEQ2hqT0dZMk5EYzJObVl3T1RVMU1qZzFORGt4TVRrNVpEWXlaR0ZsTURZelpHSTBOMlE1T0RZNE1CY0dDaXNHCkFRUUJnNzh3QVJRRUNRd0hjbVZzWldGelpUQlpCZ29yQmdFRUFZTy9NQUVWQkVzTVNXaDBkSEJ6T2k4dloybDAKYUhWaUxtTnZiUzlzY1dNMk1qUXZZMkZ5TFhKMWJuUnBiV1V2WVdOMGFXOXVjeTl5ZFc1ekx6UXdNRGMwTXprMQpOelkwTDJGMGRHVnRjSFJ6THpFd0ZnWUtLd1lCQkFHRHZ6QUJGZ1FJREFad2RXSnNhV013VUFZS0t3WUJCQUdECnZ6QUJHQVJDREVCeVpYQnZPbXh4WXpZeU5FQTJPVEl6TkRVMk5DOWpZWEl0Y25WdWRHbHRaVUF4TXpZeE1Ua3kKTnpFME9uSmxaanB5WldaekwzUmhaM012TVM0eE5pNHdNSUdLQmdvckJnRUVBZFo1QWdRQ0JId0VlZ0I0QUhZQQozVDB3YXNiSEVUSmpHUjRjbVdjM0FxSktYcmplUEszL2g0cHlnQzhwN280QUFBR2hiTkdCR1FBQUJBTUFSekJGCkFpQkJqUE1ydndKRUtLRUd2V0ljZXdGRncrU09GWmlaVXhvdlJENllDWEhoTmdJaEFQL295c2VCVU1jamxKSXMKcjFOT0Fvd1VlRXlwS3QvTmgycUlOY0tucHRFNk1Bb0dDQ3FHU000OUJBTURBMmdBTUdVQ01RQ3gwOVAvV3JhbgpCZThNdExSVjUyNlJtYis0aGoyRU5QS3NwUkRDYmcyRm9zWTFIYzlaRFhvMlFtRTdWckRQRFZRQ01EckR4VkVNClM4Y2k5UkxKelpNU0JHV2Fjak80Y2hrYVZGU3k3a3F0SjcxZnRSY2trTm82b0czR2ZGM2Fsc2xsd2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==","rekorBundle":{"SignedEntryTimestamp":"MEQCIDot8LHVF9v+mf3Fin/ylZudExwX87RgRfaNfyoRQ0GBAiBcYNkPTfERvsHWvfSMeSTgpe+6SHGlXnFN6rBNBj1VCw==","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJmZTUwY2JhMmY4YjhlYjk4NDZlYjE5YmFlMTEzNjJjZGU2MTM0YjZlMzBjZTcxOTkyYzcwZDc3YTVlOTYyNDg4In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJQURleGozQ3liOWRCTFdvTnA2UlRNQlhoTUNrZEpFQmJTVEh3WTRBL3VKRkFpRUF4VFhTZkRTYTZ4Ukx3MVNSYjhjOHFLY3pPeUVYbExFbTR5SUVOOFA4Q0pBPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVYzFla05EUW0weVowRjNTVUpCWjBsVlVISkpkVmwwTDFSMWRraDNVVGh3YkU1eGNpdEVhWFV2VkN0dmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFplRTFFU1RCTlJHTjZUVVJOZUZkb1kwNU5hbGw0VFVSSk1FMUVZekJOUkUxNFYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVUxT0RoQ2JUSjNNVTVZUlVreVRYZzBMM2hGYjBoaU5WTmplR05NWlcxVVpUTkhkVTBLUkhOSmVVMVBTa1Z0VFhONk5rSXhXRlZWWW5rMFVWZFFaMjlYWW1kMlNUTjBNbXcyV0dWUmRqTkxNVlZHUzA5WWJ6WlBRMEpaZDNkbloxZEpUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXWkNaMDVXU0ZOTlJVZEVRVmRuUWxSbUNqQXJibEJXYVZGU2JIWnRiekpQYTI5V1lVeEhUR2hvYTFCNlFtbENaMDVXU0ZKRlFrRm1PRVZYUkVKWGFHeFNiMlJJVW5kamVtOTJUREprY0dSSGFERUtXV2sxYW1JeU1IWmlTRVpxVG1wSk1Fd3lUbWhqYVRGNVpGYzFNR0ZYTVd4TWVUVnVZVmhTYjJSWFNYWmtNamw1WVRKYWMySXpaSHBNTTBwc1lrZFdhQXBqTWxWMVpWY3hjMUZJU214YWJrMTJaRWRHYm1ONU9IaE1ha1V5VEdwQmQwOVJXVXRMZDFsQ1FrRkhSSFo2UVVKQlVWRnlZVWhTTUdOSVRUWk1lVGt3Q21JeWRHeGlhVFZvV1ROU2NHSXlOWHBNYldSd1pFZG9NVmx1Vm5wYVdFcHFZakkxTUZwWE5UQk1iVTUyWWxSQlZrSm5iM0pDWjBWRlFWbFBMMDFCUlVNS1FrRmtlVnBYZUd4WldFNXNUVVJaUjBOcGMwZEJVVkZDWnpjNGQwRlJUVVZMUjAwMFdtcFpNRTU2V1RKYWFrRTFUbFJWZVU5RVZUQlBWRVY0VDFSc2F3cE9ha3ByV1ZkVmQwNXFUbXRaYWxFeldrUnJORTVxWjNkR1VWbExTM2RaUWtKQlIwUjJla0ZDUWtGUlNHTnRWbk5hVjBaNldsUkJaMEpuYjNKQ1owVkZDa0ZaVHk5TlFVVkdRa0pLYzJOWFRUSk5hbEYyV1RKR2VVeFlTakZpYmxKd1lsZFZkMGhuV1V0TGQxbENRa0ZIUkhaNlFVSkNaMUZSWTIxV2JXTjVPVEFLV1Zka2VreDZSWFZOVkZsMVRVUkJOMEpuYjNKQ1owVkZRVmxQTDAxQlJVbENRekJOU3pKb01HUklRbnBQYVRoMlpFYzVjbHBYTkhWWlYwNHdZVmM1ZFFwamVUVnVZVmhTYjJSWFNqRmpNbFo1V1RJNWRXUkhWblZrUXpWcVlqSXdkMXBCV1V0TGQxbENRa0ZIUkhaNlFVSkRVVkpYUkVaU2IyUklVbmRqZW05MkNrd3laSEJrUjJneFdXazFhbUl5TUhaaVNFWnFUbXBKTUV3eVRtaGphVEY1WkZjMU1HRlhNV3hNZVRWdVlWaFNiMlJYU1haa01qbDVZVEphYzJJelpIb0tURE5LYkdKSFZtaGpNbFYxWlZjeGMxRklTbXhhYmsxMlpFZEdibU41T0hoTWFrVXlUR3BCZDA5QldVdExkMWxDUWtGSFJIWjZRVUpEWjFGeFJFTm9hZ3BQUjFreVRrUmpNazV0V1hkUFZGVXhUV3BuTVU1RWEzaE5WR3MxV2tSWmVWcEhSbXhOUkZsNldrZEpNRTR5VVRWUFJGazBUVUl3UjBOcGMwZEJVVkZDQ21jM09IZEJVWE5GUkhkM1Rsb3liREJoU0ZacFRGZG9kbU16VW14YVJFRXhRbWR2Y2tKblJVVkJXVTh2VFVGRlRVSkRZMDFLVjJnd1pFaENlazlwT0hZS1dqSnNNR0ZJVm1sTWJVNTJZbE01YzJOWFRUSk5hbEYyV1RKR2VVeFlTakZpYmxKd1lsZFZkMDlCV1V0TGQxbENRa0ZIUkhaNlFVSkVVVkZ4UkVOb2FncFBSMWt5VGtSak1rNXRXWGRQVkZVeFRXcG5NVTVFYTNoTlZHczFXa1JaZVZwSFJteE5SRmw2V2tkSk1FNHlVVFZQUkZrMFRVTkJSME5wYzBkQlVWRkNDbWMzT0hkQlVUUkZSV2QzVVdOdFZtMWplVGt3V1Zka2VreDZSWFZOVkZsMVRVUkJZVUpuYjNKQ1owVkZRVmxQTDAxQlJWQkNRWGROUTJwRmVrNXFSWGdLVDFSSk0wMVVVWGRMVVZsTFMzZFpRa0pCUjBSMmVrRkNSVUZSWWtSQ2JHOWtTRkozWTNwdmRrd3laSEJrUjJneFdXazFhbUl5TUhaaVNFWnFUbXBKTUFwTlFtZEhRMmx6UjBGUlVVSm5OemgzUVZKRlJVTm5kMGxPYW10NVRYcFJNVTVxVVhkYVFWbExTM2RaUWtKQlIwUjJla0ZDUldkU1YwUkdVbTlrU0ZKM0NtTjZiM1pNTW1Sd1pFZG9NVmxwTldwaU1qQjJZa2hHYWs1cVNUQk1NazVvWTJreGVXUlhOVEJoVnpGc1RIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTUtZak5rZWt3elNteGlSMVpvWXpKVmRXVlhNWE5SU0Vwc1dtNU5kbVJIUm01amVUaDRUR3BGTWt4cVFYZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JYZFJjUXBFUTJocVQwZFpNazVFWXpKT2JWbDNUMVJWTVUxcVp6Rk9SR3Q0VFZSck5WcEVXWGxhUjBac1RVUlplbHBIU1RCT01sRTFUMFJaTkUxQ1kwZERhWE5IQ2tGUlVVSm5OemgzUVZKUlJVTlJkMGhqYlZaeldsZEdlbHBVUWxwQ1oyOXlRbWRGUlVGWlR5OU5RVVZXUWtWelRWTlhhREJrU0VKNlQyazRkbG95YkRBS1lVaFdhVXh0VG5aaVV6bHpZMWROTWsxcVVYWlpNa1o1VEZoS01XSnVVbkJpVjFWMldWZE9NR0ZYT1hWamVUbDVaRmMxZWt4NlVYZE5SR013VFhwck1RcE9lbGt3VERKR01HUkhWblJqU0ZKNlRIcEZkMFpuV1V0TGQxbENRa0ZIUkhaNlFVSkdaMUZKUkVGYWQyUlhTbk5oVjAxM1ZVRlpTMHQzV1VKQ1FVZEVDblo2UVVKSFFWSkRSRVZDZVZwWVFuWlBiWGg0V1hwWmVVNUZRVEpQVkVsNlRrUlZNazVET1dwWldFbDBZMjVXZFdSSGJIUmFWVUY0VFhwWmVFMVVhM2tLVG5wRk1FOXVTbXhhYW5CNVdsZGFla3d6VW1oYU0wMTJUVk0wZUU1cE5IZE5TVWRMUW1kdmNrSm5SVVZCWkZvMVFXZFJRMEpJZDBWbFowSTBRVWhaUVFvelZEQjNZWE5pU0VWVVNtcEhValJqYlZkak0wRnhTa3RZY21wbFVFc3pMMmcwY0hsblF6aHdOMjgwUVVGQlIyaGlUa2RDUjFGQlFVSkJUVUZTZWtKR0NrRnBRa0pxVUUxeWRuZEtSVXRMUlVkMlYwbGpaWGRHUm5jclUwOUdXbWxhVlhodmRsSkVObGxEV0Vob1RtZEphRUZRTDI5NWMyVkNWVTFqYW14S1NYTUtjakZPVDBGdmQxVmxSWGx3UzNRdlRtZ3ljVWxPWTB0dWNIUkZOazFCYjBkRFEzRkhVMDAwT1VKQlRVUkJNbWRCVFVkVlEwMVJRM2d3T1ZBdlYzSmhiZ3BDWlRoTmRFeFNWalV5TmxKdFlpczBhR295UlU1UVMzTndVa1JEWW1jeVJtOXpXVEZJWXpsYVJGaHZNbEZ0UlRkV2NrUlFSRlpSUTAxRWNrUjRWa1ZOQ2xNNFkyazVVa3hLZWxwTlUwSkhWMkZqYWs4MFkyaHJZVlpHVTNrM2EzRjBTamN4Wm5SU1kydHJUbTgyYjBjelIyWkdNMkZzYzJ4c2QyYzlQUW90TFMwdExVVk9SQ0JEUlZKVVNVWkpRMEZVUlMwdExTMHRDZz09In19fX0=","integratedTime":1792827032,"logIndex":3437295368,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}}
package/dist/cli.js CHANGED
@@ -63,8 +63,9 @@ const HELP = `用法: car <command> [args]
63
63
  CAR_UNSIGNED_ALLOW=1 显式声明豁免(warn 缺签路径计数 confirmed=yes,横幅保留)
64
64
  配置文件通道(1.5 起双载体):cwd car.config.ts(export default {…};发现序 ts > json)或
65
65
  car.config.json 或 --config <path>;键位 sandbox.unsigned.allow / sandbox.sig.enforce /
66
- sandbox.sig.trustRoot / llm.* / llm.modelPool.*(多端点 fallback:endpoints id/baseUrl/model/
67
- adapterId/keyEnv/priority/weight/maxTokens + probe + maxAttempts;路由决策落链)/ mcp.servers.*
66
+ sandbox.sig.trustRoot / llm.* / modelPool.*(多端点 fallback:endpoints id/baseUrl/model/
67
+ adapterId/keyEnv/priority/weight/maxTokens + probe + maxAttempts;路由决策落链)/ llm.subagent.*
68
+ (子 Agent:model 独立锚点 / maxConcurrent / maxCumulative 护栏上限)/ mcp.servers.*
68
69
  (stdio: command/args/env;远程: url/headers,\${ENV_VAR} 引用注入凭据);优先级 flag > env > 配置 > 缺省;未知键 fail-visible`;
69
70
  // 进程内热重载会话(ReloadManager 持有 epoch 与实例注册表;同进程连续 reload 语义完整)
70
71
  let reloadMgrPromise;
@@ -244,7 +245,7 @@ async function main() {
244
245
  console.error('CAR-E-LLM-CONFIG: 真实模型路径需要 baseUrl + model——');
245
246
  console.error(' 配置:car.config.ts(export default)或 car.config.json {"llm":{"baseUrl":"https://…","model":"…"}} / env CAR_LLM_BASE_URL+CAR_LLM_MODEL / flag --base-url --model');
246
247
  console.error(' anthropic:llm.adapterId "anthropic"(或 --adapter-id anthropic)+ baseUrl https://api.anthropic.com;凭据 ANTHROPIC_API_KEY');
247
- console.error(' 模型池:llm.modelPool.endpoints(多端点 fallback + health 预检;凭据 keyEnv 引用;路由决策落链)');
248
+ console.error(' 模型池:modelPool.endpoints(多端点 fallback + health 预检;凭据 keyEnv 引用;路由决策落链)');
248
249
  console.error(' 凭据:OPENAI_API_KEY / ANTHROPIC_API_KEY(env fallback 需 CAR_ALLOW_ENV_CREDENTIALS=1 或 llm.allowEnvFallback)或 keychain;诊断:car doctor');
249
250
  return 2;
250
251
  }
@@ -21,6 +21,17 @@ export interface LlmConfig {
21
21
  allowEnvFallback?: boolean;
22
22
  /** 1.14-S2(K-MP-2 / D-40):历史压缩策略(阈值自动触发判定入参;立即压缩 API 独立可用) */
23
23
  compaction?: CompactionConfig;
24
+ /** 1.16-K3(D-K2-2):子 Agent 配置(缺省 = 继承父会话模型锚点 Q-A2 + 宿主护栏常量 Q-A3) */
25
+ subagent?: SubagentConfig;
26
+ }
27
+ /** 1.16-K3(D-K2-2):子 Agent 配置面——宿主编排消费(内核自身不装配编排;schema 只登记键位) */
28
+ export interface SubagentConfig {
29
+ /** 独立子模型锚点(缺省 = 继承父会话现值;modelPool 激活时被池压过——与 llm.model 同口径) */
30
+ model?: string;
31
+ /** 并发子 Agent 上限(正整数;缺省 = 宿主常量 3,Q-A3) */
32
+ maxConcurrent?: number;
33
+ /** 单父会话累计派生上限(正整数;缺省 = 宿主常量 10,Q-A3) */
34
+ maxCumulative?: number;
24
35
  }
25
36
  /** 1.14-S4(K-POOL-1 / D-42):模型池端点登记(多端点 fallback 候选;凭据仅收 keyEnv 引用) */
26
37
  export interface ModelPoolEndpointSpec {
@@ -133,6 +133,18 @@ const rawSchema = z.object({
133
133
  protectLastTurns: z.number({ invalid_type_error: '必须为正整数', required_error: '必须为正整数' })
134
134
  .refine(v => Number.isInteger(v) && v > 0, { message: '必须为正整数' }).optional(),
135
135
  }).strict().optional(),
136
+ // 1.16-K3(D-K2-2):子 Agent 配置(model 独立锚点 + 护栏上限;空对象无意义显式拒——禁静默 no-op)
137
+ subagent: z.object({
138
+ model: nonEmptyTrimmed().optional(),
139
+ maxConcurrent: z.number({ invalid_type_error: '必须为正整数', required_error: '必须为正整数' })
140
+ .refine(v => Number.isFinite(v) && Number.isInteger(v) && v > 0, { message: '必须为正整数' })
141
+ .optional(),
142
+ maxCumulative: z.number({ invalid_type_error: '必须为正整数', required_error: '必须为正整数' })
143
+ .refine(v => Number.isFinite(v) && Number.isInteger(v) && v > 0, { message: '必须为正整数' })
144
+ .optional(),
145
+ }).strict()
146
+ .refine(v => Object.keys(v).length > 0, { message: '至少登记一个键(model/maxConcurrent/maxCumulative;无子 Agent 配置需求请移除 llm.subagent 键,行为与 1.15.2 一致)' })
147
+ .optional(),
136
148
  }).strict().optional(),
137
149
  // 1.14-S4(K-POOL-1 / D-42):模型池登记(多端点 fallback + health + routing/decide 落链)
138
150
  modelPool: modelPoolSchema.optional(),
@@ -140,8 +152,8 @@ const rawSchema = z.object({
140
152
  servers: z.record(z.string(), mcpServerSchema, { invalid_type_error: '必须为对象(serverId → 启动规格)' }),
141
153
  }).strict().optional(),
142
154
  }, { invalid_type_error: '配置顶层必须为 JSON 对象' }).strict();
143
- /** 未登记键提示(渲染层拼 path)——与系统设计键位空间同步 */
144
- const KEY_SPACES = '登记键位:sandbox.* / llm.* / llm.modelPool.* / mcp.servers.*';
155
+ /** 未登记键提示(渲染层拼 path)——与系统设计键位空间同步;D-1 勘误:modelPool 为顶层键(非 llm.modelPool) */
156
+ const KEY_SPACES = '登记键位:sandbox.* / llm.* / modelPool.* / llm.subagent.* / mcp.servers.*';
145
157
  /** zod issue → CAR-E-CONFIG 渲染(首个 issue;unrecognized_keys 按键路径展开) */
146
158
  function renderIssue(error) {
147
159
  const iss = error.issues[0];
@@ -194,6 +206,16 @@ function parseCarConfig(raw) {
194
206
  cp.protectLastTurns = d.llm.compaction.protectLastTurns;
195
207
  llm.compaction = cp;
196
208
  }
209
+ if (d.llm.subagent) {
210
+ const sg = {};
211
+ if (d.llm.subagent.model !== undefined)
212
+ sg.model = d.llm.subagent.model;
213
+ if (d.llm.subagent.maxConcurrent !== undefined)
214
+ sg.maxConcurrent = d.llm.subagent.maxConcurrent;
215
+ if (d.llm.subagent.maxCumulative !== undefined)
216
+ sg.maxCumulative = d.llm.subagent.maxCumulative;
217
+ llm.subagent = sg;
218
+ }
197
219
  out.llm = llm;
198
220
  }
199
221
  if (d.mcp) {
@@ -24,7 +24,9 @@ export interface MemoryEventPayload {
24
24
  export declare class MemoryStore {
25
25
  #private;
26
26
  readonly dir: string;
27
- constructor(dir: string);
27
+ constructor(dir: string, opts?: {
28
+ now?: () => number;
29
+ });
28
30
  /** 列出全部记忆(updatedAt 降序——最近维护优先);坏文件显式拒绝(带病不静默,loadSessionLog 同纪律) */
29
31
  list(): MemoryEntry[];
30
32
  get(id: string): MemoryEntry | undefined;
@@ -38,8 +38,11 @@ function assertValidId(id) {
38
38
  }
39
39
  export class MemoryStore {
40
40
  dir;
41
- constructor(dir) {
41
+ /** 时钟缝(1.15.2 测试可观测性):缺省 Date.now;spec 注入受控时钟消除同毫秒排序竞态 */
42
+ #now;
43
+ constructor(dir, opts) {
42
44
  this.dir = dir;
45
+ this.#now = opts?.now ?? Date.now;
43
46
  mkdirSync(dir, { recursive: true });
44
47
  }
45
48
  #file(id) {
@@ -100,7 +103,7 @@ export class MemoryStore {
100
103
  if (this.get(id)) {
101
104
  throw new Error(`CAR-E-MEM-EXISTS: 记忆 "${id}" 已存在(write 冲突 fail-visible——修改请走 edit)`);
102
105
  }
103
- const now = Date.now();
106
+ const now = this.#now();
104
107
  const entry = { id, text: input.text, createdAt: now, updatedAt: now };
105
108
  if (input.tags?.length)
106
109
  entry.tags = [...input.tags];
@@ -126,7 +129,7 @@ export class MemoryStore {
126
129
  }
127
130
  // tags 语义:undefined = 不变(payload 不带键,重放取前态);数组 = 整体替换(含空数组 =
128
131
  // 清空,payload 恒带键——重放 [] 与清空同构,禁「带键/缺键」二义)
129
- const next = { ...prev, text, updatedAt: Date.now() };
132
+ const next = { ...prev, text, updatedAt: this.#now() };
130
133
  if (tags !== undefined) {
131
134
  const { tags: _drop, ...rest } = next;
132
135
  void _drop;
@@ -191,7 +194,7 @@ export class MemoryStore {
191
194
  });
192
195
  try {
193
196
  if (target.present) {
194
- const entry = { id, text: target.text, createdAt: target.createdAt, updatedAt: Date.now() };
197
+ const entry = { id, text: target.text, createdAt: target.createdAt, updatedAt: this.#now() };
195
198
  if (target.tags?.length)
196
199
  entry.tags = [...target.tags];
197
200
  if (target.sourceSession)
@@ -1,4 +1,4 @@
1
- {"stage":"archive","detail":"git archive HEAD → car-runtime-1.15.1.tgz(393531 bytes,树哈希锚定)","ts":1792393347695}
2
- {"stage":"sha256sums","detail":"SHA256SUMS 48c5733414a7f402…(裸字节复核通过)","ts":1792393347696}
3
- {"stage":"sbom","detail":"55 个组件(运行时依赖 0 项)","ts":1792393347703}
4
- {"stage":"cosign-keyless","detail":"signed car-runtime-1.15.1.tgz (keyless OIDC + Rekor)","ts":1792393349141}
1
+ {"stage":"archive","detail":"git archive HEAD → car-runtime-1.16.0.tgz(398072 bytes,树哈希锚定)","ts":1792827030875}
2
+ {"stage":"sha256sums","detail":"SHA256SUMS fe50cba2f8b8eb98…(裸字节复核通过)","ts":1792827030876}
3
+ {"stage":"sbom","detail":"55 个组件(运行时依赖 0 项)","ts":1792827030883}
4
+ {"stage":"cosign-keyless","detail":"signed car-runtime-1.16.0.tgz (keyless OIDC + Rekor)","ts":1792827034321}
@@ -164,6 +164,11 @@ const nodeHttpSseFetch = (url, init = {}) => new Promise((resolve, reject) => {
164
164
  const mod = u.protocol === 'https:' ? httpsRequest : httpRequest;
165
165
  const req = mod(u, { method: init.method ?? 'GET', headers: init.headers }, res => {
166
166
  const status = res.statusCode ?? 0;
167
+ // 1.15.2-BUG(桌面 S6 终验实证):取消时 req.destroy(err) 会让**响应流** res 异步 emit
168
+ // 'error'——此前无监听 → Node 抛 unhandled 'error' 事件 → 宿主进程直接退出(Electron
169
+ // utilityProcess 无 uncaughtException 兜底时 = 句柄全失、引导队列被 resume 误标 interrupted)。
170
+ // 迭代器侧已由 streamSsePost 的 catch 按 D-19 静默收口,此处监听仅防进程级未捕获异常
171
+ res.on('error', () => { });
167
172
  resolve({
168
173
  ok: status >= 200 && status < 300,
169
174
  status,
@@ -176,8 +181,13 @@ const nodeHttpSseFetch = (url, init = {}) => new Promise((resolve, reject) => {
176
181
  body: res,
177
182
  });
178
183
  });
184
+ // 1.15.2-BUG(桌面 S6 终验 R-1 实证):取消走 destroy() **不带 Error**——此前
185
+ // `req.destroy(new Error('aborted'))` 在 Electron Node 24 宿主体内表现为进程级未捕获
186
+ // 异常(响应流侧异步派发,无监听 → 宿主 utilityProcess 直接退出,句柄全失、引导队列被
187
+ // resume 误标 interrupted)。取消语义已由 spec.signal / D-19 承载,无需错误对象;
188
+ // res 侧 error 监听为双保险(中断时的取消性错误不再逃逸到进程级)。
179
189
  const onAbort = () => { try {
180
- req.destroy(new Error('aborted'));
190
+ req.destroy();
181
191
  }
182
192
  catch { /* 已完成 */ } };
183
193
  if (init.signal) {
package/dist/sbom.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "bomFormat": "CAR-SBOM",
3
3
  "specVersion": "0.1",
4
- "version": "1.15.1",
4
+ "version": "1.16.0",
5
5
  "components": [
6
6
  {
7
7
  "type": "file",
@@ -11,7 +11,7 @@
11
11
  {
12
12
  "type": "file",
13
13
  "path": "src/cli.ts",
14
- "sha256": "950c904e6a5dc05ae130b997bf93bcd8ea6a00dfe10b8bc36796641298f8fafa"
14
+ "sha256": "7313438811663fe23b28ed1edfd21c6f4fd45b15d08e68792a95deafdf4aafa6"
15
15
  },
16
16
  {
17
17
  "type": "file",
@@ -56,7 +56,7 @@
56
56
  {
57
57
  "type": "file",
58
58
  "path": "src/load/config.ts",
59
- "sha256": "2cb17ffa5da642ffdb17a2b067d10c421129534366bbe1f41687e1d8a5aeaab3"
59
+ "sha256": "86584c58bfb5d458475e474b896de6ffa2f89e7e76364f4bfe9f2f3fd3d2ad75"
60
60
  },
61
61
  {
62
62
  "type": "file",
@@ -126,7 +126,7 @@
126
126
  {
127
127
  "type": "file",
128
128
  "path": "src/memory/store.ts",
129
- "sha256": "656abef78cae852baa6ac21849f206aaf6a0a0e17492a860aeff34ad803f4ca1"
129
+ "sha256": "6390d1bd7739ca7f1d37cc5012cced4870ea9d8aba8310e5eac40d4f340d7b77"
130
130
  },
131
131
  {
132
132
  "type": "file",
@@ -176,7 +176,7 @@
176
176
  {
177
177
  "type": "file",
178
178
  "path": "src/runtime-core/llm.ts",
179
- "sha256": "3d203bae2ade0fdde8094e5a4b181fb759264d043eb020fde5b62ff4220cda1d"
179
+ "sha256": "b61eb6d9373442b5e35476b741184b5048451b6530c3490ea2a178d2982a8cc9"
180
180
  },
181
181
  {
182
182
  "type": "file",
@@ -211,7 +211,7 @@
211
211
  {
212
212
  "type": "file",
213
213
  "path": "src/seam.ts",
214
- "sha256": "54cc179a6b863e6e2d0d94a6275bd1ed17fefa46ca0b6de14d1c8e08cd5c1e2d"
214
+ "sha256": "bd0bad44f5dc0da542556146eff1318a30cb5b56eaf682d0350947716db2628a"
215
215
  },
216
216
  {
217
217
  "type": "file",
@@ -271,7 +271,7 @@
271
271
  {
272
272
  "type": "file",
273
273
  "path": "package.json",
274
- "sha256": "263bca628ecdf1f9ba119efca39f7e84366286af8637e3498570d0f12d6f1892"
274
+ "sha256": "dfebc528f18e62971b0d801c0ffccf2fe6cc461ba9b07c7a39a6648009ac424d"
275
275
  },
276
276
  {
277
277
  "type": "file",
package/dist/seam.d.ts CHANGED
@@ -49,7 +49,7 @@ export { CredentialService } from './runtime-core/credentials.ts';
49
49
  export type { LlmAdapter, LlmRequest, LlmChunk } from './runtime-core/types.ts';
50
50
  export { mountPlugin } from './load/loader.ts';
51
51
  export { Context } from './kernel/context.ts';
52
- export { loadCarConfig, mergeLlmConfig, mergeSignatureGate, warmCarConfig, type CarConfig, type LlmConfig } from './load/config.ts';
52
+ export { loadCarConfig, mergeLlmConfig, mergeSignatureGate, warmCarConfig, type CarConfig, type LlmConfig, type SubagentConfig } from './load/config.ts';
53
53
  export { probeCapabilities, SandboxExecutor } from './sandbox/sandbox.ts';
54
54
  export { AuthzService, checkCapability, type Decision, type AuthzRequest, type AuthzDecision, type DeclaredCapabilities } from './authz/authz.ts';
55
55
  export { createTelemetryFacade, telemetryConfigFromEnv } from './runtime-core/telemetry.ts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lqc123qwe/car-runtime",
3
- "version": "1.15.1",
3
+ "version": "1.16.0",
4
4
  "description": "Composable Agent Runtime (CAR) - microkernel plugin system with sandboxed PTC, append-only hashed session log, and MCP host bridge",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/cli.ts CHANGED
@@ -65,8 +65,9 @@ const HELP = `用法: car <command> [args]
65
65
  CAR_UNSIGNED_ALLOW=1 显式声明豁免(warn 缺签路径计数 confirmed=yes,横幅保留)
66
66
  配置文件通道(1.5 起双载体):cwd car.config.ts(export default {…};发现序 ts > json)或
67
67
  car.config.json 或 --config <path>;键位 sandbox.unsigned.allow / sandbox.sig.enforce /
68
- sandbox.sig.trustRoot / llm.* / llm.modelPool.*(多端点 fallback:endpoints id/baseUrl/model/
69
- adapterId/keyEnv/priority/weight/maxTokens + probe + maxAttempts;路由决策落链)/ mcp.servers.*
68
+ sandbox.sig.trustRoot / llm.* / modelPool.*(多端点 fallback:endpoints id/baseUrl/model/
69
+ adapterId/keyEnv/priority/weight/maxTokens + probe + maxAttempts;路由决策落链)/ llm.subagent.*
70
+ (子 Agent:model 独立锚点 / maxConcurrent / maxCumulative 护栏上限)/ mcp.servers.*
70
71
  (stdio: command/args/env;远程: url/headers,\${ENV_VAR} 引用注入凭据);优先级 flag > env > 配置 > 缺省;未知键 fail-visible`
71
72
 
72
73
  // 进程内热重载会话(ReloadManager 持有 epoch 与实例注册表;同进程连续 reload 语义完整)
@@ -232,7 +233,7 @@ async function main(): Promise<number> {
232
233
  console.error('CAR-E-LLM-CONFIG: 真实模型路径需要 baseUrl + model——')
233
234
  console.error(' 配置:car.config.ts(export default)或 car.config.json {"llm":{"baseUrl":"https://…","model":"…"}} / env CAR_LLM_BASE_URL+CAR_LLM_MODEL / flag --base-url --model')
234
235
  console.error(' anthropic:llm.adapterId "anthropic"(或 --adapter-id anthropic)+ baseUrl https://api.anthropic.com;凭据 ANTHROPIC_API_KEY')
235
- console.error(' 模型池:llm.modelPool.endpoints(多端点 fallback + health 预检;凭据 keyEnv 引用;路由决策落链)')
236
+ console.error(' 模型池:modelPool.endpoints(多端点 fallback + health 预检;凭据 keyEnv 引用;路由决策落链)')
236
237
  console.error(' 凭据:OPENAI_API_KEY / ANTHROPIC_API_KEY(env fallback 需 CAR_ALLOW_ENV_CREDENTIALS=1 或 llm.allowEnvFallback)或 keychain;诊断:car doctor')
237
238
  return 2
238
239
  }
@@ -52,6 +52,18 @@ export interface LlmConfig {
52
52
  allowEnvFallback?: boolean
53
53
  /** 1.14-S2(K-MP-2 / D-40):历史压缩策略(阈值自动触发判定入参;立即压缩 API 独立可用) */
54
54
  compaction?: CompactionConfig
55
+ /** 1.16-K3(D-K2-2):子 Agent 配置(缺省 = 继承父会话模型锚点 Q-A2 + 宿主护栏常量 Q-A3) */
56
+ subagent?: SubagentConfig
57
+ }
58
+
59
+ /** 1.16-K3(D-K2-2):子 Agent 配置面——宿主编排消费(内核自身不装配编排;schema 只登记键位) */
60
+ export interface SubagentConfig {
61
+ /** 独立子模型锚点(缺省 = 继承父会话现值;modelPool 激活时被池压过——与 llm.model 同口径) */
62
+ model?: string
63
+ /** 并发子 Agent 上限(正整数;缺省 = 宿主常量 3,Q-A3) */
64
+ maxConcurrent?: number
65
+ /** 单父会话累计派生上限(正整数;缺省 = 宿主常量 10,Q-A3) */
66
+ maxCumulative?: number
55
67
  }
56
68
 
57
69
  /** 1.14-S4(K-POOL-1 / D-42):模型池端点登记(多端点 fallback 候选;凭据仅收 keyEnv 引用) */
@@ -235,6 +247,18 @@ const rawSchema = z.object({
235
247
  protectLastTurns: z.number({ invalid_type_error: '必须为正整数', required_error: '必须为正整数' })
236
248
  .refine(v => Number.isInteger(v) && v > 0, { message: '必须为正整数' }).optional(),
237
249
  }).strict().optional(),
250
+ // 1.16-K3(D-K2-2):子 Agent 配置(model 独立锚点 + 护栏上限;空对象无意义显式拒——禁静默 no-op)
251
+ subagent: z.object({
252
+ model: nonEmptyTrimmed().optional(),
253
+ maxConcurrent: z.number({ invalid_type_error: '必须为正整数', required_error: '必须为正整数' })
254
+ .refine(v => Number.isFinite(v) && Number.isInteger(v) && v > 0, { message: '必须为正整数' })
255
+ .optional(),
256
+ maxCumulative: z.number({ invalid_type_error: '必须为正整数', required_error: '必须为正整数' })
257
+ .refine(v => Number.isFinite(v) && Number.isInteger(v) && v > 0, { message: '必须为正整数' })
258
+ .optional(),
259
+ }).strict()
260
+ .refine(v => Object.keys(v).length > 0, { message: '至少登记一个键(model/maxConcurrent/maxCumulative;无子 Agent 配置需求请移除 llm.subagent 键,行为与 1.15.2 一致)' })
261
+ .optional(),
238
262
  }).strict().optional(),
239
263
  // 1.14-S4(K-POOL-1 / D-42):模型池登记(多端点 fallback + health + routing/decide 落链)
240
264
  modelPool: modelPoolSchema.optional(),
@@ -243,8 +267,8 @@ const rawSchema = z.object({
243
267
  }).strict().optional(),
244
268
  }, { invalid_type_error: '配置顶层必须为 JSON 对象' }).strict()
245
269
 
246
- /** 未登记键提示(渲染层拼 path)——与系统设计键位空间同步 */
247
- const KEY_SPACES = '登记键位:sandbox.* / llm.* / llm.modelPool.* / mcp.servers.*'
270
+ /** 未登记键提示(渲染层拼 path)——与系统设计键位空间同步;D-1 勘误:modelPool 为顶层键(非 llm.modelPool) */
271
+ const KEY_SPACES = '登记键位:sandbox.* / llm.* / modelPool.* / llm.subagent.* / mcp.servers.*'
248
272
 
249
273
  /** zod issue → CAR-E-CONFIG 渲染(首个 issue;unrecognized_keys 按键路径展开) */
250
274
  function renderIssue(error: z.ZodError): string {
@@ -287,6 +311,13 @@ function parseCarConfig(raw: unknown): { config: CarConfig; error?: string } {
287
311
  if (d.llm.compaction.protectLastTurns !== undefined) cp.protectLastTurns = d.llm.compaction.protectLastTurns
288
312
  llm.compaction = cp
289
313
  }
314
+ if (d.llm.subagent) {
315
+ const sg: SubagentConfig = {}
316
+ if (d.llm.subagent.model !== undefined) sg.model = d.llm.subagent.model
317
+ if (d.llm.subagent.maxConcurrent !== undefined) sg.maxConcurrent = d.llm.subagent.maxConcurrent
318
+ if (d.llm.subagent.maxCumulative !== undefined) sg.maxCumulative = d.llm.subagent.maxCumulative
319
+ llm.subagent = sg
320
+ }
290
321
  out.llm = llm
291
322
  }
292
323
  if (d.mcp) {
@@ -67,9 +67,12 @@ function assertValidId(id: string): void {
67
67
 
68
68
  export class MemoryStore {
69
69
  readonly dir: string
70
+ /** 时钟缝(1.15.2 测试可观测性):缺省 Date.now;spec 注入受控时钟消除同毫秒排序竞态 */
71
+ readonly #now: () => number
70
72
 
71
- constructor(dir: string) {
73
+ constructor(dir: string, opts?: { now?: () => number }) {
72
74
  this.dir = dir
75
+ this.#now = opts?.now ?? Date.now
73
76
  mkdirSync(dir, { recursive: true })
74
77
  }
75
78
 
@@ -132,7 +135,7 @@ export class MemoryStore {
132
135
  if (this.get(id)) {
133
136
  throw new Error(`CAR-E-MEM-EXISTS: 记忆 "${id}" 已存在(write 冲突 fail-visible——修改请走 edit)`)
134
137
  }
135
- const now = Date.now()
138
+ const now = this.#now()
136
139
  const entry: MemoryEntry = { id, text: input.text, createdAt: now, updatedAt: now }
137
140
  if (input.tags?.length) entry.tags = [...input.tags]
138
141
  if (input.sourceSession) entry.sourceSession = input.sourceSession
@@ -156,7 +159,7 @@ export class MemoryStore {
156
159
  }
157
160
  // tags 语义:undefined = 不变(payload 不带键,重放取前态);数组 = 整体替换(含空数组 =
158
161
  // 清空,payload 恒带键——重放 [] 与清空同构,禁「带键/缺键」二义)
159
- const next: MemoryEntry = { ...prev, text, updatedAt: Date.now() }
162
+ const next: MemoryEntry = { ...prev, text, updatedAt: this.#now() }
160
163
  if (tags !== undefined) {
161
164
  const { tags: _drop, ...rest } = next as MemoryEntry & { tags?: string[] }
162
165
  void _drop
@@ -216,7 +219,7 @@ export class MemoryStore {
216
219
  } satisfies MemoryEventPayload)
217
220
  try {
218
221
  if (target.present) {
219
- const entry: MemoryEntry = { id, text: target.text!, createdAt: target.createdAt!, updatedAt: Date.now() }
222
+ const entry: MemoryEntry = { id, text: target.text!, createdAt: target.createdAt!, updatedAt: this.#now() }
220
223
  if (target.tags?.length) entry.tags = [...target.tags]
221
224
  if (target.sourceSession) entry.sourceSession = target.sourceSession
222
225
  this.#writeFile(entry)
@@ -189,6 +189,11 @@ const nodeHttpSseFetch = (url: string, init: { method?: string; headers?: Record
189
189
  const mod = u.protocol === 'https:' ? httpsRequest : httpRequest
190
190
  const req = mod(u, { method: init.method ?? 'GET', headers: init.headers }, res => {
191
191
  const status = res.statusCode ?? 0
192
+ // 1.15.2-BUG(桌面 S6 终验实证):取消时 req.destroy(err) 会让**响应流** res 异步 emit
193
+ // 'error'——此前无监听 → Node 抛 unhandled 'error' 事件 → 宿主进程直接退出(Electron
194
+ // utilityProcess 无 uncaughtException 兜底时 = 句柄全失、引导队列被 resume 误标 interrupted)。
195
+ // 迭代器侧已由 streamSsePost 的 catch 按 D-19 静默收口,此处监听仅防进程级未捕获异常
196
+ res.on('error', () => { /* 取消/中断:由消费侧(streamSsePost catch)收口 */ })
192
197
  resolve({
193
198
  ok: status >= 200 && status < 300,
194
199
  status,
@@ -201,7 +206,12 @@ const nodeHttpSseFetch = (url: string, init: { method?: string; headers?: Record
201
206
  body: res,
202
207
  })
203
208
  })
204
- const onAbort = () => { try { req.destroy(new Error('aborted')) } catch { /* 已完成 */ } }
209
+ // 1.15.2-BUG(桌面 S6 终验 R-1 实证):取消走 destroy() **不带 Error**——此前
210
+ // `req.destroy(new Error('aborted'))` 在 Electron Node 24 宿主体内表现为进程级未捕获
211
+ // 异常(响应流侧异步派发,无监听 → 宿主 utilityProcess 直接退出,句柄全失、引导队列被
212
+ // resume 误标 interrupted)。取消语义已由 spec.signal / D-19 承载,无需错误对象;
213
+ // res 侧 error 监听为双保险(中断时的取消性错误不再逃逸到进程级)。
214
+ const onAbort = () => { try { req.destroy() } catch { /* 已完成 */ } }
205
215
  if (init.signal) {
206
216
  if (init.signal.aborted) onAbort()
207
217
  else init.signal.addEventListener('abort', onAbort, { once: true })
package/src/seam.ts CHANGED
@@ -49,7 +49,7 @@ export { CredentialService } from './runtime-core/credentials.ts'
49
49
  export type { LlmAdapter, LlmRequest, LlmChunk } from './runtime-core/types.ts'
50
50
  export { mountPlugin } from './load/loader.ts'
51
51
  export { Context } from './kernel/context.ts'
52
- export { loadCarConfig, mergeLlmConfig, mergeSignatureGate, warmCarConfig, type CarConfig, type LlmConfig } from './load/config.ts'
52
+ export { loadCarConfig, mergeLlmConfig, mergeSignatureGate, warmCarConfig, type CarConfig, type LlmConfig, type SubagentConfig } from './load/config.ts'
53
53
  export { probeCapabilities, SandboxExecutor } from './sandbox/sandbox.ts'
54
54
  export { AuthzService, checkCapability, type Decision, type AuthzRequest, type AuthzDecision, type DeclaredCapabilities } from './authz/authz.ts'
55
55
  export { createTelemetryFacade, telemetryConfigFromEnv } from './runtime-core/telemetry.ts'
Binary file
@@ -1 +0,0 @@
1
- {"base64Signature":"MEYCIQC1Pd8enRMQuJLPeyQxzcr+Jrs5tNBepaveEloOXtX2ngIhALWseKiCpb4moRpy0KpUqDQI5IbifzLv1ok43QvSeHQY","cert":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUc1ekNDQm0yZ0F3SUJBZ0lVT1lYVXBLWkZCSWZzelIvZFQwNm9jNVcydWl3d0NnWUlLb1pJemowRUF3TXcKTnpFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUjR3SEFZRFZRUURFeFZ6YVdkemRHOXlaUzFwYm5SbApjbTFsWkdsaGRHVXdIaGNOTWpZeE1ERTVNRGN3TWpJNFdoY05Nall4TURFNU1EY3hNakk0V2pBQU1Ga3dFd1lICktvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUwZFFETHVuWmtEb2RNdy9lSHNIL2o1RnlmNjNFN2FLL2VXWncKN3RoUG1aYSs4TmxYWHByVHo4elFqWXl5aWtiZHh1b2JMSGFOU2lPZy9uK3UwcFlDWXFPQ0JZd3dnZ1dJTUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREF6QWZCZ05WSFNNRUdEQVdnQlRmCjArblBWaVFSbHZtbzJPa29WYUxHTGhoa1B6QmlCZ05WSFJFQkFmOEVXREJXaGxSb2RIUndjem92TDJkcGRHaDEKWWk1amIyMHZiSEZqTmpJMEwyTmhjaTF5ZFc1MGFXMWxMeTVuYVhSb2RXSXZkMjl5YTJac2IzZHpMM0psYkdWaApjMlV1ZVcxc1FISmxabk12ZEdGbmN5OHhMakUxTGpFd09RWUtLd1lCQkFHRHZ6QUJBUVFyYUhSMGNITTZMeTkwCmIydGxiaTVoWTNScGIyNXpMbWRwZEdoMVluVnpaWEpqYjI1MFpXNTBMbU52YlRBVkJnb3JCZ0VFQVlPL01BRUMKQkFkeVpXeGxZWE5sTURZR0Npc0dBUVFCZzc4d0FRTUVLR1UzWkRneE5tRm1NV1F6WkRaa1pqSTVNVEpoWldNdwpNRGt6TW1Vek9XVmpZMkkyTkdJNU1XWXdGUVlLS3dZQkJBR0R2ekFCQkFRSGNtVnNaV0Z6WlRBZ0Jnb3JCZ0VFCkFZTy9NQUVGQkJKc2NXTTJNalF2WTJGeUxYSjFiblJwYldVd0hnWUtLd1lCQkFHRHZ6QUJCZ1FRY21WbWN5OTAKWVdkekx6RXVNVFV1TVRBN0Jnb3JCZ0VFQVlPL01BRUlCQzBNSzJoMGRIQnpPaTh2ZEc5clpXNHVZV04wYVc5dQpjeTVuYVhSb2RXSjFjMlZ5WTI5dWRHVnVkQzVqYjIwd1pBWUtLd1lCQkFHRHZ6QUJDUVJXREZSb2RIUndjem92CkwyZHBkR2gxWWk1amIyMHZiSEZqTmpJMEwyTmhjaTF5ZFc1MGFXMWxMeTVuYVhSb2RXSXZkMjl5YTJac2IzZHoKTDNKbGJHVmhjMlV1ZVcxc1FISmxabk12ZEdGbmN5OHhMakUxTGpFd09BWUtLd1lCQkFHRHZ6QUJDZ1FxRENobApOMlE0TVRaaFpqRmtNMlEyWkdZeU9URXlZV1ZqTURBNU16SmxNemxsWTJOaU5qUmlPVEZtTUIwR0Npc0dBUVFCCmc3OHdBUXNFRHd3TloybDBhSFZpTFdodmMzUmxaREExQmdvckJnRUVBWU8vTUFFTUJDY01KV2gwZEhCek9pOHYKWjJsMGFIVmlMbU52YlM5c2NXTTJNalF2WTJGeUxYSjFiblJwYldVd09BWUtLd1lCQkFHRHZ6QUJEUVFxRENobApOMlE0TVRaaFpqRmtNMlEyWkdZeU9URXlZV1ZqTURBNU16SmxNemxsWTJOaU5qUmlPVEZtTUNBR0Npc0dBUVFCCmc3OHdBUTRFRWd3UWNtVm1jeTkwWVdkekx6RXVNVFV1TVRBYUJnb3JCZ0VFQVlPL01BRVBCQXdNQ2pFek5qRXgKT1RJM01UUXdLUVlLS3dZQkJBR0R2ekFCRUFRYkRCbG9kSFJ3Y3pvdkwyZHBkR2gxWWk1amIyMHZiSEZqTmpJMApNQmdHQ2lzR0FRUUJnNzh3QVJFRUNnd0lOamt5TXpRMU5qUXdaQVlLS3dZQkJBR0R2ekFCRWdSV0RGUm9kSFJ3CmN6b3ZMMmRwZEdoMVlpNWpiMjB2YkhGak5qSTBMMk5oY2kxeWRXNTBhVzFsTHk1bmFYUm9kV0l2ZDI5eWEyWnMKYjNkekwzSmxiR1ZoYzJVdWVXMXNRSEpsWm5NdmRHRm5jeTh4TGpFMUxqRXdPQVlLS3dZQkJBR0R2ekFCRXdRcQpEQ2hsTjJRNE1UWmhaakZrTTJRMlpHWXlPVEV5WVdWak1EQTVNekpsTXpsbFkyTmlOalJpT1RGbU1CY0dDaXNHCkFRUUJnNzh3QVJRRUNRd0hjbVZzWldGelpUQlpCZ29yQmdFRUFZTy9NQUVWQkVzTVNXaDBkSEJ6T2k4dloybDAKYUhWaUxtTnZiUzlzY1dNMk1qUXZZMkZ5TFhKMWJuUnBiV1V2WVdOMGFXOXVjeTl5ZFc1ekx6TTVNakV6TkRJMgpPVEU1TDJGMGRHVnRjSFJ6THpFd0ZnWUtLd1lCQkFHRHZ6QUJGZ1FJREFad2RXSnNhV013VUFZS0t3WUJCQUdECnZ6QUJHQVJDREVCeVpYQnZPbXh4WXpZeU5FQTJPVEl6TkRVMk5DOWpZWEl0Y25WdWRHbHRaVUF4TXpZeE1Ua3kKTnpFME9uSmxaanB5WldaekwzUmhaM012TVM0eE5TNHhNSUdLQmdvckJnRUVBZFo1QWdRQ0JId0VlZ0I0QUhZQQozVDB3YXNiSEVUSmpHUjRjbVdjM0FxSktYcmplUEszL2g0cHlnQzhwN280QUFBR2hVdmdGUWdBQUJBTUFSekJGCkFpQVVzSXJVZm4xRDVDelMzVWRkd1NzV2FwSEU1aW5nWTVCYkxXSXdCTnpKakFJaEFQbU9WNW9UajNGdXNDbUcKV3dRNmxuQ2dkS3VwM1IrT1p0VHVqVFhXWjA4ME1Bb0dDQ3FHU000OUJBTURBMmdBTUdVQ01FNlZxVGhrMGxMaAo5NEVsU05iMjNFWlI1UXA5T3J4RHBwckhkODFKUklJeEpUczE0M2QrZ1ZwRG1jVWxmRFdxRlFJeEFMQ2U0Vi9YCjQyZUwwMjFMSHR5ekFBelV4ei9IakdHOVU3Zk9RVkhFejVnb2dHMVpLR1JRTkVZMXBOL0Z4QkNrVUE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==","rekorBundle":{"SignedEntryTimestamp":"MEUCIGZpwjyHanrQN38GmVzMx+W/q7gYQ8ee+mVMm9bgMYBuAiEA9SpTASJaO9rm+UTocrIKNF6DeLUSiHFJk5NRq8RiPJA=","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI0OGM1NzMzNDE0YTdmNDAyN2ViNDQxYTM1YjRkYjBmOTExYjVhOGI4MWQ4ODlhZDIxMjg0MDQwMWQ4ZTJiNzUyIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUUMxUGQ4ZW5STVF1SkxQZXlReHpjcitKcnM1dE5CZXBhdmVFbG9PWHRYMm5nSWhBTFdzZUtpQ3BiNG1vUnB5MEtwVXFEUUk1SWJpZnpMdjFvazQzUXZTZUhRWSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVYzFla05EUW0weVowRjNTVUpCWjBsVlQxbFlWWEJMV2taQ1NXWnplbEl2WkZRd05tOWpOVmN5ZFdsM2QwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFplRTFFUlRWTlJHTjNUV3BKTkZkb1kwNU5hbGw0VFVSRk5VMUVZM2hOYWtrMFYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVV3WkZGRVRIVnVXbXRFYjJSTmR5OWxTSE5JTDJvMVJubG1Oak5GTjJGTEwyVlhXbmNLTjNSb1VHMWFZU3M0VG14WVdIQnlWSG80ZWxGcVdYbDVhV3RpWkhoMWIySk1TR0ZPVTJsUFp5OXVLM1V3Y0ZsRFdYRlBRMEpaZDNkbloxZEpUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXWkNaMDVXU0ZOTlJVZEVRVmRuUWxSbUNqQXJibEJXYVZGU2JIWnRiekpQYTI5V1lVeEhUR2hvYTFCNlFtbENaMDVXU0ZKRlFrRm1PRVZYUkVKWGFHeFNiMlJJVW5kamVtOTJUREprY0dSSGFERUtXV2sxYW1JeU1IWmlTRVpxVG1wSk1Fd3lUbWhqYVRGNVpGYzFNR0ZYTVd4TWVUVnVZVmhTYjJSWFNYWmtNamw1WVRKYWMySXpaSHBNTTBwc1lrZFdhQXBqTWxWMVpWY3hjMUZJU214YWJrMTJaRWRHYm1ONU9IaE1ha1V4VEdwRmQwOVJXVXRMZDFsQ1FrRkhSSFo2UVVKQlVWRnlZVWhTTUdOSVRUWk1lVGt3Q21JeWRHeGlhVFZvV1ROU2NHSXlOWHBNYldSd1pFZG9NVmx1Vm5wYVdFcHFZakkxTUZwWE5UQk1iVTUyWWxSQlZrSm5iM0pDWjBWRlFWbFBMMDFCUlVNS1FrRmtlVnBYZUd4WldFNXNUVVJaUjBOcGMwZEJVVkZDWnpjNGQwRlJUVVZMUjFVeldrUm5lRTV0Um0xTlYxRjZXa1JhYTFwcVNUVk5WRXBvV2xkTmR3cE5SR3Q2VFcxVmVrOVhWbXBaTWtreVRrZEpOVTFYV1hkR1VWbExTM2RaUWtKQlIwUjJla0ZDUWtGUlNHTnRWbk5hVjBaNldsUkJaMEpuYjNKQ1owVkZDa0ZaVHk5TlFVVkdRa0pLYzJOWFRUSk5hbEYyV1RKR2VVeFlTakZpYmxKd1lsZFZkMGhuV1V0TGQxbENRa0ZIUkhaNlFVSkNaMUZSWTIxV2JXTjVPVEFLV1Zka2VreDZSWFZOVkZWMVRWUkJOMEpuYjNKQ1owVkZRVmxQTDAxQlJVbENRekJOU3pKb01HUklRbnBQYVRoMlpFYzVjbHBYTkhWWlYwNHdZVmM1ZFFwamVUVnVZVmhTYjJSWFNqRmpNbFo1V1RJNWRXUkhWblZrUXpWcVlqSXdkMXBCV1V0TGQxbENRa0ZIUkhaNlFVSkRVVkpYUkVaU2IyUklVbmRqZW05MkNrd3laSEJrUjJneFdXazFhbUl5TUhaaVNFWnFUbXBKTUV3eVRtaGphVEY1WkZjMU1HRlhNV3hNZVRWdVlWaFNiMlJYU1haa01qbDVZVEphYzJJelpIb0tURE5LYkdKSFZtaGpNbFYxWlZjeGMxRklTbXhhYmsxMlpFZEdibU41T0hoTWFrVXhUR3BGZDA5QldVdExkMWxDUWtGSFJIWjZRVUpEWjFGeFJFTm9iQXBPTWxFMFRWUmFhRnBxUm10Tk1sRXlXa2RaZVU5VVJYbFpWMVpxVFVSQk5VMTZTbXhOZW14c1dUSk9hVTVxVW1sUFZFWnRUVUl3UjBOcGMwZEJVVkZDQ21jM09IZEJVWE5GUkhkM1Rsb3liREJoU0ZacFRGZG9kbU16VW14YVJFRXhRbWR2Y2tKblJVVkJXVTh2VFVGRlRVSkRZMDFLVjJnd1pFaENlazlwT0hZS1dqSnNNR0ZJVm1sTWJVNTJZbE01YzJOWFRUSk5hbEYyV1RKR2VVeFlTakZpYmxKd1lsZFZkMDlCV1V0TGQxbENRa0ZIUkhaNlFVSkVVVkZ4UkVOb2JBcE9NbEUwVFZSYWFGcHFSbXROTWxFeVdrZFplVTlVUlhsWlYxWnFUVVJCTlUxNlNteE5lbXhzV1RKT2FVNXFVbWxQVkVadFRVTkJSME5wYzBkQlVWRkNDbWMzT0hkQlVUUkZSV2QzVVdOdFZtMWplVGt3V1Zka2VreDZSWFZOVkZWMVRWUkJZVUpuYjNKQ1owVkZRVmxQTDAxQlJWQkNRWGROUTJwRmVrNXFSWGdLVDFSSk0wMVVVWGRMVVZsTFMzZFpRa0pCUjBSMmVrRkNSVUZSWWtSQ2JHOWtTRkozWTNwdmRrd3laSEJrUjJneFdXazFhbUl5TUhaaVNFWnFUbXBKTUFwTlFtZEhRMmx6UjBGUlVVSm5OemgzUVZKRlJVTm5kMGxPYW10NVRYcFJNVTVxVVhkYVFWbExTM2RaUWtKQlIwUjJla0ZDUldkU1YwUkdVbTlrU0ZKM0NtTjZiM1pNTW1Sd1pFZG9NVmxwTldwaU1qQjJZa2hHYWs1cVNUQk1NazVvWTJreGVXUlhOVEJoVnpGc1RIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTUtZak5rZWt3elNteGlSMVpvWXpKVmRXVlhNWE5SU0Vwc1dtNU5kbVJIUm01amVUaDRUR3BGTVV4cVJYZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JYZFJjUXBFUTJoc1RqSlJORTFVV21oYWFrWnJUVEpSTWxwSFdYbFBWRVY1V1ZkV2FrMUVRVFZOZWtwc1RYcHNiRmt5VG1sT2FsSnBUMVJHYlUxQ1kwZERhWE5IQ2tGUlVVSm5OemgzUVZKUlJVTlJkMGhqYlZaeldsZEdlbHBVUWxwQ1oyOXlRbWRGUlVGWlR5OU5RVVZXUWtWelRWTlhhREJrU0VKNlQyazRkbG95YkRBS1lVaFdhVXh0VG5aaVV6bHpZMWROTWsxcVVYWlpNa1o1VEZoS01XSnVVbkJpVjFWMldWZE9NR0ZYT1hWamVUbDVaRmMxZWt4NlRUVk5ha1Y2VGtSSk1ncFBWRVUxVERKR01HUkhWblJqU0ZKNlRIcEZkMFpuV1V0TGQxbENRa0ZIUkhaNlFVSkdaMUZKUkVGYWQyUlhTbk5oVjAxM1ZVRlpTMHQzV1VKQ1FVZEVDblo2UVVKSFFWSkRSRVZDZVZwWVFuWlBiWGg0V1hwWmVVNUZRVEpQVkVsNlRrUlZNazVET1dwWldFbDBZMjVXZFdSSGJIUmFWVUY0VFhwWmVFMVVhM2tLVG5wRk1FOXVTbXhhYW5CNVdsZGFla3d6VW1oYU0wMTJUVk0wZUU1VE5IaE5TVWRMUW1kdmNrSm5SVVZCWkZvMVFXZFJRMEpJZDBWbFowSTBRVWhaUVFvelZEQjNZWE5pU0VWVVNtcEhValJqYlZkak0wRnhTa3RZY21wbFVFc3pMMmcwY0hsblF6aHdOMjgwUVVGQlIyaFZkbWRHVVdkQlFVSkJUVUZTZWtKR0NrRnBRVlZ6U1hKVlptNHhSRFZEZWxNelZXUmtkMU56VjJGd1NFVTFhVzVuV1RWQ1lreFhTWGRDVG5wS2FrRkphRUZRYlU5V05XOVVhak5HZFhORGJVY0tWM2RSTm14dVEyZGtTM1Z3TTFJclQxcDBWSFZxVkZoWFdqQTRNRTFCYjBkRFEzRkhVMDAwT1VKQlRVUkJNbWRCVFVkVlEwMUZObFp4Vkdock1HeE1hQW81TkVWc1UwNWlNak5GV2xJMVVYQTVUM0o0UkhCd2NraGtPREZLVWtsSmVFcFVjekUwTTJRcloxWndSRzFqVld4bVJGZHhSbEZKZUVGTVEyVTBWaTlZQ2pReVpVd3dNakZNU0hSNWVrRkJlbFY0ZWk5SWFrZEhPVlUzWms5UlZraEZlalZuYjJkSE1WcExSMUpSVGtWWk1YQk9MMFo0UWtOclZVRTlQUW90TFMwdExVVk9SQ0JEUlZKVVNVWkpRMEZVUlMwdExTMHRDZz09In19fX0=","integratedTime":1792393348,"logIndex":3319543860,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}}