dsh-ptc-plus 0.2.1
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/LICENSE +21 -0
- package/README.md +137 -0
- package/README.zh.md +137 -0
- package/assets/dsh-ptc-plus-banner.webp +0 -0
- package/assets/ptc-plus-repair.png +0 -0
- package/assets/ptc-plus-settings.png +0 -0
- package/client.js +366 -0
- package/cordis.patch.yml +5 -0
- package/docs/README.md +21 -0
- package/docs/adr/0001-delegate-governance-to-dsh.md +3 -0
- package/docs/adr/0002-limit-work-map-scope.md +3 -0
- package/docs/adr/0003-prefer-native-program-surfaces.md +3 -0
- package/docs/adr/0004-declare-program-bindings-at-the-host.md +5 -0
- package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +129 -0
- package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +45 -0
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +39 -0
- package/docs/adr/0008-define-agent-operating-contract.md +25 -0
- package/docs/adr/0009-bound-expensive-acceptance-default.md +39 -0
- package/docs/adr/0010-session-log-derived-recovery-tips.md +26 -0
- package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +20 -0
- package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +23 -0
- package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +21 -0
- package/docs/adr/0014-persist-cell-rewrite-policy.md +25 -0
- package/docs/adr/0015-preserve-source-positions-through-rewrites.md +25 -0
- package/docs/adr/0016-archive-resolved-review-findings.md +43 -0
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +23 -0
- package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +25 -0
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +32 -0
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +36 -0
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +68 -0
- package/docs/adr/README.md +18 -0
- package/docs/architecture.md +134 -0
- package/docs/capability-projection.md +48 -0
- package/docs/client-ui.md +47 -0
- package/docs/durability-design.md +265 -0
- package/docs/evaluation.md +62 -0
- package/docs/installation.md +82 -0
- package/docs/program-data-plane.md +61 -0
- package/docs/publishing.md +37 -0
- package/docs/runtime-reference.md +119 -0
- package/docs/value-wire.md +61 -0
- package/index.js +532 -0
- package/internal/ast-traversal.js +20 -0
- package/internal/binding-descriptors.js +95 -0
- package/internal/binding-pattern.js +54 -0
- package/internal/builtin-esm-sync.js +9 -0
- package/internal/cell-analysis.js +467 -0
- package/internal/cell-rewriter.js +520 -0
- package/internal/config-spec.js +179 -0
- package/internal/cordis-tools-owner.js +363 -0
- package/internal/diagnostic.js +133 -0
- package/internal/direct-surface-owner.js +326 -0
- package/internal/edit-transport-owner.js +287 -0
- package/internal/failure-reporting.js +139 -0
- package/internal/kernel-worker.js +484 -0
- package/internal/module-policy.js +46 -0
- package/internal/program-bindings.js +187 -0
- package/internal/record-utils.js +53 -0
- package/internal/recovery-tips.js +81 -0
- package/internal/rejected-cell-editor.js +328 -0
- package/internal/repl-convenience.js +201 -0
- package/internal/runtime-bridge-owner.js +417 -0
- package/internal/runtime-config.js +77 -0
- package/internal/runtime-contexts.js +31 -0
- package/internal/sdk-projection.js +88 -0
- package/internal/session-cell-executor.js +612 -0
- package/internal/session-journal.js +889 -0
- package/internal/session-log-view.js +80 -0
- package/internal/session-runtime.js +536 -0
- package/internal/session-state.js +45 -0
- package/internal/source-position-map.js +224 -0
- package/internal/tool-call-canonicalizer.js +339 -0
- package/internal/value-wire.js +421 -0
- package/internal/worker-client.js +218 -0
- package/internal/worker-cwd-virtualization.js +155 -0
- package/package.json +100 -0
- package/src/client.js +165 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { latestRecoveryTip } from './recovery-tips.js'
|
|
2
|
+
import { projectSessionLog } from './session-log-view.js'
|
|
3
|
+
|
|
4
|
+
const REWRITE_FEEDBACK = 'tools:ptc-plus-rewrite-info'
|
|
5
|
+
|
|
6
|
+
function continuationFeedback(view) {
|
|
7
|
+
const run = view.latestRun
|
|
8
|
+
const rewrites = run?.rewrites
|
|
9
|
+
if (rewrites === undefined || rewrites.length === 0) return undefined
|
|
10
|
+
const details = rewrites.map(rewrite => rewrite.description).join('; ')
|
|
11
|
+
if (run.journal === undefined) {
|
|
12
|
+
return `The preceding run_code cell had these source adjustments: ${details}. Its completion is unknown because no valid execution journal is available. Inspect its tool result and live bindings before continuing; do not assume it completed or failed, and do not replay it automatically.`
|
|
13
|
+
}
|
|
14
|
+
if (run.journal.completion?.kind !== 'return') {
|
|
15
|
+
return `The preceding run_code cell failed after a source adjustment: ${details}. Treat it as failed; inspect its tool result and live bindings before continuing, and do not replay it automatically.`
|
|
16
|
+
}
|
|
17
|
+
return undefined
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Build all dynamic PTC contexts from one session-log projection. */
|
|
21
|
+
export function sessionRuntimeContexts(agent, tipConfig) {
|
|
22
|
+
const view = projectSessionLog(agent)
|
|
23
|
+
const rewrite = continuationFeedback(view)
|
|
24
|
+
const tip = latestRecoveryTip(view, tipConfig)
|
|
25
|
+
return Object.freeze({
|
|
26
|
+
contexts: Object.freeze([
|
|
27
|
+
...(rewrite === undefined ? [] : [{ name: REWRITE_FEEDBACK, text: rewrite }]),
|
|
28
|
+
...(tip === undefined ? [] : [tip]),
|
|
29
|
+
]),
|
|
30
|
+
})
|
|
31
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Adapt the host program SDK without weakening the declared direct tool surface. */
|
|
2
|
+
import { parse } from '@babel/parser'
|
|
3
|
+
|
|
4
|
+
const PROJECTION_ERROR = 'ptc-plus: incompatible tools SDK projection: '
|
|
5
|
+
const TYPESCRIPT_FENCE = '```ts\n'
|
|
6
|
+
|
|
7
|
+
function incompatible(message, cause = undefined) {
|
|
8
|
+
return new Error(`${PROJECTION_ERROR}${message}`, cause === undefined ? undefined : { cause })
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function lineStart(source, offset) {
|
|
12
|
+
return source.lastIndexOf('\n', offset - 1) + 1
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function memberName(member) {
|
|
16
|
+
if (member.type !== 'TSPropertySignature') return undefined
|
|
17
|
+
if (member.key.type === 'Identifier') return member.key.name
|
|
18
|
+
if (member.key.type === 'StringLiteral') return member.key.value
|
|
19
|
+
return undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function supportedFence(source) {
|
|
23
|
+
const starts = []
|
|
24
|
+
for (let offset = 0; offset < source.length;) {
|
|
25
|
+
const start = source.indexOf(TYPESCRIPT_FENCE, offset)
|
|
26
|
+
if (start < 0) break
|
|
27
|
+
if (start === 0 || source[start - 1] === '\n') starts.push(start)
|
|
28
|
+
offset = start + TYPESCRIPT_FENCE.length
|
|
29
|
+
}
|
|
30
|
+
if (starts.length !== 1) {
|
|
31
|
+
throw incompatible(`expected exactly one ${JSON.stringify(TYPESCRIPT_FENCE.trim())} fence`)
|
|
32
|
+
}
|
|
33
|
+
const codeStart = starts[0] + TYPESCRIPT_FENCE.length
|
|
34
|
+
const codeEnd = source.indexOf('\n```', codeStart)
|
|
35
|
+
if (codeEnd < 0) throw incompatible('the TypeScript fence is not closed')
|
|
36
|
+
return { codeStart, codeEnd }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Remove one direct-only tool from the host-generated program SDK. */
|
|
40
|
+
export function projectProgramSdk(nativeSdk, excludedName = 'edit_run_code') {
|
|
41
|
+
if (typeof nativeSdk !== 'string') return ''
|
|
42
|
+
if (!nativeSdk.includes(excludedName)) return nativeSdk
|
|
43
|
+
|
|
44
|
+
const { codeStart, codeEnd } = supportedFence(nativeSdk)
|
|
45
|
+
const code = nativeSdk.slice(codeStart, codeEnd)
|
|
46
|
+
let ast
|
|
47
|
+
try {
|
|
48
|
+
ast = parse(code, { sourceType: 'module', plugins: ['typescript'] })
|
|
49
|
+
} catch (error) {
|
|
50
|
+
throw incompatible('the TypeScript fence could not be parsed', error)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const removals = []
|
|
54
|
+
for (const interfaceName of ['ToolArgsMap', 'ToolOutputMap']) {
|
|
55
|
+
const declarations = ast.program.body.filter(statement => (
|
|
56
|
+
statement.type === 'TSInterfaceDeclaration' && statement.id.name === interfaceName
|
|
57
|
+
))
|
|
58
|
+
if (declarations.length !== 1) {
|
|
59
|
+
throw incompatible(`expected exactly one ${interfaceName} interface`)
|
|
60
|
+
}
|
|
61
|
+
const declaration = declarations[0]
|
|
62
|
+
const members = declaration.body.body.filter(member => memberName(member) === excludedName)
|
|
63
|
+
if (members.length !== 1) {
|
|
64
|
+
throw incompatible(`expected exactly one ${excludedName} member in ${interfaceName}`)
|
|
65
|
+
}
|
|
66
|
+
const member = members[0]
|
|
67
|
+
if (declaration.body.body.length === 1) {
|
|
68
|
+
removals.push([declaration.body.start + 1, declaration.body.end - 1])
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
71
|
+
const commentStart = member.leadingComments?.[0]?.start
|
|
72
|
+
const startOffset = commentStart ?? member.start
|
|
73
|
+
const start = lineStart(code, startOffset)
|
|
74
|
+
let end = member.end
|
|
75
|
+
if (code[end] === '\n') end += 1
|
|
76
|
+
removals.push([start, end])
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let projectedCode = code
|
|
80
|
+
for (const [start, end] of removals.sort((left, right) => right[0] - left[0])) {
|
|
81
|
+
projectedCode = projectedCode.slice(0, start) + projectedCode.slice(end)
|
|
82
|
+
}
|
|
83
|
+
const projected = nativeSdk.slice(0, codeStart) + projectedCode + nativeSdk.slice(codeEnd)
|
|
84
|
+
if (projected.includes(excludedName)) {
|
|
85
|
+
throw incompatible(`residual ${excludedName} token remains after projection`)
|
|
86
|
+
}
|
|
87
|
+
return projected
|
|
88
|
+
}
|