@toddzheng024/dscode-bundle 0.7.27 → 0.7.29
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/README.md +1 -1
- package/THIRD_PARTY_NOTICES.md +10 -10
- package/bootstrap.mjs +1 -1
- package/cordis.patch.yml +433 -46
- package/package.json +280 -245
- package/plugins/account/index.mjs +178 -0
- package/plugins/account/state.mjs +123 -0
- package/plugins/auto-review/index.mjs +8 -5
- package/plugins/code-review/index.mjs +1 -1
- package/plugins/computer-use/index.mjs +37 -0
- package/plugins/cordis-config/plain.mjs +31 -0
- package/plugins/dscode/index.mjs +1 -1
- package/plugins/exec/cli.mjs +1 -1
- package/plugins/grok/index.mjs +28 -24
- package/plugins/i18n/messages.mjs +204 -0
- package/plugins/memory/index.mjs +1 -1
- package/plugins/message-source/kind.mjs +20 -0
- package/plugins/openrouter/adapter.mjs +29 -13
- package/plugins/openrouter/index.mjs +31 -28
- package/plugins/session-bridge/communication.mjs +6 -3
- package/plugins/session-bridge/server.mjs +3 -2
- package/plugins/session-bridge/tasks.mjs +3 -1
- package/plugins/session-cards/index.mjs +1 -1
- package/plugins/time-marks/index.mjs +3 -2
- package/plugins/time-marks/marks.mjs +6 -5
- package/plugins/triggers/config.mjs +1 -1
- package/plugins/triggers/tools.mjs +1 -1
- package/plugins/tui-tools/doctor.mjs +1 -1
- package/plugins/tui-tools/index.mjs +16 -4
- package/plugins/ultra/policy.mjs +16 -0
- package/vendor/bash/index.js +455 -186
- package/vendor/bash/types/background.d.ts +38 -7
- package/vendor/bash/types/index.d.ts +20 -4
- package/vendor/bash/types/render.d.ts +28 -9
- package/vendor/command-goal/index.js +3 -1
- package/vendor/deepseek/index.js +1378 -1246
- package/vendor/deepseek/types/adapter.d.ts +16 -155
- package/vendor/deepseek/types/config.d.ts +127 -0
- package/vendor/deepseek/types/defaults.d.ts +24 -0
- package/vendor/deepseek/types/file-store.d.ts +5 -3
- package/vendor/deepseek/types/files-api.d.ts +12 -9
- package/vendor/deepseek/types/image-tokens.d.ts +24 -9
- package/vendor/deepseek/types/images.d.ts +35 -0
- package/vendor/deepseek/types/index.d.ts +10 -94
- package/vendor/deepseek/types/messages-api.d.ts +10 -0
- package/vendor/deepseek/types/model-info.d.ts +16 -0
- package/vendor/deepseek/types/models.d.ts +4 -0
- package/vendor/deepseek/types/replay.d.ts +27 -0
- package/vendor/deepseek/types/request-extensions.d.ts +16 -0
- package/vendor/deepseek/types/request-files.d.ts +49 -0
- package/vendor/deepseek/types/request-pricing.d.ts +32 -20
- package/vendor/deepseek/types/serialize.d.ts +17 -82
- package/vendor/deepseek/types/sse.d.ts +6 -22
- package/vendor/deepseek/types/translate.d.ts +13 -36
- package/vendor/deepseek/types/transport.d.ts +15 -0
- package/vendor/deepseek/types/types.d.ts +106 -167
- package/vendor/deepseek/types/wire-types.d.ts +62 -0
- package/vendor/persistent/index.js +9 -3
- package/vendor/subagent/index.js +11 -8
- package/vendor/subagent/model-selection-settings.js +12 -38
- package/vendor/subagent/types/index.d.ts +4 -3
- package/vendor/subagent/types/model-selection-settings.d.ts +12 -10
- package/vendor/subagent-core/index.js +401 -264
- package/vendor/subagent-core/typert.host.js +103 -113
- package/vendor/subagent-core/typert.remote-client.d.ts +1 -3
- package/vendor/subagent-core/typert.remote-client.js +23 -69
- package/vendor/subagent-core/types/archive-admission.d.ts +16 -0
- package/vendor/subagent-core/types/archive-admission.js +151 -0
- package/vendor/subagent-core/types/assistant-output.d.ts +2 -2
- package/vendor/subagent-core/types/catalog.d.ts +17 -10
- package/vendor/subagent-core/types/catalog.js +12 -6
- package/vendor/subagent-core/types/child-agent.d.ts +8 -5
- package/vendor/subagent-core/types/child-agent.js +11 -5
- package/vendor/subagent-core/types/continuation-activation.d.ts +17 -1
- package/vendor/subagent-core/types/continuation-activation.js +41 -4
- package/vendor/subagent-core/types/continuation-messages.d.ts +1 -1
- package/vendor/subagent-core/types/continuation-messages.js +7 -3
- package/vendor/subagent-core/types/continuation.d.ts +1 -1
- package/vendor/subagent-core/types/continuation.js +2 -2
- package/vendor/subagent-core/types/control-types.d.ts +29 -36
- package/vendor/subagent-core/types/control-types.js +2 -3
- package/vendor/subagent-core/types/control.d.ts +2 -28
- package/vendor/subagent-core/types/control.js +3 -40
- package/vendor/subagent-core/types/index.d.ts +45 -41
- package/vendor/subagent-core/types/index.js +46 -82
- package/vendor/subagent-core/types/internal.d.ts +2 -2
- package/vendor/subagent-core/types/internal.js +2 -2
- package/vendor/subagent-core/types/lifecycle.d.ts +1 -1
- package/vendor/subagent-core/types/lifecycle.js +5 -3
- package/vendor/subagent-core/types/list-children.d.ts +15 -32
- package/vendor/subagent-core/types/list-children.js +45 -49
- package/vendor/subagent-core/types/out-of-process.d.ts +1 -1
- package/vendor/subagent-core/types/projection-types.d.ts +9 -1
- package/vendor/subagent-core/types/projection.d.ts +5 -0
- package/vendor/subagent-core/types/projection.js +10 -4
- package/vendor/subagent-core/types/run-settlement.js +1 -1
- package/vendor/subagent-core/types/types.d.ts +2 -2
- package/vendor/terminal/index.js +94 -30
- package/vendor/tui/lib/index.mjs +2 -1
- package/vendor/tui/lib/kernel-panels.mjs +1 -1
- package/vendor/tui/lib/render/projection.mjs +50 -36
- package/presets/dscode/agent.cordis.yml +0 -321
- package/presets/dscode/preset.yml +0 -3
|
@@ -53,6 +53,40 @@ export const MESSAGES = {
|
|
|
53
53
|
'doctor.noRoute': 'No model route is available, so the model analysis could not run.',
|
|
54
54
|
'doctor.scope': 'Evidence scope: {traces} recent sessions, {logs} warnings/errors; conversation text, tool arguments and tool output were not read.',
|
|
55
55
|
'doctor.failed': 'Model analysis did not finish: {error}.',
|
|
56
|
+
'account.signedIn': 'DeepSeek account: signed in on this machine (the stored grant is not re-checked here).',
|
|
57
|
+
'account.signedOut': 'DeepSeek account: signed out. The DeepSeek route falls back to an API key.',
|
|
58
|
+
'account.profile': 'Identity: {identity}',
|
|
59
|
+
'account.profileFailed': 'Identity: could not be read just now.',
|
|
60
|
+
'account.unknownIdentity': 'no display name',
|
|
61
|
+
'account.balance': 'Balance: {wallets}',
|
|
62
|
+
'account.bonus': 'bonus {wallets}',
|
|
63
|
+
'account.balanceFailed': 'Balance: could not be read just now.',
|
|
64
|
+
'account.balanceEmpty': 'Balance: no wallet reported.',
|
|
65
|
+
'account.attempt': 'Last sign-in: {phase}',
|
|
66
|
+
'account.attemptFailed': 'Last sign-in: {phase} ({reason})',
|
|
67
|
+
'account.phase.initializing': 'starting',
|
|
68
|
+
'account.phase.waiting-browser': 'waiting for the browser',
|
|
69
|
+
'account.phase.exchanging': 'exchanging the code',
|
|
70
|
+
'account.phase.committing': 'saving the grant',
|
|
71
|
+
'account.phase.succeeded': 'signed in',
|
|
72
|
+
'account.phase.cancelled': 'cancelled',
|
|
73
|
+
'account.phase.expired': 'expired',
|
|
74
|
+
'account.phase.failed': 'failed',
|
|
75
|
+
'account.error.network': 'the platform could not be reached',
|
|
76
|
+
'account.error.protocol': 'the platform answered unexpectedly',
|
|
77
|
+
'account.error.expired': 'the attempt timed out',
|
|
78
|
+
'account.error.storage': 'the credential store refused the grant',
|
|
79
|
+
'account.links': 'Usage: {usage} · Top-up: {topUp}',
|
|
80
|
+
'account.hintSignedIn': '/account logout signs out on this machine.',
|
|
81
|
+
'account.hintSignedOut': '/account login opens the browser to sign in.',
|
|
82
|
+
'account.unavailable': 'This deployment composes no DeepSeek account service.',
|
|
83
|
+
'account.noCallback': 'Account login needs the loopback callback server; it is disabled (DSCODE_ACCOUNT_LOGIN=0).',
|
|
84
|
+
'account.usage': 'Usage: /account [login|cancel|logout]',
|
|
85
|
+
'account.startFailed': 'The sign-in did not start.',
|
|
86
|
+
'account.nothingToCancel': 'No sign-in is in progress.',
|
|
87
|
+
'account.starting': 'Signing in to DeepSeek through the browser…',
|
|
88
|
+
'account.browserOpened': 'The browser was opened. Finish the sign-in there; it lands back on this machine.',
|
|
89
|
+
'account.browserManual': 'Open this URL to finish the sign-in:',
|
|
56
90
|
},
|
|
57
91
|
'zh-CN': {
|
|
58
92
|
'activity.replying': '正在回复', 'activity.thinking': '正在思考', 'activity.running': '正在执行',
|
|
@@ -83,6 +117,40 @@ export const MESSAGES = {
|
|
|
83
117
|
'doctor.noRoute': '没有可用的模型路由,无法运行模型分析。',
|
|
84
118
|
'doctor.scope': '证据范围:{traces} 个近期会话、{logs} 条 warning/error;未读取对话正文、工具参数或工具输出。',
|
|
85
119
|
'doctor.failed': '模型分析未完成:{error}。',
|
|
120
|
+
'account.signedIn': 'DeepSeek 账号:本机已登录(此处不重新校验凭据是否仍被服务端接受)。',
|
|
121
|
+
'account.signedOut': 'DeepSeek 账号:未登录。DeepSeek 路由将回退到 API key。',
|
|
122
|
+
'account.profile': '身份:{identity}',
|
|
123
|
+
'account.profileFailed': '身份:暂时读取失败。',
|
|
124
|
+
'account.unknownIdentity': '无显示名',
|
|
125
|
+
'account.balance': '余额:{wallets}',
|
|
126
|
+
'account.bonus': '赠额 {wallets}',
|
|
127
|
+
'account.balanceFailed': '余额:暂时读取失败。',
|
|
128
|
+
'account.balanceEmpty': '余额:未返回任何钱包。',
|
|
129
|
+
'account.attempt': '最近一次登录:{phase}',
|
|
130
|
+
'account.attemptFailed': '最近一次登录:{phase}({reason})',
|
|
131
|
+
'account.phase.initializing': '正在开始',
|
|
132
|
+
'account.phase.waiting-browser': '等待浏览器',
|
|
133
|
+
'account.phase.exchanging': '正在兑换授权码',
|
|
134
|
+
'account.phase.committing': '正在保存凭据',
|
|
135
|
+
'account.phase.succeeded': '已登录',
|
|
136
|
+
'account.phase.cancelled': '已取消',
|
|
137
|
+
'account.phase.expired': '已过期',
|
|
138
|
+
'account.phase.failed': '失败',
|
|
139
|
+
'account.error.network': '无法连接平台',
|
|
140
|
+
'account.error.protocol': '平台返回异常',
|
|
141
|
+
'account.error.expired': '尝试超时',
|
|
142
|
+
'account.error.storage': '凭据存储拒绝写入',
|
|
143
|
+
'account.links': '用量:{usage} · 充值:{topUp}',
|
|
144
|
+
'account.hintSignedIn': '/account logout 在本机退出登录。',
|
|
145
|
+
'account.hintSignedOut': '/account login 打开浏览器登录。',
|
|
146
|
+
'account.unavailable': '当前部署没有挂载 DeepSeek 账号服务。',
|
|
147
|
+
'account.noCallback': '账号登录需要回环回调服务,它已被关闭(DSCODE_ACCOUNT_LOGIN=0)。',
|
|
148
|
+
'account.usage': '用法:/account [login|cancel|logout]',
|
|
149
|
+
'account.startFailed': '登录没有启动。',
|
|
150
|
+
'account.nothingToCancel': '当前没有正在进行的登录。',
|
|
151
|
+
'account.starting': '正在通过浏览器登录 DeepSeek……',
|
|
152
|
+
'account.browserOpened': '已打开浏览器,请在那里完成登录,完成后会回到本机。',
|
|
153
|
+
'account.browserManual': '打开这个地址完成登录:',
|
|
86
154
|
},
|
|
87
155
|
'zh-TW': {
|
|
88
156
|
'activity.replying': '正在回覆', 'activity.thinking': '正在思考', 'activity.running': '正在執行',
|
|
@@ -113,6 +181,40 @@ export const MESSAGES = {
|
|
|
113
181
|
'doctor.noRoute': '沒有可用的模型路由,無法執行模型分析。',
|
|
114
182
|
'doctor.scope': '證據範圍:{traces} 個近期工作階段、{logs} 筆 warning/error;未讀取對話內容、工具參數或工具輸出。',
|
|
115
183
|
'doctor.failed': '模型分析未完成:{error}。',
|
|
184
|
+
'account.signedIn': 'DeepSeek 帳號:本機已登入(此處不重新驗證憑證是否仍被服務端接受)。',
|
|
185
|
+
'account.signedOut': 'DeepSeek 帳號:未登入。DeepSeek 路由將回退到 API key。',
|
|
186
|
+
'account.profile': '身分:{identity}',
|
|
187
|
+
'account.profileFailed': '身分:暫時讀取失敗。',
|
|
188
|
+
'account.unknownIdentity': '無顯示名稱',
|
|
189
|
+
'account.balance': '餘額:{wallets}',
|
|
190
|
+
'account.bonus': '贈額 {wallets}',
|
|
191
|
+
'account.balanceFailed': '餘額:暫時讀取失敗。',
|
|
192
|
+
'account.balanceEmpty': '餘額:未回傳任何錢包。',
|
|
193
|
+
'account.attempt': '最近一次登入:{phase}',
|
|
194
|
+
'account.attemptFailed': '最近一次登入:{phase}({reason})',
|
|
195
|
+
'account.phase.initializing': '正在開始',
|
|
196
|
+
'account.phase.waiting-browser': '等待瀏覽器',
|
|
197
|
+
'account.phase.exchanging': '正在兌換授權碼',
|
|
198
|
+
'account.phase.committing': '正在儲存憑證',
|
|
199
|
+
'account.phase.succeeded': '已登入',
|
|
200
|
+
'account.phase.cancelled': '已取消',
|
|
201
|
+
'account.phase.expired': '已過期',
|
|
202
|
+
'account.phase.failed': '失敗',
|
|
203
|
+
'account.error.network': '無法連線平台',
|
|
204
|
+
'account.error.protocol': '平台回應異常',
|
|
205
|
+
'account.error.expired': '嘗試逾時',
|
|
206
|
+
'account.error.storage': '憑證儲存拒絕寫入',
|
|
207
|
+
'account.links': '用量:{usage} · 充值:{topUp}',
|
|
208
|
+
'account.hintSignedIn': '/account logout 在本機登出。',
|
|
209
|
+
'account.hintSignedOut': '/account login 開啟瀏覽器登入。',
|
|
210
|
+
'account.unavailable': '目前部署沒有掛載 DeepSeek 帳號服務。',
|
|
211
|
+
'account.noCallback': '帳號登入需要回環回呼服務,它已被關閉(DSCODE_ACCOUNT_LOGIN=0)。',
|
|
212
|
+
'account.usage': '用法:/account [login|cancel|logout]',
|
|
213
|
+
'account.startFailed': '登入沒有啟動。',
|
|
214
|
+
'account.nothingToCancel': '目前沒有進行中的登入。',
|
|
215
|
+
'account.starting': '正在透過瀏覽器登入 DeepSeek……',
|
|
216
|
+
'account.browserOpened': '已開啟瀏覽器,請在那裡完成登入,完成後會回到本機。',
|
|
217
|
+
'account.browserManual': '開啟這個網址完成登入:',
|
|
116
218
|
},
|
|
117
219
|
ja: {
|
|
118
220
|
'activity.replying': '応答中', 'activity.thinking': '思考中', 'activity.running': '実行中',
|
|
@@ -143,6 +245,40 @@ export const MESSAGES = {
|
|
|
143
245
|
'doctor.noRoute': '利用できるモデルルートがないため、モデル分析を実行できません。',
|
|
144
246
|
'doctor.scope': '根拠の範囲:直近のセッション {traces} 件、warning/error {logs} 件。会話本文、ツール引数、ツール出力は読んでいません。',
|
|
145
247
|
'doctor.failed': 'モデル分析が完了しませんでした:{error}。',
|
|
248
|
+
'account.signedIn': 'DeepSeek アカウント:このマシンでサインイン済み(保存済み認可の有効性はここでは再確認しません)。',
|
|
249
|
+
'account.signedOut': 'DeepSeek アカウント:サインアウト。DeepSeek ルートは API キーにフォールバックします。',
|
|
250
|
+
'account.profile': 'アカウント:{identity}',
|
|
251
|
+
'account.profileFailed': 'アカウント:今は取得できませんでした。',
|
|
252
|
+
'account.unknownIdentity': '表示名なし',
|
|
253
|
+
'account.balance': '残高:{wallets}',
|
|
254
|
+
'account.bonus': 'ボーナス {wallets}',
|
|
255
|
+
'account.balanceFailed': '残高:今は取得できませんでした。',
|
|
256
|
+
'account.balanceEmpty': '残高:ウォレットの報告がありません。',
|
|
257
|
+
'account.attempt': '直近のサインイン:{phase}',
|
|
258
|
+
'account.attemptFailed': '直近のサインイン:{phase}({reason})',
|
|
259
|
+
'account.phase.initializing': '開始中',
|
|
260
|
+
'account.phase.waiting-browser': 'ブラウザ待ち',
|
|
261
|
+
'account.phase.exchanging': 'コード交換中',
|
|
262
|
+
'account.phase.committing': '認可を保存中',
|
|
263
|
+
'account.phase.succeeded': 'サインイン済み',
|
|
264
|
+
'account.phase.cancelled': 'キャンセル',
|
|
265
|
+
'account.phase.expired': '期限切れ',
|
|
266
|
+
'account.phase.failed': '失敗',
|
|
267
|
+
'account.error.network': 'プラットフォームに接続できません',
|
|
268
|
+
'account.error.protocol': 'プラットフォームの応答が不正です',
|
|
269
|
+
'account.error.expired': 'タイムアウトしました',
|
|
270
|
+
'account.error.storage': '認証情報ストアが保存を拒否しました',
|
|
271
|
+
'account.links': '使用量:{usage} · チャージ:{topUp}',
|
|
272
|
+
'account.hintSignedIn': '/account logout でこのマシンからサインアウトします。',
|
|
273
|
+
'account.hintSignedOut': '/account login でブラウザを開いてサインインします。',
|
|
274
|
+
'account.unavailable': 'この構成には DeepSeek アカウントサービスがありません。',
|
|
275
|
+
'account.noCallback': 'アカウントサインインにはループバックのコールバックサーバーが必要ですが、無効です(DSCODE_ACCOUNT_LOGIN=0)。',
|
|
276
|
+
'account.usage': '使い方:/account [login|cancel|logout]',
|
|
277
|
+
'account.startFailed': 'サインインを開始できませんでした。',
|
|
278
|
+
'account.nothingToCancel': '進行中のサインインはありません。',
|
|
279
|
+
'account.starting': 'ブラウザで DeepSeek にサインインしています……',
|
|
280
|
+
'account.browserOpened': 'ブラウザを開きました。そこでサインインを完了すると、このマシンに戻ります。',
|
|
281
|
+
'account.browserManual': 'この URL を開いてサインインを完了してください:',
|
|
146
282
|
},
|
|
147
283
|
ko: {
|
|
148
284
|
'activity.replying': '응답 중', 'activity.thinking': '생각 중', 'activity.running': '실행 중',
|
|
@@ -173,6 +309,40 @@ export const MESSAGES = {
|
|
|
173
309
|
'doctor.noRoute': '사용 가능한 모델 경로가 없어 모델 분석을 실행할 수 없습니다.',
|
|
174
310
|
'doctor.scope': '근거 범위: 최근 세션 {traces}개, warning/error {logs}건. 대화 본문, 도구 인수, 도구 출력은 읽지 않았습니다.',
|
|
175
311
|
'doctor.failed': '모델 분석이 완료되지 않았습니다: {error}.',
|
|
312
|
+
'account.signedIn': 'DeepSeek 계정: 이 기기에서 로그인됨(저장된 인증이 여전히 유효한지는 여기서 다시 확인하지 않습니다).',
|
|
313
|
+
'account.signedOut': 'DeepSeek 계정: 로그아웃 상태. DeepSeek 경로는 API 키로 대체됩니다.',
|
|
314
|
+
'account.profile': '계정: {identity}',
|
|
315
|
+
'account.profileFailed': '계정: 지금은 읽을 수 없습니다.',
|
|
316
|
+
'account.unknownIdentity': '표시 이름 없음',
|
|
317
|
+
'account.balance': '잔액: {wallets}',
|
|
318
|
+
'account.bonus': '보너스 {wallets}',
|
|
319
|
+
'account.balanceFailed': '잔액: 지금은 읽을 수 없습니다.',
|
|
320
|
+
'account.balanceEmpty': '잔액: 보고된 지갑이 없습니다.',
|
|
321
|
+
'account.attempt': '최근 로그인: {phase}',
|
|
322
|
+
'account.attemptFailed': '최근 로그인: {phase} ({reason})',
|
|
323
|
+
'account.phase.initializing': '시작 중',
|
|
324
|
+
'account.phase.waiting-browser': '브라우저 대기 중',
|
|
325
|
+
'account.phase.exchanging': '코드 교환 중',
|
|
326
|
+
'account.phase.committing': '인증 저장 중',
|
|
327
|
+
'account.phase.succeeded': '로그인됨',
|
|
328
|
+
'account.phase.cancelled': '취소됨',
|
|
329
|
+
'account.phase.expired': '만료됨',
|
|
330
|
+
'account.phase.failed': '실패',
|
|
331
|
+
'account.error.network': '플랫폼에 연결할 수 없습니다',
|
|
332
|
+
'account.error.protocol': '플랫폼 응답이 올바르지 않습니다',
|
|
333
|
+
'account.error.expired': '시간이 초과되었습니다',
|
|
334
|
+
'account.error.storage': '자격 증명 저장소가 저장을 거부했습니다',
|
|
335
|
+
'account.links': '사용량: {usage} · 충전: {topUp}',
|
|
336
|
+
'account.hintSignedIn': '/account logout 으로 이 기기에서 로그아웃합니다.',
|
|
337
|
+
'account.hintSignedOut': '/account login 으로 브라우저를 열어 로그인합니다.',
|
|
338
|
+
'account.unavailable': '이 구성에는 DeepSeek 계정 서비스가 없습니다.',
|
|
339
|
+
'account.noCallback': '계정 로그인에는 루프백 콜백 서버가 필요하지만 비활성화되어 있습니다(DSCODE_ACCOUNT_LOGIN=0).',
|
|
340
|
+
'account.usage': '사용법: /account [login|cancel|logout]',
|
|
341
|
+
'account.startFailed': '로그인이 시작되지 않았습니다.',
|
|
342
|
+
'account.nothingToCancel': '진행 중인 로그인이 없습니다.',
|
|
343
|
+
'account.starting': '브라우저로 DeepSeek에 로그인하고 있습니다……',
|
|
344
|
+
'account.browserOpened': '브라우저를 열었습니다. 거기서 로그인을 완료하면 이 기기로 돌아옵니다.',
|
|
345
|
+
'account.browserManual': '이 URL을 열어 로그인을 완료하세요:',
|
|
176
346
|
},
|
|
177
347
|
es: {
|
|
178
348
|
'activity.replying': 'Respondiendo', 'activity.thinking': 'Pensando', 'activity.running': 'Ejecutando',
|
|
@@ -203,6 +373,40 @@ export const MESSAGES = {
|
|
|
203
373
|
'doctor.noRoute': 'No hay una ruta de modelo disponible, así que el análisis con modelo no se pudo ejecutar.',
|
|
204
374
|
'doctor.scope': 'Alcance de la evidencia: {traces} sesiones recientes, {logs} warnings/errores; no se leyó el texto de la conversación, los argumentos ni la salida de las herramientas.',
|
|
205
375
|
'doctor.failed': 'El análisis con modelo no terminó: {error}.',
|
|
376
|
+
'account.signedIn': 'Cuenta DeepSeek: sesión iniciada en esta máquina (aquí no se vuelve a comprobar la concesión guardada).',
|
|
377
|
+
'account.signedOut': 'Cuenta DeepSeek: sin sesión. La ruta DeepSeek recurre a una clave de API.',
|
|
378
|
+
'account.profile': 'Identidad: {identity}',
|
|
379
|
+
'account.profileFailed': 'Identidad: no se pudo leer ahora.',
|
|
380
|
+
'account.unknownIdentity': 'sin nombre visible',
|
|
381
|
+
'account.balance': 'Saldo: {wallets}',
|
|
382
|
+
'account.bonus': 'bonificación {wallets}',
|
|
383
|
+
'account.balanceFailed': 'Saldo: no se pudo leer ahora.',
|
|
384
|
+
'account.balanceEmpty': 'Saldo: ninguna cartera informada.',
|
|
385
|
+
'account.attempt': 'Último inicio de sesión: {phase}',
|
|
386
|
+
'account.attemptFailed': 'Último inicio de sesión: {phase} ({reason})',
|
|
387
|
+
'account.phase.initializing': 'iniciando',
|
|
388
|
+
'account.phase.waiting-browser': 'esperando el navegador',
|
|
389
|
+
'account.phase.exchanging': 'canjeando el código',
|
|
390
|
+
'account.phase.committing': 'guardando la concesión',
|
|
391
|
+
'account.phase.succeeded': 'sesión iniciada',
|
|
392
|
+
'account.phase.cancelled': 'cancelado',
|
|
393
|
+
'account.phase.expired': 'caducado',
|
|
394
|
+
'account.phase.failed': 'fallido',
|
|
395
|
+
'account.error.network': 'no se pudo contactar con la plataforma',
|
|
396
|
+
'account.error.protocol': 'la plataforma respondió de forma inesperada',
|
|
397
|
+
'account.error.expired': 'el intento caducó',
|
|
398
|
+
'account.error.storage': 'el almacén de credenciales rechazó la concesión',
|
|
399
|
+
'account.links': 'Uso: {usage} · Recarga: {topUp}',
|
|
400
|
+
'account.hintSignedIn': '/account logout cierra la sesión en esta máquina.',
|
|
401
|
+
'account.hintSignedOut': '/account login abre el navegador para iniciar sesión.',
|
|
402
|
+
'account.unavailable': 'Esta composición no incluye el servicio de cuenta DeepSeek.',
|
|
403
|
+
'account.noCallback': 'El inicio de sesión necesita el servidor de retorno en loopback; está desactivado (DSCODE_ACCOUNT_LOGIN=0).',
|
|
404
|
+
'account.usage': 'Uso: /account [login|cancel|logout]',
|
|
405
|
+
'account.startFailed': 'El inicio de sesión no comenzó.',
|
|
406
|
+
'account.nothingToCancel': 'No hay ningún inicio de sesión en curso.',
|
|
407
|
+
'account.starting': 'Iniciando sesión en DeepSeek a través del navegador…',
|
|
408
|
+
'account.browserOpened': 'Se abrió el navegador. Termina ahí el inicio de sesión y volverá a esta máquina.',
|
|
409
|
+
'account.browserManual': 'Abre esta URL para terminar el inicio de sesión:',
|
|
206
410
|
},
|
|
207
411
|
};
|
|
208
412
|
|
package/plugins/memory/index.mjs
CHANGED
|
@@ -48,7 +48,7 @@ export function apply(ctx, options = {}) {
|
|
|
48
48
|
await chargeTo(live.has(lastSession) ? lastSession : undefined, 'memory', async () => {
|
|
49
49
|
for await (const chunk of ctx.llm.stream({
|
|
50
50
|
...target, ...(reasoningEffort ? { reasoningEffort } : {}),
|
|
51
|
-
system, messages: [createUserMessage({ content: [{ type: 'text', text: JSON.stringify(input) }], source: { kind:
|
|
51
|
+
system, messages: [createUserMessage({ content: [{ type: 'text', text: JSON.stringify(input) }], source: { kind: name } })],
|
|
52
52
|
maxTokens: 12000, signal: deadline,
|
|
53
53
|
})) {
|
|
54
54
|
deadline.throwIfAborted(); assembler.push(chunk);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Producer identity of one message source.
|
|
3
|
+
*
|
|
4
|
+
* DSH 0.1.7 retired the shared `plugin` kind: every producer now declares its own
|
|
5
|
+
* `kind`, and DSCODE's plugins name themselves the same way. Durable history carries two
|
|
6
|
+
* older shapes — the raw `{ kind: 'plugin', plugin: '<producer>' }` of a session written
|
|
7
|
+
* before the upgrade, and the `plugin:<producer>` kind the session format's v3-to-v4
|
|
8
|
+
* migration writes for a producer it does not know — so every reader of history resolves
|
|
9
|
+
* all three through this one function.
|
|
10
|
+
*
|
|
11
|
+
* @param source - a message source from any release.
|
|
12
|
+
* @returns the producing subsystem's name, or `''` when the source names none.
|
|
13
|
+
*/
|
|
14
|
+
export function producerKind(source) {
|
|
15
|
+
if (source === null || typeof source !== 'object') return '';
|
|
16
|
+
const { kind, plugin } = source;
|
|
17
|
+
if (kind === 'plugin') return typeof plugin === 'string' ? plugin : '';
|
|
18
|
+
if (typeof kind !== 'string') return '';
|
|
19
|
+
return kind.startsWith('plugin:') ? kind.slice('plugin:'.length) : kind;
|
|
20
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LlmAdapter, LlmError, ReasoningEffortId, attributionHeaders, contentHasImage,
|
|
1
|
+
import { IMAGE_OFFLOAD_REQUIRED_CODE, LlmAdapter, LlmError, ReasoningEffortId, attributionHeaders, contentHasImage, offloadedImageText, projectOffloadedImages, requiredImageOffload } from '@deepseek-ai/dsh-llm';
|
|
2
2
|
import { listOpenRouterModels, openRouterModel } from './models.mjs';
|
|
3
3
|
import { PROVIDER, effortInfo, errorCode, errorMessage, modelReasoning, requestBody, retryAfterMs, sseData, translate } from './wire.mjs';
|
|
4
4
|
|
|
@@ -157,22 +157,38 @@ export class OpenRouterAdapter extends LlmAdapter {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
/**
|
|
160
|
+
/**
|
|
161
|
+
* Read request versions of every retained image.
|
|
162
|
+
*
|
|
163
|
+
* DSH 0.1.7 made the offloaded set a durable surface fact: a route projects what the
|
|
164
|
+
* surface already offloaded into text and reports how much more must go with
|
|
165
|
+
* `IMAGE_OFFLOAD_REQUIRED`, instead of dropping the oldest occurrences itself. The
|
|
166
|
+
* `compaction-image-offload` executor records that choice and retries, so the decision
|
|
167
|
+
* survives a route change, resume and replay rather than being remade per request.
|
|
168
|
+
*/
|
|
161
169
|
async prepareImages(options, entry, connection, signal) {
|
|
162
|
-
if (!options.messages.some(message => contentHasImage(message.content))) return undefined;
|
|
163
|
-
if (!entry?.inputModalities?.includes('image')) throw new LlmError(`OpenRouter model "${options.model}" does not accept image input.`, 'UNSUPPORTED_CONTENT');
|
|
164
170
|
const attachments = this.config.resolveAttachments?.();
|
|
171
|
+
const access = ref => (attachments === undefined ? undefined : this.config.resolveImageAccess?.(attachments, ref));
|
|
172
|
+
const messages = projectOffloadedImages(options.messages, ref => offloadedImageText(ref, access(ref)));
|
|
173
|
+
const withImages = messages.some(message => contentHasImage(message.content));
|
|
174
|
+
if (!withImages) return messages === options.messages ? undefined : { options: { ...options, messages: [...messages] }, versions: new Map(), access };
|
|
175
|
+
if (!entry?.inputModalities?.includes('image')) throw new LlmError(`OpenRouter model "${options.model}" does not accept image input.`, 'UNSUPPORTED_CONTENT');
|
|
165
176
|
if (attachments === undefined) throw new LlmError('OpenRouter image input requires the durable attachment service.', 'UNSUPPORTED_CONTENT');
|
|
166
|
-
const access = ref => this.config.resolveImageAccess?.(attachments, ref);
|
|
167
|
-
const bounded = policyBytes => offloadRequestImagesWithPolicy(policyBytes.messages, {
|
|
168
|
-
representation: 'base64', maxBytes: connection.maxRequestImageBytes, byteQuantum: 1,
|
|
169
|
-
byteLength: policyBytes.byteLength, placeholder: ref => offloadedImageText(ref, access(ref)),
|
|
170
|
-
});
|
|
171
|
-
const estimated = bounded({ messages: options.messages, byteLength: ref => Math.min(ref.bytes, IMAGE_POLICY.maxBytes) });
|
|
172
177
|
const refs = new Map();
|
|
173
|
-
for (const message of
|
|
178
|
+
for (const message of messages) collectImages(message.content, refs);
|
|
174
179
|
const versions = new Map(await Promise.all([...refs.values()].map(async ref => [ref.attachmentId, await attachments.readImageRequest(ref, IMAGE_POLICY, signal)])));
|
|
175
|
-
const
|
|
176
|
-
|
|
180
|
+
const offloadImages = requiredImageOffload(
|
|
181
|
+
messages,
|
|
182
|
+
{ representation: 'base64', maxBytes: connection.maxRequestImageBytes, byteQuantum: 1 },
|
|
183
|
+
block => versions.get(block.attachment.attachmentId).bytes,
|
|
184
|
+
);
|
|
185
|
+
if (offloadImages > 0) {
|
|
186
|
+
throw new LlmError(
|
|
187
|
+
`OpenRouter request images exceed ${connection.maxRequestImageBytes} bytes; ${offloadImages} more oldest occurrence(s) must be offloaded.`,
|
|
188
|
+
IMAGE_OFFLOAD_REQUIRED_CODE,
|
|
189
|
+
{ offloadImages },
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
return { options: { ...options, messages: [...messages] }, versions, access };
|
|
177
193
|
}
|
|
178
194
|
}
|
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
import z from '@deepseek-ai/schemastery';
|
|
2
2
|
import { LlmError, RetryPolicySchema, assertUsableApiKey, resolveImageAttachmentAccess, resolveRetryPolicy } from '@deepseek-ai/dsh-llm';
|
|
3
3
|
import { credentialRef } from '@deepseek-ai/dsh-credentials';
|
|
4
|
+
import { deepEqualJson } from '@deepseek-ai/dsh-util-values';
|
|
5
|
+
import { plainConfig } from '../cordis-config/plain.mjs';
|
|
4
6
|
import { launchEnvironmentOf } from '@deepseek-ai/dsh-launch-environment';
|
|
5
7
|
import { OpenRouterAdapter, PROVIDER } from './adapter.mjs';
|
|
6
8
|
import { ensureOpenRouterModels } from './models.mjs';
|
|
7
9
|
import { OpenRouterSearchProvider, RoutedSearchProvider } from './search.mjs';
|
|
8
10
|
|
|
9
11
|
// The `openrouter` route: DSCODE's own OpenRouter adapter over its live model
|
|
10
|
-
// listing, configured by
|
|
11
|
-
//
|
|
12
|
+
// listing, configured by this entry's own profile row, plus web search that
|
|
13
|
+
// follows the session's route.
|
|
12
14
|
export const name = 'dscode-openrouter';
|
|
13
15
|
export const inject = ['llm'];
|
|
14
16
|
const NS = 'llm-openrouter';
|
|
15
17
|
const DEFAULT_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
16
18
|
|
|
19
|
+
// DSH 0.1.7 replaced settings sections with volatile configuration: a field marked
|
|
20
|
+
// `.volatile()` reaches the plugin as a reference the Settings form and a profile edit
|
|
21
|
+
// both write, so each read below sees the current value without a change callback.
|
|
17
22
|
export const Config = z.object({
|
|
18
|
-
apiKeyEnv: z.string().role('credential-ref').default('OPENROUTER_API_KEY'),
|
|
19
|
-
baseURL: z.string().default(DEFAULT_BASE_URL),
|
|
20
|
-
streamIdleTimeoutMs: z.number().min(1).default(300000),
|
|
21
|
-
maxRequestImageBytes: z.number().step(1).min(1).default(20 * 1024 * 1024),
|
|
22
|
-
searchModel: z.string().default('deepseek/deepseek-v4-flash'),
|
|
23
|
-
retryPolicy: RetryPolicySchema,
|
|
23
|
+
apiKeyEnv: z.string().role('credential-ref').default('OPENROUTER_API_KEY').volatile(),
|
|
24
|
+
baseURL: z.string().default(DEFAULT_BASE_URL).volatile(),
|
|
25
|
+
streamIdleTimeoutMs: z.number().min(1).default(300000).volatile(),
|
|
26
|
+
maxRequestImageBytes: z.number().step(1).min(1).default(20 * 1024 * 1024).volatile(),
|
|
27
|
+
searchModel: z.string().default('deepseek/deepseek-v4-flash').volatile(),
|
|
28
|
+
retryPolicy: RetryPolicySchema.volatile(),
|
|
24
29
|
});
|
|
25
30
|
|
|
31
|
+
|
|
26
32
|
/** Validated connection facts from one config snapshot. */
|
|
27
33
|
export function resolveOptions(config = {}) {
|
|
28
34
|
const streamIdleTimeoutMs = config.streamIdleTimeoutMs ?? 300000;
|
|
@@ -40,18 +46,18 @@ export function resolveOptions(config = {}) {
|
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
export function apply(ctx, config = {}) {
|
|
43
|
-
|
|
49
|
+
// The TUI renders this route's own page, so Settings must not generate a form for it.
|
|
50
|
+
ctx.inject(['settings'], settingsCtx => {
|
|
51
|
+
settingsCtx.effect(() => settingsCtx.settings.configure({ auto: false }, ctx.fiber));
|
|
52
|
+
});
|
|
53
|
+
let lastGood;
|
|
44
54
|
const options = () => {
|
|
45
|
-
const raw = current();
|
|
46
|
-
if (raw === lastRaw && lastGood !== undefined) return lastGood;
|
|
47
55
|
try {
|
|
48
|
-
lastGood = resolveOptions(
|
|
49
|
-
lastRaw = raw;
|
|
56
|
+
lastGood = resolveOptions(plainConfig(config));
|
|
50
57
|
return lastGood;
|
|
51
58
|
} catch (error) {
|
|
52
59
|
if (lastGood === undefined) throw error;
|
|
53
|
-
|
|
54
|
-
ctx.logger.error(`${name}: keeping the last good configuration after an invalid settings section`);
|
|
60
|
+
ctx.logger.error(`${name}: keeping the last good configuration after an invalid edit`);
|
|
55
61
|
ctx.logger.error(error);
|
|
56
62
|
return lastGood;
|
|
57
63
|
}
|
|
@@ -75,20 +81,17 @@ export function apply(ctx, config = {}) {
|
|
|
75
81
|
resolveAttachments: () => ctx.get('attachments'),
|
|
76
82
|
resolveImageAccess: (attachments, ref) => resolveImageAttachmentAccess(attachments, hostPath => ctx.get('fs')?.processPathFromHostPath(hostPath), ref),
|
|
77
83
|
});
|
|
78
|
-
ctx.llm.registerConfigurableProviders([{ provider: PROVIDER, displayName: 'OpenRouter', settingsNs: NS, settingsPath: [] }]);
|
|
84
|
+
ctx.llm.registerConfigurableProviders([{ provider: PROVIDER, displayName: 'OpenRouter', settingsNs: ctx.fiber.entry?.options.id ?? NS, settingsPath: [] }]);
|
|
79
85
|
const registration = ctx.llm.registerAdapter([PROVIDER], adapter);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
registeredPolicy = policy;
|
|
90
|
-
},
|
|
91
|
-
});
|
|
86
|
+
// The retry policy is captured at registration, and a reference carries no change
|
|
87
|
+
// callback: re-register the route when an edit lands on a different policy.
|
|
88
|
+
let registeredPolicy = options().retryPolicy;
|
|
89
|
+
ctx.on('loader/volatile-update', () => {
|
|
90
|
+
let policy;
|
|
91
|
+
try { policy = options().retryPolicy; } catch (error) { ctx.logger.warn(error); return; }
|
|
92
|
+
if (deepEqualJson(policy, registeredPolicy)) return;
|
|
93
|
+
registration.replace([PROVIDER]);
|
|
94
|
+
registeredPolicy = policy;
|
|
92
95
|
});
|
|
93
96
|
ctx.inject(['web'], webCtx => {
|
|
94
97
|
const openrouter = new OpenRouterSearchProvider(() => {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createUserMessage, freezeMessage } from '@deepseek-ai/dsh-llm';
|
|
2
2
|
import { Mailbox, fail } from './mailbox.mjs';
|
|
3
|
+
import { producerKind } from '../message-source/kind.mjs';
|
|
3
4
|
import { discover, request as socketRequest } from './client.mjs';
|
|
4
5
|
|
|
5
6
|
const plugin = 'dscode-session-bridge';
|
|
6
|
-
export const communicationId = m => m?.source
|
|
7
|
+
export const communicationId = m => producerKind(m?.source) === plugin ? m.source.communicationId : undefined;
|
|
7
8
|
export const isHuman = m => ['user', 'human'].includes(m?.source?.kind);
|
|
8
9
|
const eligible = a => a?.session.header.agentPreset === 'dscode' || a?.session.header.origin === 'subagent';
|
|
9
10
|
|
|
@@ -17,7 +18,9 @@ export class CommunicationService {
|
|
|
17
18
|
this.pending = new Set();
|
|
18
19
|
this.closed = false;
|
|
19
20
|
this.disposers = [
|
|
20
|
-
|
|
21
|
+
// DSH 0.1.7 retired `agent/session-start`: `agent/created` is awaited at the same
|
|
22
|
+
// point, once the session is entered and announced.
|
|
23
|
+
ctx.on('agent/created', ({ agent }) => this.start(agent)),
|
|
21
24
|
ctx.on('agent/pre-step', (payload, next) => this.preStep(payload, next)),
|
|
22
25
|
ctx.on('session/event', (session, event) => this.observe(session, event)),
|
|
23
26
|
ctx.on('agent/inbox/discarded', ({ agent, message }) => {
|
|
@@ -102,7 +105,7 @@ export class CommunicationService {
|
|
|
102
105
|
// Identity must survive retries even when the prior native inbox insertion did not persist.
|
|
103
106
|
return freezeMessage({ ...createUserMessage({ content: [{ type: 'text', text:
|
|
104
107
|
`[External source: ${e.from.kind === 'session' ? `session:${e.from.sessionId}` : e.from.source}] [${e.kind}/${e.mode}]\nMessage ID: ${e.messageId}${e.inReplyTo ? `; reply to: ${e.inReplyTo}` : ''}\n${e.text}` }],
|
|
105
|
-
source: { kind:
|
|
108
|
+
source: { kind: plugin, form: 'relay', communicationId: e.messageId, requestId: e.idempotencyKey,
|
|
106
109
|
label: e.from.kind === 'session' ? `session:${e.from.sessionId}` : e.from.source, mode: e.mode, composedAt: e.createdAt } }), id: e.messageId });
|
|
107
110
|
}
|
|
108
111
|
async confirm(state) {
|
|
@@ -5,6 +5,7 @@ import { randomUUID, createHash } from 'node:crypto';
|
|
|
5
5
|
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
6
6
|
import { normalizeSessionTitle } from '@deepseek-ai/dsh-session-title';
|
|
7
7
|
import { ensureSocketDirectory } from './paths.mjs';
|
|
8
|
+
import { producerKind } from '../message-source/kind.mjs';
|
|
8
9
|
|
|
9
10
|
export const BRIDGE_SOURCE = 'dscode-session-bridge';
|
|
10
11
|
const MAX_REQUEST = 128 * 1024, MAX_BUFFER = 8 * 1024 * 1024;
|
|
@@ -51,7 +52,7 @@ export class SessionBridge {
|
|
|
51
52
|
if (!cache) { cache = { seq: 0, values: new Map() }; this.receipts.set(session, cache); }
|
|
52
53
|
for (const event of session.snapshotEvents(cache.seq)) {
|
|
53
54
|
const messages = event.type === 'agent/inbox/spliced' ? event.data.inserted : event.type === 'user/message' ? [event.data] : [];
|
|
54
|
-
for (const message of messages) if (message.source
|
|
55
|
+
for (const message of messages) if (producerKind(message.source) === BRIDGE_SOURCE && message.source.requestId) {
|
|
55
56
|
cache.values.set(message.source.requestId, { digest: message.source.digest, messageId: message.id });
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -82,7 +83,7 @@ export class SessionBridge {
|
|
|
82
83
|
let messageId = previous?.messageId;
|
|
83
84
|
if (!previous) {
|
|
84
85
|
const message = createUserMessage({ content: [{ type: 'text', text: `[External source: ${source}]\n${text}` }],
|
|
85
|
-
source: { kind:
|
|
86
|
+
source: { kind: BRIDGE_SOURCE, form: 'relay', requestId, digest, label: source, mode } });
|
|
86
87
|
// Explicit naming uses the native title service, including sanitization,
|
|
87
88
|
// persistence, UI events and cancellation of stale automatic title work.
|
|
88
89
|
// A duplicate request must never undo a newer title.
|
|
@@ -21,6 +21,8 @@ const MAX_WAITING_REQUESTS = 16
|
|
|
21
21
|
const MAX_PREVIEW_CHARS = 72
|
|
22
22
|
|
|
23
23
|
/** The plugin name the session bridge stamps on its relayed messages. */
|
|
24
|
+
import { producerKind } from '../message-source/kind.mjs'
|
|
25
|
+
|
|
24
26
|
const BRIDGE_PLUGIN = 'dscode-session-bridge'
|
|
25
27
|
|
|
26
28
|
/** Tool names that address another session. */
|
|
@@ -67,7 +69,7 @@ function relayFields(data) {
|
|
|
67
69
|
if (data === null || typeof data !== 'object') return undefined
|
|
68
70
|
const source = data.source
|
|
69
71
|
if (source === null || typeof source !== 'object') return undefined
|
|
70
|
-
if (source
|
|
72
|
+
if (producerKind(source) !== BRIDGE_PLUGIN || source.form !== 'relay') return undefined
|
|
71
73
|
const label = typeof source.label === 'string' && source.label !== '' ? source.label : undefined
|
|
72
74
|
const id = typeof source.communicationId === 'string' && source.communicationId !== '' ? source.communicationId : undefined
|
|
73
75
|
if (label === undefined && id === undefined) return undefined
|
|
@@ -16,7 +16,7 @@ export function apply(ctx, config = {}) {
|
|
|
16
16
|
const reasoningEffort = await effortFor(ctx.llm, base, 'low', signal);
|
|
17
17
|
await chargeTo(sessionId, 'session-card', async () => {
|
|
18
18
|
for await (const chunk of ctx.llm.stream({ ...base, ...(reasoningEffort ? { reasoningEffort } : {}), system: TOPIC_PROMPT,
|
|
19
|
-
messages: [createUserMessage({ content: [{ type: 'text', text: JSON.stringify(input) }], source: { kind:
|
|
19
|
+
messages: [createUserMessage({ content: [{ type: 'text', text: JSON.stringify(input) }], source: { kind: name } })],
|
|
20
20
|
maxTokens: 2000, signal })) {
|
|
21
21
|
signal.throwIfAborted(); assembler.push(chunk);
|
|
22
22
|
if (chunk.type === 'finish') finished = true;
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import z from '@deepseek-ai/schemastery';
|
|
13
13
|
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
14
14
|
import { arrivalMark, resolveTimeZone, turnEndMark } from './marks.mjs';
|
|
15
|
+
import { producerKind } from '../message-source/kind.mjs';
|
|
15
16
|
export const name = 'dscode-time-marks';
|
|
16
17
|
export const Config = z.object({
|
|
17
18
|
/** Fallback display zone; empty uses the host zone. */
|
|
@@ -42,7 +43,7 @@ export function apply(ctx, config = {}) {
|
|
|
42
43
|
for (const message of payload.messages) {
|
|
43
44
|
// Marks are injected context, never an inbox arrival; skipping our own
|
|
44
45
|
// producer keeps a future delivery path from marking itself.
|
|
45
|
-
if (message.source
|
|
46
|
+
if (producerKind(message.source) === name) continue;
|
|
46
47
|
const line = arrivalMark(message, at, timeZone);
|
|
47
48
|
if (line !== null && lines.length < MARK_LIMIT) lines.push(line);
|
|
48
49
|
}
|
|
@@ -60,7 +61,7 @@ export function apply(ctx, config = {}) {
|
|
|
60
61
|
// the prompt there, not this mark.
|
|
61
62
|
messages: [createUserMessage({
|
|
62
63
|
content: [{ type: 'text', text: lines.join('\n') }],
|
|
63
|
-
source: { kind:
|
|
64
|
+
source: { kind: name, form: 'snapshot' },
|
|
64
65
|
}), ...decision.messages],
|
|
65
66
|
};
|
|
66
67
|
}, { prepend: true });
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* @module dscode-time-marks/marks
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { producerKind } from '../message-source/kind.mjs'
|
|
11
|
+
|
|
10
12
|
/** Shortest queue wait worth naming; below it the message simply arrived. */
|
|
11
13
|
const WAIT_FLOOR_MS = 1_000
|
|
12
14
|
|
|
@@ -108,15 +110,14 @@ export function elapsedText(ms) {
|
|
|
108
110
|
* @returns the attribution clause.
|
|
109
111
|
*/
|
|
110
112
|
export function describeSource(source) {
|
|
111
|
-
const
|
|
112
|
-
if (
|
|
113
|
-
if (
|
|
114
|
-
if (source.form === 'relay') {
|
|
113
|
+
const producer = producerKind(source)
|
|
114
|
+
if (producer === 'user') return 'user message'
|
|
115
|
+
if (source?.form === 'relay') {
|
|
115
116
|
const mode = plain(source.mode) || 'queue'
|
|
116
117
|
const label = plain(source.label) || 'another session'
|
|
117
118
|
return `${mode} relay from ${label}`
|
|
118
119
|
}
|
|
119
|
-
return `message from ${
|
|
120
|
+
return producer === '' ? 'message' : `message from ${producer}`
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
/**
|
|
@@ -34,7 +34,7 @@ export const DEFAULTS = Object.freeze({
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
/** Permission presets an unattended run may use; `ask` can never complete. */
|
|
37
|
-
const UNATTENDED_PERMISSIONS = Object.freeze(['auto', 'workspace-write', 'read-only', 'danger-full-access']);
|
|
37
|
+
const UNATTENDED_PERMISSIONS = Object.freeze(['auto-review', 'auto', 'workspace-write', 'read-only', 'danger-full-access']);
|
|
38
38
|
|
|
39
39
|
const ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/u;
|
|
40
40
|
|
|
@@ -12,7 +12,7 @@ export function mutationProblem(ctx, agent) {
|
|
|
12
12
|
const plan = ctx.get('planMode')?.get(agent);
|
|
13
13
|
if (plan?.active || plan?.pending) return 'Schedule management is unavailable in plan mode';
|
|
14
14
|
const permission = ctx.permissionPresets.current(agent.session);
|
|
15
|
-
if (!['auto', 'ask', 'workspace-write', 'danger-full-access'].includes(permission)) return 'Schedule management requires a writable permission preset';
|
|
15
|
+
if (!['auto-review', 'auto', 'ask', 'workspace-write', 'danger-full-access'].includes(permission)) return 'Schedule management requires a writable permission preset';
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export function registerTriggerTools(ctx, { home, ...deps }) {
|
|
@@ -131,7 +131,7 @@ export async function analyzeDoctorEvidence(ctx, evidence, route, signal, { mode
|
|
|
131
131
|
const reasoningEffort = await effortFor(ctx.llm, route, 'low', deadline);
|
|
132
132
|
await chargeTo(sessionId, 'doctor', async () => {
|
|
133
133
|
for await (const chunk of ctx.llm.stream({ provider: route.provider, model: route.model, ...(reasoningEffort ? { reasoningEffort } : {}), maxTokens: 4096, system: SYSTEM,
|
|
134
|
-
messages: [createUserMessage({ content: [{ type: 'text', text: JSON.stringify(evidence) }], source: { kind: '
|
|
134
|
+
messages: [createUserMessage({ content: [{ type: 'text', text: JSON.stringify(evidence) }], source: { kind: 'dscode-doctor' } })], signal: deadline })) {
|
|
135
135
|
deadline.throwIfAborted(); assembler.push(chunk);
|
|
136
136
|
if (chunk.type === 'finish') finished = true;
|
|
137
137
|
}
|