narraeon 0.7.10 → 0.8.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/modelConnections.js +15 -0
- package/dist/node/protocol/modelUsage.js +4 -0
- package/dist/node/protocol/sillyTavernContent.js +1 -0
- package/dist/node/protocol/v1.js +97 -0
- package/dist/node/runtime/V1Runtime.js +105 -3
- package/dist/node/runtime/authoring/AuthoringEditPlan.js +79 -0
- package/dist/node/runtime/authoring/AuthoringRequestSnapshot.js +15 -3
- package/dist/node/runtime/authoring/AuthoringRetry.js +59 -0
- package/dist/node/runtime/authoring/DamagedGoogleContinuation.js +68 -0
- package/dist/node/runtime/authoring/ModelToolConversation.js +66 -25
- package/dist/node/runtime/content/ContentWorkspace.js +10 -2
- package/dist/node/runtime/content/CurrentTreeContentLibrary.js +14 -8
- package/dist/node/runtime/content/SillyTavernContent.js +796 -0
- package/dist/node/runtime/model/AiFailureLog.js +8 -1
- package/dist/node/runtime/model/DispatchFailure.js +8 -0
- package/dist/node/runtime/model/FileNativeModelAdapters.js +627 -18
- package/dist/node/runtime/model/GoogleHopJournal.js +90 -0
- package/dist/node/runtime/model/GoogleInteractionsStream.js +242 -0
- package/dist/node/runtime/model/GoogleRequestPreview.js +184 -0
- package/dist/node/runtime/model/ModelConnectionStore.js +4 -1
- package/dist/node/runtime/model/ProviderExchangeState.js +44 -1
- package/dist/node/runtime/model/ProviderStream.js +4 -2
- package/dist/node/runtime/play/FileNativePlayAdvanceStore.js +4 -4
- package/dist/node/runtime/play/FileNativePlayPresetStore.js +150 -78
- package/dist/node/runtime/play/FileNativePlayTimelineStore.js +199 -10
- package/dist/node/runtime/play/OrderedPlayPrompts.js +139 -178
- package/dist/node/runtime/play/PlayAdvanceLifecycle.js +51 -23
- package/dist/node/runtime/play/PlayCallChain.js +92 -8
- package/dist/node/runtime/play/PlayFollowupRequests.js +23 -3
- package/dist/node/runtime/prompt/PromptCompilationCodec.js +2 -1
- package/dist/node/runtime/setting/FileNativeSettingImprovementStore.js +321 -15
- package/dist/node/runtime/setting/SettingImprovementSession.js +285 -21
- package/dist/node/runtime/world-revision/FileNativeWorldRevisionStore.js +236 -15
- package/dist/node/runtime/world-revision/WorldRevisionSession.js +324 -50
- package/dist/node/runtime/world-revision/WorldRevisionWorkspace.js +47 -1
- package/dist/node/shared/application-preset-files.js +29 -0
- package/dist/node/shared/default-preset-host.js +50 -38
- package/dist/node/shared/first-party-action-choices.js +7 -11
- package/dist/node/shared/first-party-generic-panels.js +7 -11
- package/dist/node/shared/first-party-player-view.js +7 -11
- package/dist/node/shared/ordered-author-prompts.js +6 -4
- package/dist/node/shared/ordered-play-prompts.js +4 -2
- package/dist/node/shared/prompt-arrangement.js +205 -0
- package/dist/node/shared/sillytavern-preset.js +454 -0
- package/dist/web/assets/index-BthiDIQu.js +1432 -0
- package/dist/web/assets/{index-DH2BVsYd.css → index-wO9Y4HT1.css} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-B2kbaOGe.js +0 -1408
|
@@ -1,8 +1,29 @@
|
|
|
1
|
+
import { prepareAuthoringDispatch, failAuthoringDispatch, } from "./AuthoringRetry.js";
|
|
1
2
|
import { randomUUID } from "node:crypto";
|
|
2
3
|
import { aggregateModelUsage, } from "../../protocol/modelUsage.js";
|
|
3
4
|
import { ModelHostCancelledError } from "../model/ModelHost.js";
|
|
5
|
+
import { withGoogleHop } from "../model/GoogleRequestPreview.js";
|
|
4
6
|
const maximumExchangesPerMessage = 64;
|
|
5
7
|
const maximumStreamTailCharacters = 240;
|
|
8
|
+
export function authoringExchange(session, requestId, boundaries) {
|
|
9
|
+
const bootstrap = session.requests?.at(-1)?.bootstrap ?? session.bootstrap;
|
|
10
|
+
return {
|
|
11
|
+
bootstrap,
|
|
12
|
+
toolUniverse: bootstrap.toolUniverse,
|
|
13
|
+
allowedTools: bootstrap.toolUniverse.map(({ name }) => name),
|
|
14
|
+
toolStrategy: bootstrap.toolStrategy,
|
|
15
|
+
tools: bootstrap.tools,
|
|
16
|
+
appended: session.modelItems,
|
|
17
|
+
...(boundaries === undefined
|
|
18
|
+
? {}
|
|
19
|
+
: { worldRevisionBoundaries: boundaries }),
|
|
20
|
+
requestId,
|
|
21
|
+
operationId: session.sessionId,
|
|
22
|
+
requestAttempt: 1,
|
|
23
|
+
exchange: session.exchange + 1,
|
|
24
|
+
maxOutputTokens: session.modelBinding.maxOutputTokens,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
6
27
|
/**
|
|
7
28
|
* Deep Module for the shared authoring-conversation loop. Its Interface leaves
|
|
8
29
|
* content-package and world-revision publication behind the settlement seam.
|
|
@@ -56,41 +77,51 @@ export class ModelToolConversation {
|
|
|
56
77
|
}
|
|
57
78
|
async #execute(input, live) {
|
|
58
79
|
const { session } = input;
|
|
59
|
-
|
|
80
|
+
let phase = "settling";
|
|
60
81
|
try {
|
|
61
82
|
for (let round = 0; round < maximumExchangesPerMessage; round += 1) {
|
|
62
|
-
session.
|
|
83
|
+
let request = authoringExchange(session, input.exchangeRequestId ?? live.requestId, input.worldRevisionBoundaries);
|
|
84
|
+
if (input.retrySupported)
|
|
85
|
+
request = prepareAuthoringDispatch(session, request);
|
|
86
|
+
session.exchange = Math.max(session.exchange, request.exchange ?? session.exchange + 1);
|
|
87
|
+
if (session.modelBinding.provider === "google_interactions")
|
|
88
|
+
session.googleOutcomeUnknown = true;
|
|
63
89
|
live.streaming = emptyStreaming();
|
|
64
90
|
session.updatedAt = Date.now();
|
|
91
|
+
phase = "preparing";
|
|
65
92
|
await input.save(session);
|
|
66
93
|
input.changed?.(true);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
toolUniverse: bootstrap.toolUniverse,
|
|
70
|
-
allowedTools: bootstrap.toolUniverse.map(({ name }) => name),
|
|
71
|
-
toolStrategy: bootstrap.toolStrategy,
|
|
72
|
-
tools: bootstrap.tools,
|
|
73
|
-
appended: session.modelItems,
|
|
74
|
-
requestId: live.requestId,
|
|
75
|
-
operationId: session.sessionId,
|
|
76
|
-
requestAttempt: 1,
|
|
77
|
-
exchange: session.exchange,
|
|
78
|
-
maxOutputTokens: session.modelBinding.maxOutputTokens,
|
|
79
|
-
}, {
|
|
94
|
+
phase = "dispatched";
|
|
95
|
+
const response = await input.host.exchange(request, {
|
|
80
96
|
signal: live.controller.signal,
|
|
97
|
+
onGoogleHop: (hop) => {
|
|
98
|
+
const requestId = input.exchangeRequestId ?? live.requestId;
|
|
99
|
+
const snapshot = session.requests?.findLast((entry) => entry.requestId === requestId);
|
|
100
|
+
if (snapshot?.wireRequest === undefined)
|
|
101
|
+
return;
|
|
102
|
+
snapshot.wireRequest = withGoogleHop(snapshot.wireRequest, hop);
|
|
103
|
+
return input.recordGoogleHop?.(requestId, hop);
|
|
104
|
+
},
|
|
81
105
|
onDelta: (delta) => {
|
|
82
106
|
recordDelta(live, delta);
|
|
83
107
|
input.changed?.(false);
|
|
84
108
|
},
|
|
85
109
|
});
|
|
110
|
+
if (live.controller.signal.aborted)
|
|
111
|
+
throw new ModelHostCancelledError("The authoring request was cancelled");
|
|
112
|
+
phase = "validating";
|
|
86
113
|
assertCompleteResponse(response);
|
|
87
114
|
const toolCalls = response.toolCalls ?? [];
|
|
88
115
|
assertUniqueToolCallIds(toolCalls);
|
|
89
116
|
const visibleText = response.text ?? "";
|
|
90
|
-
|
|
117
|
+
session.usage = aggregateModelUsage(session.usage, response.usage);
|
|
118
|
+
if (toolCalls.length === 0 && visibleText.trim().length === 0) {
|
|
119
|
+
phase = "dispatched";
|
|
91
120
|
throw new Error(input.failure?.emptyResponse ??
|
|
92
121
|
"The model returned an empty tool-free authoring response");
|
|
93
|
-
|
|
122
|
+
}
|
|
123
|
+
delete session.retryDispatch;
|
|
124
|
+
phase = "settling";
|
|
94
125
|
session.modelItems.push({
|
|
95
126
|
kind: "assistant",
|
|
96
127
|
text: visibleText,
|
|
@@ -100,6 +131,8 @@ export class ModelToolConversation {
|
|
|
100
131
|
providerState: response.providerState,
|
|
101
132
|
toolCalls: structuredClone(toolCalls),
|
|
102
133
|
});
|
|
134
|
+
if (session.modelBinding.provider === "google_interactions")
|
|
135
|
+
session.googleOutcomeUnknown = false;
|
|
103
136
|
session.updatedAt = Date.now();
|
|
104
137
|
if (toolCalls.length === 0) {
|
|
105
138
|
session.messages.push({
|
|
@@ -121,6 +154,7 @@ export class ModelToolConversation {
|
|
|
121
154
|
}
|
|
122
155
|
// The exchange budget only bounds a runaway loop. Every tool response is
|
|
123
156
|
// already settled, so the conversation pauses and can resume unchanged.
|
|
157
|
+
delete session.retryDispatch;
|
|
124
158
|
session.runStatus = "paused";
|
|
125
159
|
session.activeRequestId = null;
|
|
126
160
|
session.completedRequestIds = rememberRequest(session.completedRequestIds, live.requestId);
|
|
@@ -130,17 +164,20 @@ export class ModelToolConversation {
|
|
|
130
164
|
return input.view(session);
|
|
131
165
|
}
|
|
132
166
|
catch (error) {
|
|
167
|
+
failAuthoringDispatch(session, error, phase);
|
|
133
168
|
session.runStatus = "interrupted";
|
|
134
169
|
session.activeRequestId = null;
|
|
135
170
|
session.completedRequestIds = rememberRequest(session.completedRequestIds, live.requestId);
|
|
136
171
|
session.lastFailure =
|
|
137
|
-
|
|
138
|
-
?
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
:
|
|
143
|
-
|
|
172
|
+
session.googleOutcomeUnknown === true
|
|
173
|
+
? "The Google request outcome is unknown; start a fresh model context before sending again."
|
|
174
|
+
: error instanceof ModelHostCancelledError
|
|
175
|
+
? (input.failure?.cancelled ??
|
|
176
|
+
"The authoring response was cancelled. Complete tool responses already settled were retained.")
|
|
177
|
+
: error instanceof Error
|
|
178
|
+
? error.message
|
|
179
|
+
: (input.failure?.interrupted ??
|
|
180
|
+
"The authoring response was interrupted");
|
|
144
181
|
session.updatedAt = Date.now();
|
|
145
182
|
await input.save(session);
|
|
146
183
|
return input.view(session);
|
|
@@ -170,7 +207,11 @@ export function appendAuthoringUserMessage(session, message, requestId) {
|
|
|
170
207
|
export function resumePausedAuthoringConversation(session) {
|
|
171
208
|
if (session.runStatus !== "paused")
|
|
172
209
|
throw new Error("Only a paused authoring conversation can be continued");
|
|
173
|
-
|
|
210
|
+
const last = session.modelItems.at(-1);
|
|
211
|
+
if (last?.kind !== "tool" &&
|
|
212
|
+
!(session.modelBinding.provider === "google_interactions" &&
|
|
213
|
+
session.googleOutcomeUnknown === false &&
|
|
214
|
+
last?.kind === "user"))
|
|
174
215
|
throw new Error("The paused authoring conversation does not end with settled tool results");
|
|
175
216
|
session.runStatus = "running";
|
|
176
217
|
session.activeRequestId = session.requests?.at(-1)?.requestId ?? null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isAbsolute, win32 } from "node:path";
|
|
2
2
|
import { inflateRawSync } from "node:zlib";
|
|
3
|
+
import { FileNativeSettingImprovementStore } from "../setting/FileNativeSettingImprovementStore.js";
|
|
3
4
|
import { portableContentTreePathKey } from "../../protocol/contentTree.js";
|
|
4
5
|
import { fictionGameplay, gameplayFile, parseGameplay, } from "../../protocol/gameplay.js";
|
|
5
6
|
import { defaultAppLocale, } from "../../protocol/appPreferences.js";
|
|
@@ -36,6 +37,10 @@ export class ContentWorkspace {
|
|
|
36
37
|
limits: this.#limits,
|
|
37
38
|
...options.currentTree,
|
|
38
39
|
});
|
|
40
|
+
const recovery = new FileNativeSettingImprovementStore(dataRoot, {
|
|
41
|
+
content: this,
|
|
42
|
+
});
|
|
43
|
+
this.#currentTreeLibrary.setBeforeLease((id, lease) => recovery.recoverPendingEdits(id, lease));
|
|
39
44
|
}
|
|
40
45
|
createCurrentTreeContentPackage(gameplay = fictionGameplay) {
|
|
41
46
|
const locale = this.#locale();
|
|
@@ -64,8 +69,8 @@ export class ContentWorkspace {
|
|
|
64
69
|
readCurrentTreeContentPackage(localId) {
|
|
65
70
|
return this.#currentTreeLibrary.readPackage(localId);
|
|
66
71
|
}
|
|
67
|
-
beginCurrentTreeContentPackageOperation(localId) {
|
|
68
|
-
return this.#currentTreeLibrary.acquireOperationLease(localId);
|
|
72
|
+
beginCurrentTreeContentPackageOperation(localId, options = {}) {
|
|
73
|
+
return this.#currentTreeLibrary.acquireOperationLease(localId, options);
|
|
69
74
|
}
|
|
70
75
|
inspectCurrentTreeContentPackage(files) {
|
|
71
76
|
return inspectContentPackageCurrentTree(files);
|
|
@@ -96,6 +101,9 @@ export class ContentWorkspace {
|
|
|
96
101
|
}, options.signal === undefined ? {} : { signal: options.signal });
|
|
97
102
|
});
|
|
98
103
|
}
|
|
104
|
+
importSillyTavernContent(title, files) {
|
|
105
|
+
return this.#mutate(() => this.#currentTreeLibrary.importPackage({ title, files }));
|
|
106
|
+
}
|
|
99
107
|
copyCurrentTreeContentPackage(localId, options = {}) {
|
|
100
108
|
return this.#mutate(() => this.#currentTreeLibrary.copyPackage(localId, options.signal === undefined ? {} : { signal: options.signal }));
|
|
101
109
|
}
|
|
@@ -61,6 +61,10 @@ export class CurrentTreeContentLibrary {
|
|
|
61
61
|
#beforeCurrentTreeReplace;
|
|
62
62
|
#mutationTail = Promise.resolve();
|
|
63
63
|
#legacyLocksRemoval;
|
|
64
|
+
#beforeLease;
|
|
65
|
+
setBeforeLease(hook) {
|
|
66
|
+
this.#beforeLease = hook;
|
|
67
|
+
}
|
|
64
68
|
constructor(dataRoot, options = {}) {
|
|
65
69
|
this.#legacyLocksRoot = join(dataRoot, "content", ".package-locks");
|
|
66
70
|
this.#packagesRoot = join(dataRoot, "content", "packages");
|
|
@@ -162,9 +166,6 @@ export class CurrentTreeContentLibrary {
|
|
|
162
166
|
}
|
|
163
167
|
}
|
|
164
168
|
async readPackage(localId) {
|
|
165
|
-
const snapshot = await this.#readPackageSnapshot(localId);
|
|
166
|
-
if (snapshot.metadata.schemaVersion === 2)
|
|
167
|
-
return snapshot.package;
|
|
168
169
|
const lease = await this.acquireOperationLease(localId, { wait: true });
|
|
169
170
|
try {
|
|
170
171
|
await ensureStoredPackageTitle(this.#packageRoot(localId), localId, lease.package.title);
|
|
@@ -221,7 +222,7 @@ export class CurrentTreeContentLibrary {
|
|
|
221
222
|
localId,
|
|
222
223
|
title: normalizedTitle,
|
|
223
224
|
});
|
|
224
|
-
return packageSummary(
|
|
225
|
+
return packageSummary({ ...lease.package, title: normalizedTitle });
|
|
225
226
|
}
|
|
226
227
|
finally {
|
|
227
228
|
lease.release();
|
|
@@ -283,19 +284,24 @@ export class CurrentTreeContentLibrary {
|
|
|
283
284
|
releaseInProcessPackageLease(packageRoot);
|
|
284
285
|
};
|
|
285
286
|
try {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
package
|
|
287
|
+
let package_ = (await this.#readPackageSnapshot(localId)).package;
|
|
288
|
+
const lease = {
|
|
289
|
+
get package() {
|
|
290
|
+
return structuredClone(package_);
|
|
291
|
+
},
|
|
289
292
|
replace: async (files, options = {}) => {
|
|
290
293
|
if (released)
|
|
291
294
|
throw new CurrentTreeContentPackageBusyError();
|
|
292
295
|
options.signal?.throwIfAborted();
|
|
293
296
|
const normalized = normalizeCurrentContentTreeFiles(files, this.#limits);
|
|
294
297
|
assertGameplayModeUnchanged(package_.files, normalized);
|
|
295
|
-
|
|
298
|
+
package_ = await this.#replaceNormalizedCurrentTree(localId, package_.title, normalized, options.signal);
|
|
299
|
+
return structuredClone(package_);
|
|
296
300
|
},
|
|
297
301
|
release,
|
|
298
302
|
};
|
|
303
|
+
await this.#beforeLease?.(localId, lease);
|
|
304
|
+
return lease;
|
|
299
305
|
}
|
|
300
306
|
catch (error) {
|
|
301
307
|
release();
|