fix(web): align core profile with RL prompt
This commit is contained in:
@@ -1,6 +1,26 @@
|
||||
# Opt-in two-tool profile over the shipped Web composition. The default native
|
||||
# model surface is exactly persistent `bash` plus `str_replace_editor`; the
|
||||
# Web host, browser shell, workspace, persistence, and permission stack remain.
|
||||
# Opt-in Web shell for the RL core agent contract. The model receives exactly
|
||||
# the configured persona plus the native `bash` and `str_replace_editor`
|
||||
# schemas; the Web host, browser shell, persistence, and permission stack stay.
|
||||
|
||||
# Match the Claude SWE-compatible RL core prompt. The launcher-owned Web
|
||||
# orientation is a separate plugin so disabling it removes both its prompt
|
||||
# sections without a path-specific launcher branch. Workspace instructions are
|
||||
# model-visible user context rather than a system section, but RL core disables
|
||||
# them as part of the same prompt contract.
|
||||
- id: system-prompt
|
||||
config:
|
||||
includeHarnessIdentity: false
|
||||
persona: !!js process.env.DSH_SYSTEM_PROMPT ?? 'You are a helpful software engineer assistant.'
|
||||
|
||||
- id: web-runtime-context
|
||||
disabled: true
|
||||
|
||||
- id: workspace-context
|
||||
disabled: true
|
||||
|
||||
- id: tools
|
||||
config:
|
||||
mode: native
|
||||
|
||||
# Disable every model-facing consumer in the base/Web tree. plan-mode owns the
|
||||
# always-registered exit_plan_mode tool even while the session is not planning.
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
# `dshClient` rows are the browser roster the modules node half scans into
|
||||
# window.__DSH_BOOT__; the modules row is simultaneously a host row.
|
||||
- insert:
|
||||
# Launcher-provided builtin: owns Web GUI orientation in the model prompt
|
||||
# and the matching managed Bash variables. Profiles with a complete prompt
|
||||
# contract disable this row instead of relying on launcher special cases.
|
||||
- id: web-runtime-context
|
||||
name: cordis:web-runtime-context
|
||||
|
||||
- id: session-projection
|
||||
name: '@deepseek-ai/dsh-session-projection'
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write apps/cli/reference/README.md
|
||||
README.md: b37ec9ed61ea4e9899a51316065d4188f30997ad
|
||||
README.zh.md: ca29808a6c8e670f0d0b82c59b1a2c1fa0e13565
|
||||
README.md: 0b6c4d0ad854fb6fa0428f6a1cb2db8d91017f27
|
||||
README.zh.md: ebd055c949827eb58696e90aea94a111a543586e
|
||||
|
||||
@@ -55,7 +55,7 @@ Both modes treat the invoking directory as the default workspace root, load appl
|
||||
|
||||
New sessions default to the `workspace-write` permission preset. Bash and filesystem mutations are restricted to the session workspace and platform temporary roots; reads, network access, and process visibility are not confined. `DSH_PERMISSION_MODE` changes the process fallback. Stored General-settings permissions affect later Web sessions, not an already-open one.
|
||||
|
||||
`DSH_TOOLS_MODE` selects `native`, `code`, or `both` for the Web/headless process; another value fails at boot. [`config/core-web.cordis.yml`](../config/core-web.cordis.yml) is an optional Web overlay that reduces the native model surface to persistent `bash` and `str_replace_editor` while retaining the shipped host, browser, workspace, persistence, and permission composition.
|
||||
`DSH_TOOLS_MODE` selects `native`, `code`, or `both` for the ordinary Web/headless process; another value fails at boot. [`config/core-web.cordis.yml`](../config/core-web.cordis.yml) is an optional RL-compatible Web overlay that pins native mode, renders only `DSH_SYSTEM_PROMPT` or `You are a helpful software engineer assistant.` as the system prompt, disables Workspace instructions and Web runtime prompt context, and exposes only persistent `bash` and `str_replace_editor` while retaining the shipped host, browser, workspace, persistence, and permission composition.
|
||||
|
||||
## Shared deployment behavior
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ Web 和无头进程关闭时会给插件树最多 5 秒完成 dispose。第一
|
||||
|
||||
新会话默认使用 `workspace-write` 权限预设。Bash 和文件系统修改仅限于会话 workspace 与平台临时根目录;读取、网络访问和进程可见性不受限制。`DSH_PERMISSION_MODE` 更改进程后备值。General settings 中存储的权限影响后续 Web 会话,不改变已打开的会话。
|
||||
|
||||
`DSH_TOOLS_MODE` 为 Web/无头进程选择 `native`、`code` 或 `both`;其他值会导致启动失败。[`config/core-web.cordis.yml`](../config/core-web.cordis.yml) 是可选 Web overlay:它在保留随附宿主、浏览器、workspace、持久化和权限组合的同时,把原生模型 surface 缩减为持久 `bash` 和 `str_replace_editor`。
|
||||
`DSH_TOOLS_MODE` 为常规 Web/无头进程选择 `native`、`code` 或 `both`;其他值会导致启动失败。[`config/core-web.cordis.yml`](../config/core-web.cordis.yml) 是可选的 RL 兼容 Web overlay:它固定使用原生模式,仅将 `DSH_SYSTEM_PROMPT` 或 `You are a helpful software engineer assistant.` 渲染为系统提示词,禁用 Workspace 指令与 Web 运行时提示词上下文,并且在保留随附宿主、浏览器、workspace、持久化和权限组合的同时,仅暴露持久 `bash` 和 `str_replace_editor`。
|
||||
|
||||
## 共享部署行为
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ const SOURCE_ROOT = fileURLToPath(new URL('../../..', import.meta.url))
|
||||
|
||||
const DSH_WEB_URL = 'DSH_WEB_URL' as const
|
||||
const DSH_WEB_MODE = 'DSH_WEB_MODE' as const
|
||||
const WEB_RUNTIME_CONTEXT_BUILTIN = 'web-runtime-context' as const
|
||||
|
||||
type WebMode = 'production' | 'development'
|
||||
|
||||
@@ -53,16 +54,8 @@ function localWebUrl(ctx: Context): string {
|
||||
return `http://${LOOPBACK_HOST}:${String(port)}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the launcher-owned prompt and shell runtime context before the
|
||||
* shared config tree mounts. The earlier injections install the prompt
|
||||
* sections and managed Bash contributor when their owning services activate;
|
||||
* dynamic values read the bound server only when consumed.
|
||||
* @param ctx - Web root context with Loader installed but no config tree mounted.
|
||||
* @param sourceRoot - absolute checkout root resolved from the launcher module.
|
||||
* @param mode - whether this process mounted the client-plugin HMR receiver.
|
||||
*/
|
||||
export function prepareWebRuntimeContext(ctx: Context, sourceRoot: string, mode: WebMode): void {
|
||||
/** Register the model-facing Web orientation and its matching shell variables. */
|
||||
function applyWebRuntimeContext(ctx: Context, sourceRoot: string, mode: WebMode): void {
|
||||
ctx.inject(['systemPrompt'], (promptCtx) => {
|
||||
addHarnessSourceSection(promptCtx, sourceRoot)
|
||||
promptCtx.systemPrompt.section({
|
||||
@@ -83,6 +76,31 @@ export function prepareWebRuntimeContext(ctx: Context, sourceRoot: string, mode:
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the launcher-owned runtime-context builtin before the config tree
|
||||
* mounts. The Web overlay decides whether to mount it, so profiles that own
|
||||
* their complete model prompt can disable the contribution without changing
|
||||
* launcher control flow. Dynamic values read the bound server only when used.
|
||||
* @param ctx - Web root context with Loader installed but no config tree mounted.
|
||||
* @param sourceRoot - absolute checkout root resolved from the launcher module.
|
||||
* @param mode - whether this process mounted the client-plugin HMR receiver.
|
||||
*/
|
||||
export function prepareWebRuntimeContext(ctx: Context, sourceRoot: string, mode: WebMode): void {
|
||||
const { builtins } = ctx.loader
|
||||
if (builtins[WEB_RUNTIME_CONTEXT_BUILTIN] !== undefined) {
|
||||
throw new Error(`dsh web: Loader builtin "${WEB_RUNTIME_CONTEXT_BUILTIN}" is already registered`)
|
||||
}
|
||||
const plugin = (runtimeCtx: Context): void => {
|
||||
applyWebRuntimeContext(runtimeCtx, sourceRoot, mode)
|
||||
}
|
||||
builtins[WEB_RUNTIME_CONTEXT_BUILTIN] = plugin
|
||||
ctx.effect(() => () => {
|
||||
if (builtins[WEB_RUNTIME_CONTEXT_BUILTIN] === plugin) {
|
||||
Reflect.deleteProperty(builtins, WEB_RUNTIME_CONTEXT_BUILTIN)
|
||||
}
|
||||
}, 'dsh web runtime-context builtin')
|
||||
}
|
||||
|
||||
/**
|
||||
* Serve the browser UI from the shipped config tree. `host`/`port` are passed
|
||||
* through only when the flag was given; absent, the shipped Web overlay value stands.
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
import { sep } from 'node:path'
|
||||
import { Context } from 'cordis'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import Loader from '@cordisjs/plugin-loader'
|
||||
import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
|
||||
import { HARNESS_SOURCE_SECTION } from '@deepseek-ai/dsh-app-boot'
|
||||
import type {} from '@deepseek-ai/dsh-host-webserver'
|
||||
import { prepareWebRuntimeContext } from '../src/web.ts'
|
||||
|
||||
describe('prepareWebRuntimeContext', () => {
|
||||
it('installs both sections before a later systemPrompt consumer activates', async () => {
|
||||
it('registers the config-tree builtin that installs both prompt sections', async () => {
|
||||
const ctx = new Context()
|
||||
const sourceRoot = `${sep}opt${sep}harness-src`
|
||||
let observedSections: { name: string; text: string }[] | undefined
|
||||
try {
|
||||
await ctx.plugin(Loader)
|
||||
prepareWebRuntimeContext(ctx, sourceRoot, 'production')
|
||||
expect(() => {
|
||||
prepareWebRuntimeContext(ctx, sourceRoot, 'production')
|
||||
}).toThrow(
|
||||
'Loader builtin "web-runtime-context" is already registered',
|
||||
)
|
||||
await ctx.loader.create({ name: 'cordis:web-runtime-context' })
|
||||
ctx.provide('httpServer', { port: 3080 } as Context['httpServer'])
|
||||
const consumer = ctx.inject(['systemPrompt'], async (promptCtx) => {
|
||||
const assembly = await promptCtx.systemPrompt.assemble()
|
||||
|
||||
Reference in New Issue
Block a user