dsh-ptc-plus 0.4.8 → 0.5.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/README.en.md +61 -123
- package/README.md +61 -123
- package/assets/dsh-ptc-plus-banner-en.webp +0 -0
- package/assets/dsh-ptc-plus-banner-zh.webp +0 -0
- package/assets/ptc-plus-repl-workspace-en.png +0 -0
- package/assets/ptc-plus-repl-workspace-zh.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.cjs +42336 -0
- package/cordis.patch.yml +13 -2
- package/docs/README.md +7 -2
- package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +31 -179
- package/docs/adr/0008-define-agent-operating-contract.md +5 -1
- package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -2
- package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +2 -2
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +14 -3
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0022-stage-npm-releases-with-oidc.md +4 -2
- package/docs/adr/0023-global-user-bindings.md +3 -1
- package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +2 -0
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +101 -35
- package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +3 -3
- package/docs/adr/0031-close-semantic-obligations-by-owner.md +1 -1
- package/docs/adr/0032-own-session-log-facts-in-a-host-only-projection.md +27 -0
- package/docs/adr/0033-gate-client-visual-usability-in-a-browser.md +23 -0
- package/docs/adr/0034-keep-program-values-separate-from-output-projections.md +29 -0
- package/docs/adr/0035-run-coverage-only-before-a-new-release.md +27 -0
- package/docs/adr/0036-separate-focused-development-from-delivery-verification.md +29 -0
- package/docs/adr/0037-keep-tool-hover-previews-passive.md +52 -0
- package/docs/adr/0038-freeze-session-capability-plans.md +71 -0
- package/docs/adr/0039-verify-documentation-without-runtime-suites.md +29 -0
- package/docs/adr/0040-separate-capability-configurations-from-session-observations.md +39 -0
- package/docs/adr/0041-record-cell-execution-directories.md +65 -0
- package/docs/adr/0042-persist-provider-availability-and-handback.md +41 -0
- package/docs/adr/0043-compose-capability-and-context-policies.md +37 -0
- package/docs/adr/README.md +6 -0
- package/docs/architecture.md +25 -27
- package/docs/binding-review-placement-design.md +29 -21
- package/docs/capability-planning-components.md +93 -0
- package/docs/capability-projection.md +7 -0
- package/docs/client-ui.md +88 -29
- package/docs/client-visual-contract.md +65 -0
- package/docs/context-management.md +22 -0
- package/docs/context-optimization-plan.md +353 -0
- package/docs/context-public-interface-coverage.md +25 -0
- package/docs/durability-design.md +31 -14
- package/docs/evaluation.md +41 -6
- package/docs/evaluations/command-goat-deepseek-v4.1-flash-20261006.md +126 -0
- package/docs/evaluations/command-goat-deepseek-v4.1-flash.md +281 -0
- package/docs/installation.md +50 -8
- package/docs/program-data-plane.md +5 -3
- package/docs/publishing.md +5 -5
- package/docs/release-coverage.md +73 -0
- package/docs/release-notes.md +1 -1
- package/docs/review-procedure.md +56 -0
- package/docs/runtime-reference.md +48 -16
- package/docs/semantic-validation.md +14 -2
- package/docs/stateful-binding-updates-proposal.md +2 -2
- package/docs/user-bindings.en.md +2 -2
- package/docs/user-bindings.md +3 -3
- package/docs/value-wire.md +11 -1
- package/docs/verification-optimization-work.md +52 -15
- package/docs/verification.md +30 -86
- package/index.js +147 -23
- package/internal/binding-toggle-receipt.js +24 -0
- package/internal/capability-command-receipt.js +29 -0
- package/internal/capability-environment.js +1247 -0
- package/internal/capability-plan.js +285 -0
- package/internal/capability-policy.js +96 -0
- package/internal/capability-statistics-store.js +180 -0
- package/internal/capability-statistics.js +210 -0
- package/internal/compiler-platform.js +5 -3
- package/internal/compiler-service.js +2 -9
- package/internal/config-spec.js +79 -9
- package/internal/cordis-tools-owner.js +22 -19
- package/internal/direct-surface-owner.js +29 -29
- package/internal/dynamic-environment-runtime.js +9 -9
- package/internal/edit-transport-owner.js +183 -139
- package/internal/execution-provider-owner.js +160 -0
- package/internal/execution-seam-compat.js +76 -120
- package/internal/isolated-worker.js +12 -8
- package/internal/kernel-worker.js +104 -32
- package/internal/native-root-dynamic.js +12 -13
- package/internal/program-bindings.js +190 -0
- package/internal/recovery-tips.js +53 -23
- package/internal/rejected-cell-editor.js +8 -8
- package/internal/repl-observation-interest.js +11 -3
- package/internal/rpc-contract.js +1 -0
- package/internal/runtime-bridge-owner.js +351 -82
- package/internal/runtime-config.js +58 -0
- package/internal/runtime-contexts.js +85 -16
- package/internal/runtime-intrinsics.js +1 -0
- package/internal/runtime-messages.js +41 -0
- package/internal/sdk-projection.js +10 -82
- package/internal/session-cell-executor.js +42 -19
- package/internal/session-events.js +74 -4
- package/internal/session-journal-recovery.js +904 -184
- package/internal/session-journal-schema.js +6 -3
- package/internal/session-journal.js +31 -2
- package/internal/session-log-view.js +189 -43
- package/internal/session-runtime.js +175 -23
- package/internal/settings-compat.js +23 -6
- package/internal/stateful-module-compiler.js +3 -2
- package/internal/stateful-module-runtime.js +7 -3
- package/internal/stateful-root-runtime.js +9 -4
- package/internal/user-binding-authoring.js +2 -7
- package/internal/user-bindings-owner.js +47 -7
- package/internal/validated-parse-repair.js +1 -1
- package/internal/value-wire.js +68 -21
- package/internal/worker-cwd-virtualization.js +20 -18
- package/internal/worker-realm-surfaces.js +3 -3
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +55 -38
- package/src/client-authoring-view.js +286 -168
- package/src/client-binding-review.js +4 -1
- package/src/client-binding-toggle.js +18 -0
- package/src/client-capabilities-view.js +1341 -0
- package/src/client-capability-sort.js +29 -0
- package/src/client-code-editor.js +6 -0
- package/src/client-copy.js +881 -8
- package/src/client-feature-gates.js +15 -5
- package/src/client-host-compat.js +23 -2
- package/src/client-indicator-view.js +4 -6
- package/src/client-primitives.js +280 -0
- package/src/client-repl-view.js +23 -16
- package/src/client-settings-view.js +412 -69
- package/src/client-styles.js +193 -41
- package/src/client-tool-hover.js +185 -0
- package/src/client-tool-view.js +45 -11
- package/src/client-transport.js +44 -9
- package/src/client-workbench.js +9 -10
- package/src/client.js +148 -68
- package/assets/ptc-plus-bindings-en.png +0 -0
- package/assets/ptc-plus-bindings-zh.png +0 -0
- package/assets/ptc-plus-repair-en.png +0 -0
- package/assets/ptc-plus-repair-zh.png +0 -0
- package/client.js +0 -31857
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/** Own the execution-seam takeover, per-cell lease, journal projection, and session settlement. */
|
|
2
2
|
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
3
|
+
import { deepEqualJson, snapshotJsonValue } from '@deepseek-ai/dsh-util-values'
|
|
4
|
+
import { decodeValue, renderValueWire } from './value-wire.js'
|
|
5
|
+
import { valueLimitsFromConfig } from './value-wire-schema.js'
|
|
3
6
|
import { executionPolicies } from './binding-update-policy.js'
|
|
4
7
|
import { assertObjectJsonSchema, validateJsonSchemaValue } from '@deepseek-ai/dsh-tools'
|
|
5
8
|
import { normalizeBindingDescriptors } from './binding-descriptors.js'
|
|
@@ -17,11 +20,13 @@ import {
|
|
|
17
20
|
capabilityFind,
|
|
18
21
|
capabilityInspect,
|
|
19
22
|
capabilityTree,
|
|
23
|
+
createCapabilitySearcher,
|
|
20
24
|
toolCapabilityMetadata,
|
|
21
25
|
} from './program-bindings.js'
|
|
22
26
|
import { deepFreeze } from './record-utils.js'
|
|
23
|
-
import { withReplMemorySnapshot } from './repl-memory-projection.js'
|
|
27
|
+
import { REPL_MEMORY_META_KEY, withReplMemorySnapshot } from './repl-memory-projection.js'
|
|
24
28
|
import { withUserBindingDraftCapability } from './user-binding-draft-projection.js'
|
|
29
|
+
import { POST_EDIT_KEY } from './session-journal-schema.js'
|
|
25
30
|
import { generatedRunCodeDescriptionMeta } from './run-code-description.js'
|
|
26
31
|
import { BINDING_SUBMISSION } from './user-binding-authoring.js'
|
|
27
32
|
import {
|
|
@@ -71,7 +76,7 @@ const PROGRAM_CAPABILITY_METADATA = deepFreeze([
|
|
|
71
76
|
namespace: 'repl',
|
|
72
77
|
members: [{
|
|
73
78
|
name: 'state',
|
|
74
|
-
description: 'Manage named REPL checkpoints. list returns checkpoint names, not variable names. Save captures the final durable state of this cell, including subsequent mutations; it is lost if the cell becomes volatile or is discarded. Save, restore and delete take effect after cell settlement and journal confirmation, not when the receipt is awaited. Restore
|
|
79
|
+
description: 'Manage named REPL checkpoints. list returns checkpoint names, not variable names. Save requires a durable cell; a volatile save rejection leaves live bindings usable. Save captures the final durable state of this cell, including subsequent mutations; it is lost if the cell becomes volatile or is discarded. Save, restore and delete take effect after cell settlement and journal confirmation, not when the receipt is awaited. Restore discards bindings beyond the selected durable state for subsequent cells; an omitted name selects the prior durable head, or an empty REPL if none exists. Restore does not undo external effects or change enabled binding configuration; subsequent cells may remain volatile.',
|
|
75
80
|
parameters: {
|
|
76
81
|
type: 'object',
|
|
77
82
|
properties: {
|
|
@@ -128,7 +133,7 @@ const PROGRAM_CAPABILITY_METADATA = deepFreeze([
|
|
|
128
133
|
description: 'Child console output in emission order.',
|
|
129
134
|
},
|
|
130
135
|
result: {
|
|
131
|
-
description: '
|
|
136
|
+
description: 'Plugin-owned isolated execution preserves supported PTC Value V1 types and reference relationships; omitted for no return, present for explicit undefined. Native delegation and legacy upstream execution retain their original result contracts.',
|
|
132
137
|
},
|
|
133
138
|
},
|
|
134
139
|
required: ['logs'],
|
|
@@ -147,12 +152,14 @@ export function createRuntimeBridgeOwner({
|
|
|
147
152
|
sessionConfig,
|
|
148
153
|
userBindingsCwd,
|
|
149
154
|
observeSession,
|
|
155
|
+
readSessionLog = async session => session,
|
|
150
156
|
maxNestedRunCodeDepth,
|
|
151
157
|
presentationGeneration,
|
|
152
158
|
sessionId,
|
|
153
159
|
toolSchemasForAgent,
|
|
154
160
|
userBindingDraftForAgent,
|
|
155
161
|
bindingSubmissionForAgent,
|
|
162
|
+
capabilityEnvironment,
|
|
156
163
|
}) {
|
|
157
164
|
const scope = new AsyncLocalStorage()
|
|
158
165
|
const childScope = new AsyncLocalStorage()
|
|
@@ -172,22 +179,27 @@ export function createRuntimeBridgeOwner({
|
|
|
172
179
|
const withInitiator = ctx.agents === undefined || typeof ctx.agents.withInitiator !== 'function'
|
|
173
180
|
? undefined
|
|
174
181
|
: (agent, operation) => ctx.agents.withInitiator(agent, operation)
|
|
175
|
-
const sessions = new SessionRuntime(sessionConfig, {
|
|
182
|
+
const sessions = new SessionRuntime(sessionConfig, {
|
|
183
|
+
withInitiator, userBindingsCwd, observeSession, readSessionLog,
|
|
184
|
+
sessionForId: id => ctx.get('sessions')?.get(id),
|
|
185
|
+
})
|
|
176
186
|
let currentConfig = sessions.config
|
|
177
187
|
const patchedDefinitions = new Map()
|
|
178
188
|
const pending = new WeakMap()
|
|
179
189
|
const nativeRunCodeHandoffs = new Set()
|
|
180
190
|
let active = true
|
|
181
|
-
const runIsolated = async (request, executionToken, depth, cellConfig, inheritedTools) => {
|
|
191
|
+
const runIsolated = async (request, executionToken, depth, cellConfig, inheritedTools, programCompletion = false) => {
|
|
182
192
|
const child = new SessionRuntime({ ...cellConfig, durableReplay: false, userBindingsEnabled: false,
|
|
183
193
|
replViewEnabled: false }, { withInitiator, userBindingsCwd })
|
|
184
194
|
childRuntimes.add(child)
|
|
185
195
|
const projected = projectBindings(request, depth, executionToken, inheritedTools, cellConfig)
|
|
186
196
|
childFinalizers.add(child)
|
|
187
197
|
try {
|
|
188
|
-
|
|
189
|
-
cwd: executionToken?.session?.header?.cwd,
|
|
190
|
-
} } }, { ...projected.request, executionToken })
|
|
198
|
+
const execution = await child.runTentative({ id: 'isolated-cell', session: { header: {
|
|
199
|
+
cwd: request.cwd ?? executionToken?.session?.header?.cwd,
|
|
200
|
+
} } }, { ...projected.request, executionToken }, { programCompletion })
|
|
201
|
+
if (execution.settlement !== undefined) child.finalize(execution.settlement, true)
|
|
202
|
+
return { result: execution.result, completion: execution.settlement?.journal.completion }
|
|
191
203
|
} finally {
|
|
192
204
|
projected.release()
|
|
193
205
|
try {
|
|
@@ -262,11 +274,12 @@ export function createRuntimeBridgeOwner({
|
|
|
262
274
|
}
|
|
263
275
|
if (languageSemantics !== 'legacy-v1') {
|
|
264
276
|
const child = await runIsolated({ ...request, program: args.code }, executionToken,
|
|
265
|
-
depth + 1, cellConfig, functions)
|
|
266
|
-
if (child.error !== undefined) {
|
|
267
|
-
throw new Error(`nested run_code failed (${child.error.kind}): ${child.error.message}`)
|
|
277
|
+
depth + 1, cellConfig, functions, true)
|
|
278
|
+
if (child.result.error !== undefined) {
|
|
279
|
+
throw new Error(`nested run_code failed (${child.result.error.kind}): ${child.result.error.message}`)
|
|
268
280
|
}
|
|
269
|
-
return { logs: child.logs, ...(child.
|
|
281
|
+
return { logs: child.result.logs, ...(child.completion.hasValue
|
|
282
|
+
? { result: decodeValue(child.completion.value, valueLimitsFromConfig(cellConfig)) } : {}) }
|
|
270
283
|
}
|
|
271
284
|
const childProjected = projectBindings(
|
|
272
285
|
{ ...request, program: args.code }, depth + 1, executionToken, functions, cellConfig,
|
|
@@ -283,7 +296,8 @@ export function createRuntimeBridgeOwner({
|
|
|
283
296
|
return { logs: child.logs, ...(child.value === undefined ? {} : { result: child.value }) }
|
|
284
297
|
}
|
|
285
298
|
|
|
286
|
-
const
|
|
299
|
+
const nativeSchemas = toolSchemasForAgent(executionToken?.agent)
|
|
300
|
+
const schemas = (capabilityEnvironment?.visibleSchemas(executionToken?.agent, nativeSchemas) ?? nativeSchemas)
|
|
287
301
|
.filter(schema => schema?.name === RUN_CODE
|
|
288
302
|
|| (schema?.name !== EDIT_RUN_CODE && typeof functions[schema?.name] === 'function'))
|
|
289
303
|
const emptyObjectTools = new Set(schemas.flatMap(schema => (
|
|
@@ -293,20 +307,30 @@ export function createRuntimeBridgeOwner({
|
|
|
293
307
|
)))
|
|
294
308
|
const projected = bindingDescriptors.namespaces.map((binding) => {
|
|
295
309
|
const wrapped = Object.create(null)
|
|
296
|
-
|
|
310
|
+
const members = binding.global === 'tools'
|
|
311
|
+
? capabilityEnvironment?.projectMembers(executionToken?.agent, binding.members) ?? binding.members
|
|
312
|
+
: binding.members
|
|
313
|
+
for (const key of members) {
|
|
314
|
+
const original = (...args) => binding.functions[key](...args)
|
|
315
|
+
const invoke = binding.global === 'tools'
|
|
316
|
+
? capabilityEnvironment?.adaptFunction(executionToken?.agent, key, original) ?? original
|
|
317
|
+
: original
|
|
297
318
|
Object.defineProperty(wrapped, key, {
|
|
298
319
|
enumerable: true,
|
|
299
320
|
value: async (...args) => {
|
|
300
321
|
ensureLease()
|
|
301
|
-
return binding.
|
|
322
|
+
return binding.global === 'tools' && key === EDIT_RUN_CODE
|
|
323
|
+
? scope.run(executionToken, () => invoke(...args))
|
|
324
|
+
: invoke(...args)
|
|
302
325
|
},
|
|
303
326
|
})
|
|
304
327
|
}
|
|
305
328
|
const emptyObjectMembers = binding.global === 'tools'
|
|
306
|
-
?
|
|
329
|
+
? members.filter(member => emptyObjectTools.has(member))
|
|
307
330
|
: []
|
|
308
331
|
return {
|
|
309
332
|
...binding,
|
|
333
|
+
members,
|
|
310
334
|
functions: wrapped,
|
|
311
335
|
...(binding.global === 'tools' ? { emptyObjectMembers } : {}),
|
|
312
336
|
}
|
|
@@ -317,12 +341,14 @@ export function createRuntimeBridgeOwner({
|
|
|
317
341
|
: []
|
|
318
342
|
)))
|
|
319
343
|
const metadata = Object.freeze([
|
|
320
|
-
...toolCapabilityMetadata(schemas, annotations),
|
|
344
|
+
...(capabilityEnvironment?.toolMetadata(executionToken?.agent, toolCapabilityMetadata(schemas, annotations), schemas) ?? toolCapabilityMetadata(schemas, annotations)),
|
|
345
|
+
...(capabilityEnvironment?.metadata(executionToken?.agent) ?? []),
|
|
321
346
|
...PROGRAM_CAPABILITY_METADATA.map(entry => entry.namespace === 'code'
|
|
322
347
|
&& cellConfig.userBindingsEnabled === true
|
|
323
348
|
? { ...entry, members: [...entry.members, BINDING_SUBMISSION] }
|
|
324
349
|
: entry),
|
|
325
350
|
])
|
|
351
|
+
let searchCapabilities
|
|
326
352
|
projected.push(namespace('capabilities', {
|
|
327
353
|
tree: async value => {
|
|
328
354
|
if (value !== undefined) throw new TypeError('capabilities.tree does not accept arguments')
|
|
@@ -336,11 +362,24 @@ export function createRuntimeBridgeOwner({
|
|
|
336
362
|
},
|
|
337
363
|
inspect: async value => {
|
|
338
364
|
ensureLease()
|
|
339
|
-
if (value === undefined)
|
|
365
|
+
if (value === undefined) {
|
|
366
|
+
const result = capabilityInspect(metadata)
|
|
367
|
+
capabilityEnvironment?.explored(executionToken?.agent, result)
|
|
368
|
+
return result
|
|
369
|
+
}
|
|
340
370
|
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
341
371
|
throw new TypeError('capabilities.inspect expects an object')
|
|
342
372
|
}
|
|
343
|
-
|
|
373
|
+
const result = capabilityInspect(metadata, value.symbols, value.budget)
|
|
374
|
+
capabilityEnvironment?.explored(executionToken?.agent, result)
|
|
375
|
+
return result
|
|
376
|
+
},
|
|
377
|
+
search: async value => {
|
|
378
|
+
ensureLease()
|
|
379
|
+
searchCapabilities ??= createCapabilitySearcher(metadata)
|
|
380
|
+
const result = searchCapabilities(value)
|
|
381
|
+
capabilityEnvironment?.explored(executionToken?.agent, result)
|
|
382
|
+
return result
|
|
344
383
|
},
|
|
345
384
|
}, 'CapabilityExplorationError', 'operation'))
|
|
346
385
|
projected.push(namespace('code', {
|
|
@@ -364,16 +403,29 @@ export function createRuntimeBridgeOwner({
|
|
|
364
403
|
}
|
|
365
404
|
if (patchedDefinitions.has(definition)) return
|
|
366
405
|
const output = definition.output
|
|
367
|
-
const
|
|
406
|
+
const ownPresentationMeta = Object.getOwnPropertyDescriptor(output, 'presentationMeta')
|
|
368
407
|
const patchedPresentationMeta = (args, value) => {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
: originalPresentationMeta(args, value)
|
|
408
|
+
const projectedCurrent = scope.getStore()
|
|
409
|
+
if (projectedCurrent !== undefined) {
|
|
410
|
+
projectedCurrent.presentationMetaCalls = (projectedCurrent.presentationMetaCalls ?? 0) + 1
|
|
373
411
|
}
|
|
412
|
+
const prototype = Object.getPrototypeOf(output)
|
|
413
|
+
const originalPresentationMeta = ownPresentationMeta === undefined
|
|
414
|
+
? prototype === null ? undefined : Reflect.get(prototype, 'presentationMeta', output)
|
|
415
|
+
: Object.hasOwn(ownPresentationMeta, 'value')
|
|
416
|
+
? ownPresentationMeta.value
|
|
417
|
+
: ownPresentationMeta.get?.call(output)
|
|
374
418
|
const base = originalPresentationMeta === undefined
|
|
375
|
-
|
|
376
|
-
|
|
419
|
+
// Installing a projector replaces an optional Host callback with a
|
|
420
|
+
// required JSON-producing callback, including policy reprojection
|
|
421
|
+
// after the execution scope has ended. An empty object conveys no
|
|
422
|
+
// computation evidence; a stale settlement must never fill that gap.
|
|
423
|
+
? {}
|
|
424
|
+
: snapshotJsonValue(originalPresentationMeta.call(output, args, value))
|
|
425
|
+
// An invalid upstream projection is still the Host's output failure;
|
|
426
|
+
// adding plugin metadata must not make it appear valid.
|
|
427
|
+
if (base === undefined) return undefined
|
|
428
|
+
if (!active) return base
|
|
377
429
|
const current = scope.getStore()
|
|
378
430
|
const settlement = current?.settlement
|
|
379
431
|
if (settlement === undefined) return generatedRunCodeDescriptionMeta(args, base)
|
|
@@ -385,9 +437,50 @@ export function createRuntimeBridgeOwner({
|
|
|
385
437
|
if (settlement.userBindings !== undefined) {
|
|
386
438
|
meta = withUserBindingsSnapshot(meta, settlement.userBindings)
|
|
387
439
|
}
|
|
440
|
+
if (current.postEdit?.provenance !== undefined) {
|
|
441
|
+
meta = { ...meta, [POST_EDIT_KEY]: current.postEdit.provenance }
|
|
442
|
+
}
|
|
388
443
|
meta = generatedRunCodeDescriptionMeta(args, meta)
|
|
389
444
|
meta = withReplMemorySnapshot(meta, settlement.replMemory, presentationGeneration)
|
|
390
|
-
|
|
445
|
+
if (current.postEdit?.provenance?.meta?.[REPL_MEMORY_META_KEY] !== undefined) {
|
|
446
|
+
meta = { ...meta,
|
|
447
|
+
[REPL_MEMORY_META_KEY]: current.postEdit.provenance.meta[REPL_MEMORY_META_KEY] }
|
|
448
|
+
}
|
|
449
|
+
meta = withDraftCapability(meta, current)
|
|
450
|
+
return capabilityEnvironment?.complete(current, { meta }).meta ?? meta
|
|
451
|
+
}
|
|
452
|
+
const ownProjectContent = Object.getOwnPropertyDescriptor(definition, 'projectContent')
|
|
453
|
+
const patchedProjectContent = (exec, result) => {
|
|
454
|
+
const prototype = Object.getPrototypeOf(definition)
|
|
455
|
+
const originalProjectContent = ownProjectContent === undefined
|
|
456
|
+
? prototype === null ? undefined : Reflect.get(prototype, 'projectContent', definition)
|
|
457
|
+
: Object.hasOwn(ownProjectContent, 'value')
|
|
458
|
+
? ownProjectContent.value : ownProjectContent.get?.call(definition)
|
|
459
|
+
const original = originalProjectContent?.call(definition, exec, result)
|
|
460
|
+
const current = active ? pending.get(exec) : undefined
|
|
461
|
+
const derived = current?.derivedExecution
|
|
462
|
+
// Some public Host implementations omit the metadata projector for a
|
|
463
|
+
// nested success. Capture its canonical value before policy; the private
|
|
464
|
+
// relation is admitted only if policy retains that same frozen value.
|
|
465
|
+
if (current?.deferredSettlement?.current === current && derived !== undefined
|
|
466
|
+
&& current.exec === exec && exec.token !== undefined && exec.parent !== undefined
|
|
467
|
+
&& current.id === sessionId(exec.agent) && derived.agent === exec.agent
|
|
468
|
+
&& derived.callId === exec.callId && derived.rootCallId === exec.rootCallId
|
|
469
|
+
&& derived.parent === exec.parent && deepEqualJson(derived.arguments, exec.arguments)
|
|
470
|
+
&& current.presentationMetaCalls === undefined && result.isError === false
|
|
471
|
+
&& result.value !== null && typeof result.value === 'object'
|
|
472
|
+
&& Object.isFrozen(result.value) && result.meta?.[JOURNAL_KEY] === undefined
|
|
473
|
+
&& current.settlement !== undefined) {
|
|
474
|
+
const metadata = scope.run(current, () => patchedPresentationMeta(exec.arguments, result.value))
|
|
475
|
+
if (metadata?.[JOURNAL_KEY] !== undefined) {
|
|
476
|
+
current.deferredSettlement.projection = { exec, token: exec.token,
|
|
477
|
+
value: result.value, meta: snapshotJsonValue(result.meta), metadata,
|
|
478
|
+
presentationMetaCalls: current.presentationMetaCalls }
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
const presentation = active ? pending.get(exec)?.postEdit?.presentation : undefined
|
|
482
|
+
if (presentation === undefined) return original
|
|
483
|
+
return [...original ?? result.content, ...presentation.content]
|
|
391
484
|
}
|
|
392
485
|
const ownExecute = Object.getOwnPropertyDescriptor(definition, 'execute')
|
|
393
486
|
const originalExecute = definition.execute
|
|
@@ -406,6 +499,10 @@ export function createRuntimeBridgeOwner({
|
|
|
406
499
|
value: patchedPresentationMeta,
|
|
407
500
|
})
|
|
408
501
|
presentationPatched = true
|
|
502
|
+
Object.defineProperty(definition, 'projectContent', {
|
|
503
|
+
configurable: true, enumerable: ownProjectContent?.enumerable ?? true,
|
|
504
|
+
writable: true, value: patchedProjectContent,
|
|
505
|
+
})
|
|
409
506
|
if (patchedExecute !== undefined) {
|
|
410
507
|
Object.defineProperty(definition, 'execute', {
|
|
411
508
|
configurable: true,
|
|
@@ -417,15 +514,25 @@ export function createRuntimeBridgeOwner({
|
|
|
417
514
|
patchedDefinitions.set(definition, {
|
|
418
515
|
definition,
|
|
419
516
|
output,
|
|
420
|
-
|
|
517
|
+
ownPresentationMeta,
|
|
421
518
|
patchedPresentationMeta,
|
|
519
|
+
ownProjectContent,
|
|
520
|
+
patchedProjectContent,
|
|
422
521
|
ownExecute,
|
|
423
522
|
patchedExecute,
|
|
424
523
|
})
|
|
425
524
|
} catch (error) {
|
|
525
|
+
if (definition.projectContent === patchedProjectContent) {
|
|
526
|
+
if (ownProjectContent === undefined) delete definition.projectContent
|
|
527
|
+
else Object.defineProperty(definition, 'projectContent', ownProjectContent)
|
|
528
|
+
}
|
|
529
|
+
if (patchedExecute !== undefined && definition.execute === patchedExecute) {
|
|
530
|
+
if (ownExecute === undefined) delete definition.execute
|
|
531
|
+
else Object.defineProperty(definition, 'execute', ownExecute)
|
|
532
|
+
}
|
|
426
533
|
if (presentationPatched && output.presentationMeta === patchedPresentationMeta) {
|
|
427
|
-
if (
|
|
428
|
-
else output
|
|
534
|
+
if (ownPresentationMeta === undefined) delete output.presentationMeta
|
|
535
|
+
else Object.defineProperty(output, 'presentationMeta', ownPresentationMeta)
|
|
429
536
|
}
|
|
430
537
|
throw new Error(`ptc-plus: cannot attach the session journal to run_code results: ${error.message}`)
|
|
431
538
|
}
|
|
@@ -437,25 +544,132 @@ export function createRuntimeBridgeOwner({
|
|
|
437
544
|
if (!active || !child.active) return Promise.reject(new Error('PTC execution lease expired'))
|
|
438
545
|
if (executionPolicies(child.cellConfig).languageSemantics !== 'legacy-v1') {
|
|
439
546
|
return runIsolated(request, child.executionToken, child.depth, child.cellConfig, child.functions)
|
|
547
|
+
.then(execution => execution.result)
|
|
440
548
|
}
|
|
441
549
|
}
|
|
442
|
-
if (!active) return seam.
|
|
550
|
+
if (!active) return seam.runUpstream(request)
|
|
443
551
|
const current = scope.getStore()
|
|
444
|
-
if (current === undefined) return seam.
|
|
445
|
-
const projected = projectBindings(request, 0, current)
|
|
552
|
+
if (current === undefined) return seam.runUpstream(request)
|
|
553
|
+
const projected = projectBindings(request, 0, current, undefined, current.submission?.config ?? currentConfig)
|
|
446
554
|
return sessions.runTentative(current, {
|
|
447
555
|
...projected.request,
|
|
448
556
|
executionToken: current,
|
|
449
557
|
...(current.userBindings === undefined ? {} : { userBindings: current.userBindings }),
|
|
450
558
|
})
|
|
451
|
-
.then((execution) => {
|
|
559
|
+
.then(async (execution) => {
|
|
452
560
|
current.settlement = execution.settlement
|
|
453
|
-
|
|
561
|
+
const pendingEdit = current.pendingEdit
|
|
562
|
+
if (pendingEdit === undefined) return execution.result
|
|
563
|
+
if (!pendingEdit.confirmed || current.signal.aborted) {
|
|
564
|
+
pendingEdit.finish(false)
|
|
565
|
+
return execution.result
|
|
566
|
+
}
|
|
567
|
+
try {
|
|
568
|
+
const postEdit = await pendingEdit.dispatch(current.signal, current.exec)
|
|
569
|
+
current.postEdit = postEdit
|
|
570
|
+
for (const context of postEdit.presentation?.additionalContexts ?? []) {
|
|
571
|
+
current.exec.deferContext?.(context)
|
|
572
|
+
}
|
|
573
|
+
if (postEdit.presentation?.concludesTurn === true && execution.result.error === undefined) {
|
|
574
|
+
current.exec.concludeTurn?.()
|
|
575
|
+
}
|
|
576
|
+
const outcome = postEdit.outcome
|
|
577
|
+
const value = postEdit.provenance?.meta?.[JOURNAL_KEY]?.completion
|
|
578
|
+
const hasRenderedContent = postEdit.presentation?.content?.length > 0
|
|
579
|
+
let valueText = ''
|
|
580
|
+
if (!hasRenderedContent && value?.kind === 'return' && value.hasValue) {
|
|
581
|
+
try {
|
|
582
|
+
valueText = `; value: ${renderValueWire(value.value, {
|
|
583
|
+
...valueLimitsFromConfig(current.submission?.config ?? currentConfig),
|
|
584
|
+
maxStringBytes: 2048,
|
|
585
|
+
})}`
|
|
586
|
+
} catch {
|
|
587
|
+
valueText = '; value omitted from preview'
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
const status = outcome.edited
|
|
591
|
+
? `edit_run_code settled${outcome.error === undefined ? '' : ' with execution error'}`
|
|
592
|
+
: 'edit_run_code did not execute the accepted revision'
|
|
593
|
+
const detail = [
|
|
594
|
+
...(hasRenderedContent || !Array.isArray(outcome.logs) ? [] : outcome.logs),
|
|
595
|
+
...(!hasRenderedContent && typeof outcome.error === 'string' ? [outcome.error] : []),
|
|
596
|
+
...(!hasRenderedContent && typeof outcome.reason === 'string' ? [outcome.reason] : []),
|
|
597
|
+
].filter(item => typeof item === 'string').join('\n')
|
|
598
|
+
return { ...execution.result,
|
|
599
|
+
logs: [...execution.result.logs, `${status}${valueText}${detail ? `: ${detail}` : ''}`] }
|
|
600
|
+
} catch (error) {
|
|
601
|
+
pendingEdit.finish(false)
|
|
602
|
+
return { ...execution.result,
|
|
603
|
+
logs: [...execution.result.logs,
|
|
604
|
+
`edit_run_code failed after acceptance: ${error instanceof Error ? error.message : String(error)}`] }
|
|
605
|
+
}
|
|
454
606
|
})
|
|
455
607
|
.finally(projected.release)
|
|
456
608
|
}
|
|
457
609
|
|
|
458
|
-
const releaseSeam = seam.
|
|
610
|
+
const releaseSeam = seam.installExecute(patchedRun)
|
|
611
|
+
|
|
612
|
+
const ownedDerivedScope = (exec, executionArguments = exec.arguments) => {
|
|
613
|
+
const inherited = scope.getStore()
|
|
614
|
+
const derived = inherited?.derivedExecution
|
|
615
|
+
if (inherited?.deferredSettlement === undefined
|
|
616
|
+
|| inherited.id !== sessionId(exec.agent) || derived?.agent !== exec.agent
|
|
617
|
+
|| derived.callId !== exec.callId || derived.rootCallId !== exec.rootCallId
|
|
618
|
+
|| derived.parent !== exec.parent || exec.name !== RUN_CODE
|
|
619
|
+
|| !deepEqualJson(derived.arguments, executionArguments)) return undefined
|
|
620
|
+
return inherited
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
const withSubmission = async (exec, operation) => {
|
|
624
|
+
const id = sessionId(exec.agent)
|
|
625
|
+
const inherited = scope.getStore()
|
|
626
|
+
const ownsDerived = ownedDerivedScope(exec) !== undefined
|
|
627
|
+
if ((exec.parent !== undefined && !ownsDerived) || id === undefined
|
|
628
|
+
|| inherited?.submission?.sessionId === id) return operation()
|
|
629
|
+
const submission = sessions.beginSubmission({ id }, exec.signal)
|
|
630
|
+
const composite = inherited?.deferredSettlement !== undefined && inherited.id === id
|
|
631
|
+
? {
|
|
632
|
+
persistedCallSeq: inherited.persistedCallSeq,
|
|
633
|
+
sourceCallSeq: inherited.sourceCallSeq,
|
|
634
|
+
sessionLog: inherited.sessionLog,
|
|
635
|
+
deferredSettlement: inherited.deferredSettlement,
|
|
636
|
+
derivedExecution: inherited.derivedExecution,
|
|
637
|
+
}
|
|
638
|
+
: {}
|
|
639
|
+
try {
|
|
640
|
+
// Derived edits retain their proved source under a fresh admission for
|
|
641
|
+
// the same session. Delegated agents own a fresh log and no child handoff.
|
|
642
|
+
return await scope.run({ ...composite, submission }, () => childScope.run(undefined, operation))
|
|
643
|
+
} finally {
|
|
644
|
+
sessions.releaseSubmission(submission)
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
const readSubmissionLog = async (session, signal) => {
|
|
649
|
+
const inherited = scope.getStore()
|
|
650
|
+
const sessionLog = inherited?.sessionLog ?? await readSessionLog(session, signal)
|
|
651
|
+
if (inherited?.submission !== undefined) sessions.assertSubmission(inherited.submission)
|
|
652
|
+
return sessionLog
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
const readNestedDispatchLog = async (session, signal) => {
|
|
656
|
+
const inherited = scope.getStore()
|
|
657
|
+
if (inherited === undefined || inherited.session !== session
|
|
658
|
+
|| inherited.signal.aborted || signal?.aborted) {
|
|
659
|
+
throw new Error('ptc-plus: nested edit has no active root run_code cell')
|
|
660
|
+
}
|
|
661
|
+
return readSessionLog(session, signal)
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
const rootEditScope = exec => {
|
|
665
|
+
const current = scope.getStore()
|
|
666
|
+
if (!active || current === undefined || childScope.getStore() !== undefined
|
|
667
|
+
|| current.deferredSettlement !== undefined
|
|
668
|
+
|| current.callId !== exec.rootCallId || current.agent !== exec.agent
|
|
669
|
+
|| current.session !== exec.agent?.session || current.signal.aborted
|
|
670
|
+
|| exec.signal?.aborted) return undefined
|
|
671
|
+
return current
|
|
672
|
+
}
|
|
459
673
|
|
|
460
674
|
return Object.freeze({
|
|
461
675
|
config: sessions.config,
|
|
@@ -464,8 +678,20 @@ export function createRuntimeBridgeOwner({
|
|
|
464
678
|
currentConfig = sessions.config
|
|
465
679
|
},
|
|
466
680
|
observeRepl(id, memory, signal) { return sessions.observe(id, memory, signal) },
|
|
681
|
+
withSubmission,
|
|
682
|
+
readSubmissionLog,
|
|
683
|
+
readNestedDispatchLog,
|
|
684
|
+
prepareAgent(agent) { patchRunCodeDefinition(agent) },
|
|
685
|
+
canScheduleEdit(exec) { return rootEditScope(exec) !== undefined },
|
|
686
|
+
scheduleEdit(exec, pendingEdit) {
|
|
687
|
+
const current = rootEditScope(exec)
|
|
688
|
+
if (current === undefined || current.pendingEdit !== undefined) return false
|
|
689
|
+
current.pendingEdit = pendingEdit
|
|
690
|
+
return true
|
|
691
|
+
},
|
|
467
692
|
// A composite tool's outer result owns the final durability decision.
|
|
468
|
-
async executeTentative(callSeq, operation) {
|
|
693
|
+
async executeTentative(callSeq, sourceCallSeq, operation, sessionLog, derivedExecution) {
|
|
694
|
+
const id = scope.getStore()?.id
|
|
469
695
|
const settlement = {
|
|
470
696
|
current: undefined,
|
|
471
697
|
innerConfirmed: false,
|
|
@@ -480,69 +706,106 @@ export function createRuntimeBridgeOwner({
|
|
|
480
706
|
}
|
|
481
707
|
try {
|
|
482
708
|
const result = await scope.run({
|
|
709
|
+
id,
|
|
483
710
|
...(callSeq === undefined ? {} : { persistedCallSeq: callSeq }),
|
|
711
|
+
...(sourceCallSeq === undefined ? {} : { sourceCallSeq }),
|
|
712
|
+
...(sessionLog === undefined ? {} : { sessionLog }),
|
|
484
713
|
deferredSettlement: settlement,
|
|
714
|
+
derivedExecution,
|
|
485
715
|
}, operation)
|
|
486
|
-
return Object.freeze({ result, finalize
|
|
716
|
+
return Object.freeze({ result, finalize,
|
|
717
|
+
...(settlement.metadata === undefined ? {} : { metadata: settlement.metadata }) })
|
|
487
718
|
} catch (error) {
|
|
488
719
|
finalize(false)
|
|
489
720
|
throw error
|
|
490
721
|
}
|
|
491
722
|
},
|
|
492
|
-
handleExecute(exec, next, executionArguments = exec.arguments, userBindings = undefined) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
:
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
let meta = withJournal(result.meta, settlement.journal)
|
|
520
|
-
if (settlement.recoveryBoundaries !== undefined) {
|
|
521
|
-
meta = withRecoveryBoundaries(meta, settlement.recoveryBoundaries)
|
|
522
|
-
}
|
|
523
|
-
if (settlement.rewrites !== undefined) meta = withRewrites(meta, settlement.rewrites)
|
|
524
|
-
if (settlement.userBindings !== undefined) {
|
|
525
|
-
meta = withUserBindingsSnapshot(meta, settlement.userBindings)
|
|
526
|
-
}
|
|
527
|
-
meta = withReplMemorySnapshot(meta, settlement.replMemory, presentationGeneration)
|
|
528
|
-
meta = withDraftCapability(meta, current)
|
|
529
|
-
return { ...result, meta }
|
|
723
|
+
async handleExecute(exec, next, executionArguments = exec.arguments, userBindings = undefined) {
|
|
724
|
+
const ownsDerived = ownedDerivedScope(exec, executionArguments) !== undefined
|
|
725
|
+
if (exec.parent !== undefined && !ownsDerived) return scope.run(undefined, next)
|
|
726
|
+
return withSubmission(exec, async () => {
|
|
727
|
+
const id = sessionId(exec.agent)
|
|
728
|
+
if (id === undefined) return next()
|
|
729
|
+
await capabilityEnvironment?.prepare(exec.agent)
|
|
730
|
+
patchRunCodeDefinition(exec.agent)
|
|
731
|
+
const inherited = scope.getStore()
|
|
732
|
+
const persistedCallSeq = inherited?.persistedCallSeq
|
|
733
|
+
const current = {
|
|
734
|
+
id,
|
|
735
|
+
submission: inherited?.submission,
|
|
736
|
+
callId: String(exec.callId),
|
|
737
|
+
...(persistedCallSeq === undefined ? {} : { persistedCallSeq }),
|
|
738
|
+
...(inherited?.sourceCallSeq === undefined ? {} : { sourceCallSeq: inherited.sourceCallSeq }),
|
|
739
|
+
...(inherited?.deferredSettlement === undefined
|
|
740
|
+
? {}
|
|
741
|
+
: { deferredSettlement: inherited.deferredSettlement,
|
|
742
|
+
derivedExecution: inherited.derivedExecution }),
|
|
743
|
+
session: exec.agent?.session,
|
|
744
|
+
signal: exec.signal,
|
|
745
|
+
sessionLog: await readSubmissionLog(exec.agent?.session, exec.signal),
|
|
746
|
+
agent: exec.agent,
|
|
747
|
+
exec,
|
|
748
|
+
executionArguments,
|
|
749
|
+
...(userBindings === undefined ? {} : { userBindings }),
|
|
530
750
|
}
|
|
531
|
-
|
|
751
|
+
sessions.assertSubmission(current.submission)
|
|
752
|
+
if (current.deferredSettlement !== undefined) {
|
|
753
|
+
current.deferredSettlement.current = current
|
|
754
|
+
}
|
|
755
|
+
pending.set(exec, current)
|
|
756
|
+
return scope.run(current, async () => {
|
|
757
|
+
const result = await next()
|
|
758
|
+
const settlement = current.settlement
|
|
759
|
+
if (result?.isError === true && settlement !== undefined) {
|
|
760
|
+
let meta = withJournal(result.meta, settlement.journal)
|
|
761
|
+
if (settlement.recoveryBoundaries !== undefined) {
|
|
762
|
+
meta = withRecoveryBoundaries(meta, settlement.recoveryBoundaries)
|
|
763
|
+
}
|
|
764
|
+
if (settlement.rewrites !== undefined) meta = withRewrites(meta, settlement.rewrites)
|
|
765
|
+
if (settlement.userBindings !== undefined) {
|
|
766
|
+
meta = withUserBindingsSnapshot(meta, settlement.userBindings)
|
|
767
|
+
}
|
|
768
|
+
if (current.postEdit?.provenance !== undefined) {
|
|
769
|
+
meta = { ...meta, [POST_EDIT_KEY]: current.postEdit.provenance }
|
|
770
|
+
}
|
|
771
|
+
meta = withReplMemorySnapshot(meta, settlement.replMemory, presentationGeneration)
|
|
772
|
+
if (current.postEdit?.provenance?.meta?.[REPL_MEMORY_META_KEY] !== undefined) {
|
|
773
|
+
meta = { ...meta,
|
|
774
|
+
[REPL_MEMORY_META_KEY]: current.postEdit.provenance.meta[REPL_MEMORY_META_KEY] }
|
|
775
|
+
}
|
|
776
|
+
meta = withDraftCapability(meta, current)
|
|
777
|
+
return capabilityEnvironment?.complete(current, { ...result, meta }) ?? { ...result, meta }
|
|
778
|
+
}
|
|
779
|
+
return result
|
|
780
|
+
})
|
|
532
781
|
})
|
|
533
782
|
},
|
|
534
783
|
handleResult(exec, result) {
|
|
535
|
-
if (exec.parent !== undefined) return
|
|
784
|
+
if (exec.parent !== undefined && !pending.has(exec)) return
|
|
536
785
|
const id = sessionId(exec.agent)
|
|
537
786
|
if (id === undefined) return
|
|
538
787
|
const current = pending.get(exec)
|
|
539
788
|
pending.delete(exec)
|
|
540
789
|
const settlement = current?.settlement
|
|
541
790
|
if (settlement === undefined) {
|
|
542
|
-
|
|
791
|
+
current?.pendingEdit?.finish(false)
|
|
792
|
+
sessions.noteNoop(id, current?.sessionLog, exec.callId)
|
|
543
793
|
return
|
|
544
794
|
}
|
|
545
|
-
const
|
|
795
|
+
const deferred = current.deferredSettlement
|
|
796
|
+
const projection = deferred?.projection
|
|
797
|
+
const derived = current.derivedExecution
|
|
798
|
+
const privateMetadata = projection !== undefined && projection.exec === exec
|
|
799
|
+
&& deferred.current === current && current.exec === exec && current.id === id
|
|
800
|
+
&& derived?.agent === exec.agent && derived.callId === exec.callId
|
|
801
|
+
&& derived.rootCallId === exec.rootCallId && derived.parent === exec.parent
|
|
802
|
+
&& deepEqualJson(derived.arguments, exec.arguments)
|
|
803
|
+
&& projection.token === exec.token && projection.value === result?.value
|
|
804
|
+
&& result.isError === false && deepEqualJson(projection.meta, result.meta)
|
|
805
|
+
&& projection.presentationMetaCalls === current.presentationMetaCalls
|
|
806
|
+
? projection.metadata : undefined
|
|
807
|
+
if (deferred !== undefined) deferred.metadata = privateMetadata
|
|
808
|
+
const meta = privateMetadata ?? result?.meta
|
|
546
809
|
const confirmed = meta !== null && typeof meta === 'object' && !Array.isArray(meta)
|
|
547
810
|
&& Object.hasOwn(meta, JOURNAL_KEY)
|
|
548
811
|
&& journalsEqual(meta[JOURNAL_KEY], settlement.journal)
|
|
@@ -561,6 +824,8 @@ export function createRuntimeBridgeOwner({
|
|
|
561
824
|
return
|
|
562
825
|
}
|
|
563
826
|
sessions.finalize(settlement, confirmed)
|
|
827
|
+
current.pendingEdit?.finish(confirmed && current.postEdit?.provenance !== undefined
|
|
828
|
+
&& deepEqualJson(meta?.[POST_EDIT_KEY], current.postEdit.provenance))
|
|
564
829
|
},
|
|
565
830
|
disposeAgent(agent) {
|
|
566
831
|
return sessions.disposeSession(sessionId(agent) ?? String(agent.id))
|
|
@@ -586,8 +851,12 @@ export function createRuntimeBridgeOwner({
|
|
|
586
851
|
releaseSeam()
|
|
587
852
|
for (const patched of patchedDefinitions.values()) {
|
|
588
853
|
if (patched.output.presentationMeta === patched.patchedPresentationMeta) {
|
|
589
|
-
if (patched.
|
|
590
|
-
else patched.output
|
|
854
|
+
if (patched.ownPresentationMeta === undefined) delete patched.output.presentationMeta
|
|
855
|
+
else Object.defineProperty(patched.output, 'presentationMeta', patched.ownPresentationMeta)
|
|
856
|
+
}
|
|
857
|
+
if (patched.definition.projectContent === patched.patchedProjectContent) {
|
|
858
|
+
if (patched.ownProjectContent === undefined) delete patched.definition.projectContent
|
|
859
|
+
else Object.defineProperty(patched.definition, 'projectContent', patched.ownProjectContent)
|
|
591
860
|
}
|
|
592
861
|
if (patched.patchedExecute !== undefined
|
|
593
862
|
&& patched.definition.execute === patched.patchedExecute) {
|