narraeon 0.4.0 → 0.5.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/dist/node/protocol/appPreferences.js +25 -0
- package/dist/node/protocol/conversationObservation.js +67 -0
- package/dist/node/protocol/v1.js +186 -34
- package/dist/node/protocol/worldExtensions.js +16 -0
- package/dist/node/protocol/worldMaintenance.js +77 -0
- package/dist/node/protocol/worldPromptDiagnostics.js +1 -0
- package/dist/node/runtime/ConversationChanges.js +24 -0
- package/dist/node/runtime/V1Runtime.js +445 -121
- package/dist/node/runtime/artifact/FileNativeArtifactStore.js +326 -12
- package/dist/node/runtime/authoring/AuthoringRequestSnapshot.js +63 -0
- package/dist/node/runtime/authoring/ModelToolConversation.js +218 -0
- package/dist/node/runtime/config/AppPreferencesStore.js +46 -17
- package/dist/node/runtime/content/ContentTreeFingerprint.js +13 -0
- package/dist/node/runtime/content/ContentWorkspace.js +43 -13
- package/dist/node/runtime/content/CurrentTreeContentLibrary.js +128 -46
- package/dist/node/runtime/content/FileNativeContentTree.js +28 -10
- package/dist/node/runtime/content/PackageFollowups.js +80 -0
- package/dist/node/runtime/extension/FrontendExtensionBundle.js +19 -14
- package/dist/node/runtime/extension/PackageScriptPermissions.js +70 -0
- package/dist/node/runtime/extension/WorldExtensionControls.js +205 -0
- package/dist/node/runtime/extension/WorldExtensionRequests.js +64 -0
- package/dist/node/runtime/model/FileNativeModelAdapters.js +21 -466
- package/dist/node/runtime/model/ModelConnectionStore.js +13 -0
- package/dist/node/runtime/model/ModelHost.js +31 -1
- package/dist/node/runtime/model/ModelHostStream.js +51 -5
- package/dist/node/runtime/play/FileNativeContinuityCorrection.js +55 -45
- package/dist/node/runtime/play/FileNativePlayPresetStore.js +256 -238
- package/dist/node/runtime/play/FileNativePlayTimelineStore.js +118 -9
- package/dist/node/runtime/play/OrderedFollowups.js +71 -0
- package/dist/node/runtime/play/OrderedPlayPrompts.js +180 -0
- package/dist/node/runtime/play/PlayCallChain.js +814 -61
- package/dist/node/runtime/play/PlayContinuity.js +88 -0
- package/dist/node/runtime/play/PlayDocumentTools.js +205 -287
- package/dist/node/runtime/play/PlayFollowupRequests.js +34 -3
- package/dist/node/runtime/play/PlayPresetWorkbench.js +45 -54
- package/dist/node/runtime/play/PlayPromptRun.js +86 -0
- package/dist/node/runtime/prompt/FileNativePromptCompiler.js +670 -93
- package/dist/node/runtime/prompt/FileNativeToolRegistry.js +37 -21
- package/dist/node/runtime/prompt/PromptCompilationCodec.js +322 -0
- package/dist/node/runtime/prompt/WorldMaintenanceReport.js +251 -0
- package/dist/node/runtime/prompt/WorldMaterialCoverage.js +83 -0
- package/dist/node/runtime/prompt/WorldPromptDiagnostics.js +185 -0
- package/dist/node/runtime/setting/FileNativeSettingImprovementStore.js +1027 -0
- package/dist/node/runtime/setting/SettingAuthoringTransaction.js +1339 -0
- package/dist/node/runtime/setting/SettingImprovementSession.js +714 -0
- package/dist/node/runtime/world/FileNativeAuthorityV3.js +88 -1
- package/dist/node/runtime/world/FileNativeWorldStore.js +292 -27
- package/dist/node/runtime/world/PlayerViewBindings.js +30 -0
- package/dist/node/runtime/world/PlayerViewRenderer.js +27 -34
- package/dist/node/runtime/world/WorldDocumentMaintenance.js +174 -0
- package/dist/node/runtime/world/WorldDocumentStore.js +166 -96
- package/dist/node/runtime/world/WorldOperationCoordinator.js +103 -2
- package/dist/node/runtime/world-revision/FileNativeWorldRevisionStore.js +696 -0
- package/dist/node/runtime/world-revision/WorldRevisionAuthoringTransaction.js +380 -0
- package/dist/node/runtime/world-revision/WorldRevisionSession.js +709 -0
- package/dist/node/runtime/world-revision/WorldRevisionWorkspace.js +494 -0
- package/dist/node/server/ConversationStream.js +109 -0
- package/dist/node/server/createServer.js +5 -1
- package/dist/node/shared/artifact-payload-contract.js +123 -0
- package/dist/node/shared/default-play-prompts.js +25 -45
- package/dist/node/shared/default-preset-host.js +114 -138
- package/dist/node/shared/default-setting-improvement-prompt.js +52 -38
- package/dist/node/shared/display-regex.js +114 -0
- package/dist/node/shared/first-party-action-choices.js +1 -6
- package/dist/node/shared/first-party-player-view.js +1 -6
- package/dist/node/shared/ordered-author-prompts.js +64 -0
- package/dist/node/shared/ordered-followups.js +42 -0
- package/dist/node/shared/ordered-play-prompts.js +73 -0
- package/dist/web/assets/index-DG85hpWC.css +1 -0
- package/dist/web/assets/index-DfxvCjb6.js +1207 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/node/runtime/model/SettingAuthorStream.js +0 -21
- package/dist/node/runtime/setting/DocumentCandidateSettingImprovement.js +0 -1731
- package/dist/web/assets/index-D8YKfmNG.js +0 -1192
- package/dist/web/assets/index-Xa0s35CJ.css +0 -1
|
@@ -29,7 +29,24 @@ export async function runPlayFollowupRequests(input) {
|
|
|
29
29
|
failure ??= "The follow-up request was cancelled.";
|
|
30
30
|
break;
|
|
31
31
|
}
|
|
32
|
-
const
|
|
32
|
+
const lease = await input.controls?.acquire(input.context.worldId, {
|
|
33
|
+
playPresetId: input.context.playPresetId,
|
|
34
|
+
requestId: followup.id,
|
|
35
|
+
...(followup.extensionControl === undefined
|
|
36
|
+
? {}
|
|
37
|
+
: { extensionControl: followup.extensionControl }),
|
|
38
|
+
}, input.signal);
|
|
39
|
+
if (lease?.signal.aborted) {
|
|
40
|
+
lease.release();
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
let outcome;
|
|
44
|
+
try {
|
|
45
|
+
outcome = await runOne(input, followup, prefix, lease?.signal ?? input.signal);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
lease?.release();
|
|
49
|
+
}
|
|
33
50
|
if (signalWasAborted(input.signal)) {
|
|
34
51
|
failure ??= "The follow-up request was cancelled.";
|
|
35
52
|
break;
|
|
@@ -46,7 +63,7 @@ export async function runPlayFollowupRequests(input) {
|
|
|
46
63
|
: await input.artifacts.failExtension(input.context.operationId, "recovery_required", failure, completed);
|
|
47
64
|
return { outcomes, extension };
|
|
48
65
|
}
|
|
49
|
-
async function runOne(input, followup, prefix) {
|
|
66
|
+
async function runOne(input, followup, prefix, requestSignal) {
|
|
50
67
|
const outcome = {
|
|
51
68
|
id: followup.id,
|
|
52
69
|
displayName: followup.displayName,
|
|
@@ -55,14 +72,25 @@ async function runOne(input, followup, prefix) {
|
|
|
55
72
|
};
|
|
56
73
|
const requestContext = {
|
|
57
74
|
...input.context,
|
|
75
|
+
...(followup.extensionControl === undefined
|
|
76
|
+
? {}
|
|
77
|
+
: { extensionControl: structuredClone(followup.extensionControl) }),
|
|
78
|
+
...(input.presentations?.[followup.id] === undefined
|
|
79
|
+
? {}
|
|
80
|
+
: { frozenPresentations: input.presentations[followup.id] }),
|
|
58
81
|
requestId: followup.id,
|
|
82
|
+
displayName: followup.displayName,
|
|
59
83
|
requestAttempt: 1,
|
|
60
84
|
maxArtifactBytes: followup.maxArtifactBytes,
|
|
61
85
|
declarations: structuredClone(followup.artifacts),
|
|
86
|
+
...(followup.frozenResources === undefined
|
|
87
|
+
? {}
|
|
88
|
+
: { frozenResources: structuredClone(followup.frozenResources) }),
|
|
62
89
|
};
|
|
63
90
|
let responseDiagnostics;
|
|
64
91
|
try {
|
|
65
92
|
await input.artifacts.beginRequestAttempt(requestContext);
|
|
93
|
+
requestSignal?.throwIfAborted();
|
|
66
94
|
input.observer?.onProviderDispatch?.();
|
|
67
95
|
let response;
|
|
68
96
|
try {
|
|
@@ -87,7 +115,7 @@ async function runOne(input, followup, prefix) {
|
|
|
87
115
|
exchange: 1,
|
|
88
116
|
maxOutputTokens: input.maxOutputTokens,
|
|
89
117
|
}, {
|
|
90
|
-
...(
|
|
118
|
+
...(requestSignal === undefined ? {} : { signal: requestSignal }),
|
|
91
119
|
onDelta: (delta) => input.observer?.onProviderDelta?.(delta),
|
|
92
120
|
});
|
|
93
121
|
if (input.signal?.aborted === true)
|
|
@@ -117,6 +145,8 @@ async function runOne(input, followup, prefix) {
|
|
|
117
145
|
});
|
|
118
146
|
}
|
|
119
147
|
const failedTools = outcome.toolCalls.filter(({ ok }) => !ok);
|
|
148
|
+
if (failedTools.length > 0)
|
|
149
|
+
outcome.failure = `Follow-up request ${followup.id} could not save its artifacts.`;
|
|
120
150
|
if (failedTools.length > 0 && response.diagnostics !== undefined)
|
|
121
151
|
await input.failureLog?.recordFailure({
|
|
122
152
|
exchange: response.diagnostics,
|
|
@@ -168,6 +198,7 @@ async function runOne(input, followup, prefix) {
|
|
|
168
198
|
],
|
|
169
199
|
});
|
|
170
200
|
}
|
|
201
|
+
await input.artifacts.finishRequest?.(requestContext, outcome.failure !== undefined);
|
|
171
202
|
return outcome;
|
|
172
203
|
}
|
|
173
204
|
function signalWasAborted(signal) {
|
|
@@ -1,15 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveArtifactRenderer } from "../extension/FrontendExtensionBundle.js";
|
|
2
|
+
import { builtinFollowupExample } from "../../shared/ordered-followups.js";
|
|
3
|
+
import { projectPlayerViewPanels, } from "../extension/PlayerViewPanelProjector.js";
|
|
4
|
+
import { parsePlayPresetRegexAsset, applyPlayPresetStructuredEditor, parsePlayPresetStructuredEditor, parsePlayPresetFiles, revisionForPlayPresetFiles, toPlayPresetStructuredEditor, } from "./FileNativePlayPresetStore.js";
|
|
2
5
|
/**
|
|
3
6
|
* Read-only workbench seam. It resolves the same frozen file-native binding
|
|
4
7
|
* used by PromptCompiler and FrontendExtensionBundle, but never calls a model,
|
|
5
8
|
* writes a world, or executes author JavaScript.
|
|
6
9
|
*/
|
|
7
|
-
export function buildPlayPresetWorkbenchSnapshot(binding) {
|
|
10
|
+
export function buildPlayPresetWorkbenchSnapshot(binding, playerViewContext, draft) {
|
|
11
|
+
if (draft !== undefined) {
|
|
12
|
+
const files = draft.structure === undefined
|
|
13
|
+
? structuredClone(draft.files)
|
|
14
|
+
: applyPlayPresetStructuredEditor(draft.files, parsePlayPresetStructuredEditor(draft.structure));
|
|
15
|
+
const parsed = parsePlayPresetFiles(files);
|
|
16
|
+
if (parsed.kind === "invalid")
|
|
17
|
+
throw parsed.error;
|
|
18
|
+
binding = {
|
|
19
|
+
...binding,
|
|
20
|
+
files,
|
|
21
|
+
definition: parsed.definition,
|
|
22
|
+
revision: revisionForPlayPresetFiles(files),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
8
25
|
const scriptsEnabled = binding.scriptsEnabled !== false;
|
|
9
26
|
const structure = toPlayPresetStructuredEditor(binding.definition);
|
|
10
27
|
const staticErrors = [];
|
|
11
28
|
const artifactPreviews = [];
|
|
12
|
-
|
|
29
|
+
const previewFollowups = [
|
|
30
|
+
...binding.definition.followups,
|
|
31
|
+
...(binding.definition.followupItems === undefined
|
|
32
|
+
? []
|
|
33
|
+
: [builtinFollowupExample("en").definition]),
|
|
34
|
+
];
|
|
35
|
+
for (const followup of previewFollowups)
|
|
13
36
|
for (const declaration of followup.artifacts) {
|
|
14
37
|
const diagnostics = [];
|
|
15
38
|
let regex = [];
|
|
@@ -41,57 +64,17 @@ export function buildPlayPresetWorkbenchSnapshot(binding) {
|
|
|
41
64
|
? "<p>This is a local HTML workbench sample.</p>"
|
|
42
65
|
: "This is a local text workbench sample.";
|
|
43
66
|
let renderer;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
const scriptSources = (declaration.scripts ?? []).flatMap((path) => {
|
|
57
|
-
const script = binding.files[path];
|
|
58
|
-
if (script === undefined) {
|
|
59
|
-
diagnostics.push(`Script resource does not exist: ${path}`);
|
|
60
|
-
staticErrors.push({
|
|
61
|
-
code: "script_missing",
|
|
62
|
-
message: `Script resource does not exist: ${path}`,
|
|
63
|
-
location: path,
|
|
64
|
-
});
|
|
65
|
-
return [];
|
|
66
|
-
}
|
|
67
|
-
return [script];
|
|
68
|
-
});
|
|
69
|
-
const assetSources = (declaration.assets ?? []).flatMap((path) => {
|
|
70
|
-
const asset = binding.files[path];
|
|
71
|
-
if (asset === undefined) {
|
|
72
|
-
diagnostics.push(`Asset resource does not exist: ${path}`);
|
|
73
|
-
staticErrors.push({
|
|
74
|
-
code: "asset_missing",
|
|
75
|
-
message: `Asset resource does not exist: ${path}`,
|
|
76
|
-
location: path,
|
|
77
|
-
});
|
|
78
|
-
return [];
|
|
79
|
-
}
|
|
80
|
-
return [{ id: path, source: asset }];
|
|
81
|
-
});
|
|
82
|
-
renderer = {
|
|
83
|
-
mode: declaration.rendererMode ?? "document",
|
|
84
|
-
...(declaration.rendererRevision === undefined
|
|
85
|
-
? {}
|
|
86
|
-
: { revision: declaration.rendererRevision }),
|
|
87
|
-
document: source,
|
|
88
|
-
scripts: scriptsEnabled ? scriptSources : [],
|
|
89
|
-
assets: assetSources,
|
|
90
|
-
trustedLocalCode: scriptsEnabled &&
|
|
91
|
-
(declaration.contentType === "text/html" ||
|
|
92
|
-
(declaration.scripts?.length ?? 0) > 0),
|
|
93
|
-
};
|
|
94
|
-
}
|
|
67
|
+
try {
|
|
68
|
+
renderer = resolveArtifactRenderer(declaration, binding);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const message = error instanceof Error ? error.message : "Invalid renderer resources";
|
|
72
|
+
diagnostics.push(message);
|
|
73
|
+
staticErrors.push({
|
|
74
|
+
code: "renderer_invalid",
|
|
75
|
+
message,
|
|
76
|
+
location: declaration.renderer ?? followup.id,
|
|
77
|
+
});
|
|
95
78
|
}
|
|
96
79
|
artifactPreviews.push({
|
|
97
80
|
requestId: followup.id,
|
|
@@ -125,6 +108,14 @@ export function buildPlayPresetWorkbenchSnapshot(binding) {
|
|
|
125
108
|
revision: binding.revision,
|
|
126
109
|
structure,
|
|
127
110
|
artifactPreviews,
|
|
111
|
+
...(playerViewContext === undefined
|
|
112
|
+
? {}
|
|
113
|
+
: {
|
|
114
|
+
playerViewPreview: {
|
|
115
|
+
...playerViewContext,
|
|
116
|
+
panels: projectPlayerViewPanels({ ...playerViewContext, binding }),
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
128
119
|
staticErrors,
|
|
129
120
|
trustedLocalCode: artifactPreviews.some(({ renderer }) => renderer?.trustedLocalCode === true),
|
|
130
121
|
scriptsEnabled,
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { validPromptCompilation, validPromptTools, validPlayFollowup, } from "../prompt/PromptCompilationCodec.js";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
export function currentPlayPrompt(source) {
|
|
4
|
+
return source.promptRuns?.at(-1) ?? source;
|
|
5
|
+
}
|
|
6
|
+
export function recordedPlayPrompt(source) {
|
|
7
|
+
const lastEvent = source.events.at(-1)?.id ?? 0;
|
|
8
|
+
return (source.promptRuns?.findLast((run) => run.firstEventId <= lastEvent) ??
|
|
9
|
+
source);
|
|
10
|
+
}
|
|
11
|
+
export function playPromptRunsThroughEvents(context, events) {
|
|
12
|
+
const lastEvent = events.at(-1)?.id ?? 0;
|
|
13
|
+
const runs = (context.promptRuns ?? []).filter(({ firstEventId }) => firstEventId <= lastEvent);
|
|
14
|
+
return structuredClone([
|
|
15
|
+
...new Map(runs.map((run) => [run.firstEventId, run])).values(),
|
|
16
|
+
]);
|
|
17
|
+
}
|
|
18
|
+
export function assertPlayPromptRun(value) {
|
|
19
|
+
if (typeof value !== "object" || value === null)
|
|
20
|
+
throw new Error("Invalid play prompt run");
|
|
21
|
+
const run = value;
|
|
22
|
+
if (!exactKeys(run, [
|
|
23
|
+
"schemaVersion",
|
|
24
|
+
"firstEventId",
|
|
25
|
+
"head",
|
|
26
|
+
"exchange",
|
|
27
|
+
"playPreset",
|
|
28
|
+
"bootstrap",
|
|
29
|
+
"tools",
|
|
30
|
+
"followups",
|
|
31
|
+
"playPresetScriptsEnabled",
|
|
32
|
+
"presetFiles",
|
|
33
|
+
]) ||
|
|
34
|
+
run.schemaVersion !== 1 ||
|
|
35
|
+
!Number.isSafeInteger(run.firstEventId) ||
|
|
36
|
+
Number(run.firstEventId) < 1 ||
|
|
37
|
+
!Number.isSafeInteger(run.exchange) ||
|
|
38
|
+
Number(run.exchange) < 1 ||
|
|
39
|
+
typeof run.head !== "string" ||
|
|
40
|
+
!validPresetIdentity(run.playPreset) ||
|
|
41
|
+
!validPromptCompilation(run.bootstrap) ||
|
|
42
|
+
!validPromptTools(run.tools) ||
|
|
43
|
+
!Array.isArray(run.followups) ||
|
|
44
|
+
!run.followups.every(validPlayFollowup) ||
|
|
45
|
+
typeof run.playPresetScriptsEnabled !== "boolean" ||
|
|
46
|
+
typeof run.presetFiles !== "object" ||
|
|
47
|
+
run.presetFiles === null ||
|
|
48
|
+
Array.isArray(run.presetFiles) ||
|
|
49
|
+
!Object.values(run.presetFiles).every((contents) => typeof contents === "string"))
|
|
50
|
+
throw new Error("Invalid play prompt run");
|
|
51
|
+
}
|
|
52
|
+
export function encodePlayPromptRun(run) {
|
|
53
|
+
assertPlayPromptRun(run);
|
|
54
|
+
return {
|
|
55
|
+
kind: "play_prompt_run",
|
|
56
|
+
schemaVersion: 1,
|
|
57
|
+
run,
|
|
58
|
+
digest: createHash("sha256").update(JSON.stringify(run)).digest("hex"),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function decodePlayPromptRun(value) {
|
|
62
|
+
if (typeof value !== "object" || value === null)
|
|
63
|
+
throw new Error("Invalid play prompt run record");
|
|
64
|
+
const record = value;
|
|
65
|
+
if (!exactKeys(record, ["kind", "schemaVersion", "run", "digest"]) ||
|
|
66
|
+
record.kind !== "play_prompt_run" ||
|
|
67
|
+
record.schemaVersion !== 1 ||
|
|
68
|
+
record.digest !==
|
|
69
|
+
createHash("sha256")
|
|
70
|
+
.update(JSON.stringify(record.run) ?? "")
|
|
71
|
+
.digest("hex"))
|
|
72
|
+
throw new Error("Play prompt run does not match its durable identity");
|
|
73
|
+
assertPlayPromptRun(record.run);
|
|
74
|
+
return record.run;
|
|
75
|
+
}
|
|
76
|
+
function exactKeys(record, keys) {
|
|
77
|
+
return (Object.keys(record).length === keys.length &&
|
|
78
|
+
keys.every((key) => Object.hasOwn(record, key)));
|
|
79
|
+
}
|
|
80
|
+
function validPresetIdentity(value) {
|
|
81
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
82
|
+
return false;
|
|
83
|
+
const preset = value;
|
|
84
|
+
return (exactKeys(preset, ["id", "name", "revision"]) &&
|
|
85
|
+
[preset.id, preset.name, preset.revision].every((part) => typeof part === "string" && part.length > 0));
|
|
86
|
+
}
|