veryfront 0.1.402 → 0.1.404
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/esm/cli/commands/install/registry.d.ts.map +1 -1
- package/esm/cli/commands/install/registry.js +9 -3
- package/esm/cli/templates/manifest.d.ts +30 -0
- package/esm/cli/templates/manifest.js +30 -0
- package/esm/deno.js +1 -1
- package/esm/src/agent/conversation-hosted-terminal.d.ts +17 -0
- package/esm/src/agent/conversation-hosted-terminal.d.ts.map +1 -1
- package/esm/src/agent/conversation-hosted-terminal.js +45 -0
- package/esm/src/agent/hosted-child-status.d.ts +5 -0
- package/esm/src/agent/hosted-child-status.d.ts.map +1 -1
- package/esm/src/agent/hosted-child-status.js +14 -0
- package/esm/src/agent/index.d.ts +1 -1
- package/esm/src/agent/index.d.ts.map +1 -1
- package/esm/src/agent/index.js +1 -1
- package/esm/src/config/schemas/config.schema.d.ts +18 -0
- package/esm/src/config/schemas/config.schema.d.ts.map +1 -1
- package/esm/src/config/schemas/config.schema.js +16 -0
- package/esm/src/observability/file-log-subscriber.d.ts +32 -0
- package/esm/src/observability/file-log-subscriber.d.ts.map +1 -0
- package/esm/src/observability/file-log-subscriber.js +163 -0
- package/esm/src/observability/index.d.ts +1 -0
- package/esm/src/observability/index.d.ts.map +1 -1
- package/esm/src/observability/index.js +1 -0
- package/esm/src/server/bootstrap.d.ts.map +1 -1
- package/esm/src/server/bootstrap.js +149 -97
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/cli/commands/install/registry.ts +10 -3
- package/src/cli/templates/manifest.js +30 -0
- package/src/deno.js +1 -1
- package/src/src/agent/conversation-hosted-terminal.ts +86 -0
- package/src/src/agent/hosted-child-status.ts +27 -0
- package/src/src/agent/index.ts +10 -0
- package/src/src/config/schemas/config.schema.ts +16 -0
- package/src/src/observability/file-log-subscriber.ts +187 -0
- package/src/src/observability/index.ts +7 -0
- package/src/src/server/bootstrap.ts +184 -119
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/observability/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,KAAK,WAAW,EAChB,SAAS,EACT,KAAK,aAAa,EAClB,cAAc,EACd,QAAQ,EACR,YAAY,GACb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,KAAK,aAAa,EAClB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,KAAK,oBAAoB,EACzB,uBAAuB,EACvB,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,cAAc,EACd,aAAa,EACb,KAAK,UAAU,EACf,YAAY,GACb,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,QAAQ,EACb,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,KAAK,QAAQ,EACb,KAAK,SAAS,IAAI,eAAe,EACjC,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,cAAc,GACf,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/observability/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,KAAK,WAAW,EAChB,SAAS,EACT,KAAK,aAAa,EAClB,cAAc,EACd,QAAQ,EACR,YAAY,GACb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,KAAK,aAAa,EAClB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,KAAK,oBAAoB,EACzB,uBAAuB,EACvB,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,cAAc,EACd,aAAa,EACb,KAAK,UAAU,EACf,YAAY,GACb,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,QAAQ,EACb,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,KAAK,QAAQ,EACb,KAAK,SAAS,IAAI,eAAe,EACjC,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,cAAc,GACf,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,uBAAuB,EACvB,KAAK,aAAa,EAClB,iBAAiB,EACjB,YAAY,GACb,MAAM,0BAA0B,CAAC"}
|
|
@@ -10,3 +10,4 @@ export { initAutoInstrumentation, instrument, instrumentBatch, instrumentErrorHa
|
|
|
10
10
|
export { initializeOTLP, isOTLPEnabled, shutdownOTLP, } from "./tracing/otlp-setup.js";
|
|
11
11
|
export { ErrorCollector, getErrorCollector, parseCompileError, resetErrorCollector, } from "./error-collector.js";
|
|
12
12
|
export { getLogBuffer, interceptConsole, LogBuffer, resetLogBuffer, } from "./log-buffer.js";
|
|
13
|
+
export { createFileLogSubscriber, FileLogSubscriber, parseMaxSize, } from "./file-log-subscriber.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/src/server/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EAAE,KAAK,eAAe,EAAqC,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/src/server/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EAAE,KAAK,eAAe,EAAqC,MAAM,wBAAwB,CAAC;AA4CjG,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,OAAO,EAAE,cAAc,CAAC;IAExB,2BAA2B;IAC3B,MAAM,EAAE,eAAe,CAAC;IAExB,wCAAwC;IACxC,cAAc,EAAE,OAAO,CAAC;IAExB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,eAAe,EAAE,eAAe,CAAC;IAEjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAgHD;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,EAC3C,SAAS,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,GAClC,OAAO,CAAC,eAAe,CAAC,CAO1B;AAkDD,wBAAsB,SAAS,CAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAmK1B;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAa1B;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAyB1B"}
|
|
@@ -16,6 +16,8 @@ import { initializeEsbuild } from "../platform/compat/esbuild.js";
|
|
|
16
16
|
import { logger } from "../utils/index.js";
|
|
17
17
|
import { isDebugEnabled } from "../utils/constants/env.js";
|
|
18
18
|
import { getEnvSource, hasEnvLoaded, loadEnv, markEnvLoaded, supportsEnvFiles, } from "../utils/env-loader.js";
|
|
19
|
+
import { getLogBuffer } from "../observability/log-buffer.js";
|
|
20
|
+
import { createFileLogSubscriber, } from "../observability/file-log-subscriber.js";
|
|
19
21
|
import { ReloadNotifier } from "./reload-notifier.js";
|
|
20
22
|
import { clearDomainCache } from "./utils/domain-lookup.js";
|
|
21
23
|
const bootstrapLog = logger.component("bootstrap");
|
|
@@ -60,14 +62,51 @@ function wireTracingShim() {
|
|
|
60
62
|
bootstrapLog.debug("[bootstrap] no TracingExporter extension — using no-op tracer");
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
|
-
|
|
65
|
+
const DEFAULT_FILE_LOG_PATH = ".veryfront/logs/server.log";
|
|
66
|
+
const DEFAULT_FILE_LOG_MAX_SIZE = "10mb";
|
|
67
|
+
const DEFAULT_FILE_LOG_MAX_FILES = 5;
|
|
68
|
+
const DEFAULT_FILE_LOG_LEVEL = "warn";
|
|
69
|
+
const DEFAULT_FILE_LOG_FORMAT = "json";
|
|
70
|
+
function maybeAttachFileLogSubscriber(config) {
|
|
71
|
+
const fileConfig = config.observability?.logging?.file;
|
|
72
|
+
if (!fileConfig?.enabled)
|
|
73
|
+
return null;
|
|
74
|
+
const resolved = {
|
|
75
|
+
enabled: true,
|
|
76
|
+
path: fileConfig.path ?? DEFAULT_FILE_LOG_PATH,
|
|
77
|
+
maxSize: fileConfig.maxSize ?? DEFAULT_FILE_LOG_MAX_SIZE,
|
|
78
|
+
maxFiles: fileConfig.maxFiles ?? DEFAULT_FILE_LOG_MAX_FILES,
|
|
79
|
+
level: fileConfig.level ?? DEFAULT_FILE_LOG_LEVEL,
|
|
80
|
+
format: fileConfig.format ?? DEFAULT_FILE_LOG_FORMAT,
|
|
81
|
+
};
|
|
82
|
+
const subscriber = createFileLogSubscriber(resolved);
|
|
83
|
+
const unsubscribe = getLogBuffer().subscribe(subscriber.getSubscriber());
|
|
84
|
+
bootstrapLog.debug("[bootstrap] File log subscriber attached", {
|
|
85
|
+
path: resolved.path,
|
|
86
|
+
level: resolved.level,
|
|
87
|
+
format: resolved.format,
|
|
88
|
+
});
|
|
89
|
+
return { subscriber, unsubscribe };
|
|
90
|
+
}
|
|
91
|
+
async function teardownFileLog(handle) {
|
|
92
|
+
if (!handle)
|
|
93
|
+
return;
|
|
94
|
+
handle.unsubscribe();
|
|
95
|
+
await handle.subscriber.close();
|
|
96
|
+
}
|
|
97
|
+
function combineDispose(extensionLoader, fsDispose, fileLogHandle) {
|
|
64
98
|
return async () => {
|
|
65
99
|
try {
|
|
66
100
|
await extensionLoader.teardownAll();
|
|
67
101
|
}
|
|
68
102
|
finally {
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
try {
|
|
104
|
+
await teardownFileLog(fileLogHandle ?? null);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
if (fsDispose)
|
|
108
|
+
fsDispose();
|
|
109
|
+
}
|
|
71
110
|
}
|
|
72
111
|
};
|
|
73
112
|
}
|
|
@@ -144,118 +183,131 @@ export async function bootstrap(projectDir, adapter) {
|
|
|
144
183
|
await ensureEnvLoaded(projectDir, adapter);
|
|
145
184
|
bootstrapLog.debug("Loading config with base adapter");
|
|
146
185
|
let config = await getConfig(projectDir, adapter);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
186
|
+
let fileLog = maybeAttachFileLogSubscriber(config);
|
|
187
|
+
try {
|
|
188
|
+
const fsType = config.fs?.type;
|
|
189
|
+
const needsFSAdapter = fsType != null && fsType !== "local";
|
|
190
|
+
if (!needsFSAdapter) {
|
|
191
|
+
bootstrapLog.debug("Using local filesystem (no FSAdapter needed)");
|
|
192
|
+
const extensionLoader = await orchestrateExtensions({
|
|
193
|
+
projectDir,
|
|
194
|
+
config,
|
|
195
|
+
logger: bootstrapLog,
|
|
196
|
+
primeContracts: { [AIProviderRegistryName]: createAIProviderRegistry() },
|
|
197
|
+
builtinExtensions: createBuiltinExtensions(),
|
|
198
|
+
});
|
|
199
|
+
wireTracingShim();
|
|
200
|
+
assertRequiredContracts();
|
|
201
|
+
return {
|
|
202
|
+
adapter,
|
|
203
|
+
config,
|
|
204
|
+
usingFSAdapter: false,
|
|
205
|
+
extensionLoader,
|
|
206
|
+
dispose: combineDispose(extensionLoader, undefined, fileLog),
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
bootstrapLog.debug("Initializing FSAdapter", { type: fsType });
|
|
210
|
+
// Inject server-layer callbacks into FS config so the platform layer
|
|
211
|
+
// doesn't need to import from the server layer
|
|
212
|
+
const fsWithCallbacks = {
|
|
213
|
+
...config.fs,
|
|
214
|
+
invalidationCallbacks: {
|
|
215
|
+
triggerReload: (changedPaths, project) => ReloadNotifier.triggerReload(changedPaths, project),
|
|
216
|
+
clearDomainCache,
|
|
217
|
+
},
|
|
166
218
|
};
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
219
|
+
const enhancedAdapter = await enhanceAdapterWithFS(adapter, { ...config, fs: fsWithCallbacks }, projectDir);
|
|
220
|
+
if (enhancedAdapter === adapter) {
|
|
221
|
+
bootstrapLog.debug("Framework initialized successfully", {
|
|
222
|
+
projectDir,
|
|
223
|
+
runtime: adapter.id,
|
|
224
|
+
fsAdapter: "local",
|
|
225
|
+
});
|
|
226
|
+
const extensionLoader = await orchestrateExtensions({
|
|
227
|
+
projectDir,
|
|
228
|
+
config,
|
|
229
|
+
logger: bootstrapLog,
|
|
230
|
+
primeContracts: { [AIProviderRegistryName]: createAIProviderRegistry() },
|
|
231
|
+
builtinExtensions: createBuiltinExtensions(),
|
|
232
|
+
});
|
|
233
|
+
wireTracingShim();
|
|
234
|
+
assertRequiredContracts();
|
|
235
|
+
return {
|
|
236
|
+
adapter,
|
|
237
|
+
config,
|
|
238
|
+
usingFSAdapter: false,
|
|
239
|
+
extensionLoader,
|
|
240
|
+
dispose: combineDispose(extensionLoader, undefined, fileLog),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
const isProxyMode = config.fs?.veryfront?.proxyMode === true;
|
|
244
|
+
const isProductionMode = config.fs?.veryfront?.productionMode === true;
|
|
245
|
+
if (isProxyMode) {
|
|
246
|
+
bootstrapLog.debug("Skipping config reload in proxy mode (using local config)");
|
|
247
|
+
}
|
|
248
|
+
else if (isProductionMode) {
|
|
249
|
+
bootstrapLog.debug("Skipping config reload in production mode (using local config)");
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
bootstrapLog.debug("Reloading config with FSAdapter");
|
|
253
|
+
clearConfigCache();
|
|
254
|
+
const originalConfig = config;
|
|
255
|
+
const reloadedConfig = await getConfig(projectDir, enhancedAdapter);
|
|
256
|
+
const usesDefaultDevConfig = reloadedConfig.dev?.port === 3000 &&
|
|
257
|
+
reloadedConfig.dev?.host === "localhost" &&
|
|
258
|
+
!reloadedConfig.dev?.hmr;
|
|
259
|
+
if (usesDefaultDevConfig && originalConfig.dev) {
|
|
260
|
+
bootstrapLog.debug("Keeping original config (FSAdapter returned defaults)");
|
|
261
|
+
config = originalConfig;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
config = reloadedConfig;
|
|
265
|
+
}
|
|
266
|
+
// Re-attach file log subscriber if config was reloaded with different settings
|
|
267
|
+
const newFileLog = maybeAttachFileLogSubscriber(config);
|
|
268
|
+
if (newFileLog) {
|
|
269
|
+
await teardownFileLog(fileLog);
|
|
270
|
+
fileLog = newFileLog;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
180
273
|
bootstrapLog.debug("Framework initialized successfully", {
|
|
181
274
|
projectDir,
|
|
182
275
|
runtime: adapter.id,
|
|
183
|
-
fsAdapter:
|
|
276
|
+
fsAdapter: fsType,
|
|
184
277
|
});
|
|
185
|
-
|
|
278
|
+
let fsDispose;
|
|
279
|
+
if (isExtendedFSAdapter(enhancedAdapter.fs)) {
|
|
280
|
+
const underlying = enhancedAdapter.fs.getUnderlyingAdapter();
|
|
281
|
+
if ("dispose" in underlying &&
|
|
282
|
+
typeof underlying.dispose === "function") {
|
|
283
|
+
fsDispose = () => underlying.dispose();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// If extension orchestration fails after the FS adapter has been wired up,
|
|
287
|
+
// release the FS resources (WebSocket connections, caches) before
|
|
288
|
+
// propagating the error — otherwise the adapter would leak.
|
|
289
|
+
const extensionLoader = await orchestrateOrDisposeFS(() => orchestrateExtensions({
|
|
186
290
|
projectDir,
|
|
187
291
|
config,
|
|
188
292
|
logger: bootstrapLog,
|
|
189
293
|
primeContracts: { [AIProviderRegistryName]: createAIProviderRegistry() },
|
|
190
294
|
builtinExtensions: createBuiltinExtensions(),
|
|
191
|
-
});
|
|
295
|
+
}), fsDispose);
|
|
192
296
|
wireTracingShim();
|
|
193
297
|
assertRequiredContracts();
|
|
194
298
|
return {
|
|
195
|
-
adapter,
|
|
299
|
+
adapter: enhancedAdapter,
|
|
196
300
|
config,
|
|
197
|
-
usingFSAdapter:
|
|
301
|
+
usingFSAdapter: true,
|
|
302
|
+
fsAdapterType: fsType,
|
|
198
303
|
extensionLoader,
|
|
199
|
-
dispose: combineDispose(extensionLoader),
|
|
304
|
+
dispose: combineDispose(extensionLoader, fsDispose, fileLog),
|
|
200
305
|
};
|
|
201
306
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
bootstrapLog.debug("Skipping config reload in proxy mode (using local config)");
|
|
206
|
-
}
|
|
207
|
-
else if (isProductionMode) {
|
|
208
|
-
bootstrapLog.debug("Skipping config reload in production mode (using local config)");
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
bootstrapLog.debug("Reloading config with FSAdapter");
|
|
212
|
-
clearConfigCache();
|
|
213
|
-
const originalConfig = config;
|
|
214
|
-
const reloadedConfig = await getConfig(projectDir, enhancedAdapter);
|
|
215
|
-
const usesDefaultDevConfig = reloadedConfig.dev?.port === 3000 &&
|
|
216
|
-
reloadedConfig.dev?.host === "localhost" &&
|
|
217
|
-
!reloadedConfig.dev?.hmr;
|
|
218
|
-
if (usesDefaultDevConfig && originalConfig.dev) {
|
|
219
|
-
bootstrapLog.debug("Keeping original config (FSAdapter returned defaults)");
|
|
220
|
-
config = originalConfig;
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
config = reloadedConfig;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
bootstrapLog.debug("Framework initialized successfully", {
|
|
227
|
-
projectDir,
|
|
228
|
-
runtime: adapter.id,
|
|
229
|
-
fsAdapter: fsType,
|
|
230
|
-
});
|
|
231
|
-
let fsDispose;
|
|
232
|
-
if (isExtendedFSAdapter(enhancedAdapter.fs)) {
|
|
233
|
-
const underlying = enhancedAdapter.fs.getUnderlyingAdapter();
|
|
234
|
-
if ("dispose" in underlying &&
|
|
235
|
-
typeof underlying.dispose === "function") {
|
|
236
|
-
fsDispose = () => underlying.dispose();
|
|
237
|
-
}
|
|
307
|
+
catch (err) {
|
|
308
|
+
await teardownFileLog(fileLog);
|
|
309
|
+
throw err;
|
|
238
310
|
}
|
|
239
|
-
// If extension orchestration fails after the FS adapter has been wired up,
|
|
240
|
-
// release the FS resources (WebSocket connections, caches) before
|
|
241
|
-
// propagating the error — otherwise the adapter would leak.
|
|
242
|
-
const extensionLoader = await orchestrateOrDisposeFS(() => orchestrateExtensions({
|
|
243
|
-
projectDir,
|
|
244
|
-
config,
|
|
245
|
-
logger: bootstrapLog,
|
|
246
|
-
primeContracts: { [AIProviderRegistryName]: createAIProviderRegistry() },
|
|
247
|
-
builtinExtensions: createBuiltinExtensions(),
|
|
248
|
-
}), fsDispose);
|
|
249
|
-
wireTracingShim();
|
|
250
|
-
assertRequiredContracts();
|
|
251
|
-
return {
|
|
252
|
-
adapter: enhancedAdapter,
|
|
253
|
-
config,
|
|
254
|
-
usingFSAdapter: true,
|
|
255
|
-
fsAdapterType: fsType,
|
|
256
|
-
extensionLoader,
|
|
257
|
-
dispose: combineDispose(extensionLoader, fsDispose),
|
|
258
|
-
};
|
|
259
311
|
}
|
|
260
312
|
export async function bootstrapDev(projectDir, adapter) {
|
|
261
313
|
bootstrapDevLog.debug("Starting development mode initialization");
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.404";
|
|
2
2
|
//# sourceMappingURL=version-constant.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import manifest from "../../templates/manifest.js";
|
|
2
2
|
import { type AITool, type AIToolId, AIToolIdSchema, AIToolSchema } from "./types.js";
|
|
3
3
|
|
|
4
4
|
const AI_TOOLS_RAW = [
|
|
@@ -67,6 +67,13 @@ export function isValidToolId(id: string): id is AIToolId {
|
|
|
67
67
|
|
|
68
68
|
export function getTemplateContent(toolId: string): Promise<string> {
|
|
69
69
|
const { template } = getToolById(toolId);
|
|
70
|
-
const
|
|
71
|
-
|
|
70
|
+
const entry = (manifest as Record<string, unknown>).templates as Record<
|
|
71
|
+
string,
|
|
72
|
+
{ files: Record<string, string> }
|
|
73
|
+
>;
|
|
74
|
+
const aiRule = entry[`ai-rules:${template}`];
|
|
75
|
+
if (!aiRule) throw new Error(`Template not found in manifest: ${template}`);
|
|
76
|
+
const content = aiRule.files[template];
|
|
77
|
+
if (!content) throw new Error(`Template file not found in manifest: ${template}`);
|
|
78
|
+
return Promise.resolve(content);
|
|
72
79
|
}
|
|
@@ -587,6 +587,36 @@ export default {
|
|
|
587
587
|
"app/api/auth/docs-google/callback/route.ts": "import { createOAuthCallbackHandler, docsGoogleConfig } from \"veryfront/oauth\";\nimport { tokenStore } from \"../../../../../lib/token-store.ts\";\nimport { oauthMemoryTokenStore } from \"../../../../../lib/oauth-memory-store.ts\";\n\nconst hybridTokenStore = {\n getTokens(serviceId: string, userId: string) {\n return tokenStore.getToken(userId, serviceId);\n },\n async setTokens(\n serviceId: string,\n userId: string,\n tokens: { accessToken: string; refreshToken?: string; expiresAt?: number },\n ) {\n await tokenStore.setToken(userId, serviceId, tokens);\n },\n async clearTokens(serviceId: string, userId: string) {\n await tokenStore.revokeToken(userId, serviceId);\n },\n setState(\n state: string,\n meta: {\n userId: string;\n serviceId: string;\n codeVerifier?: string;\n redirectUri?: string;\n scopes?: string[];\n createdAt: number;\n },\n ) {\n return oauthMemoryTokenStore.setState(state, meta);\n },\n consumeState(state: string) {\n return oauthMemoryTokenStore.consumeState(state);\n },\n};\n\nexport const GET = createOAuthCallbackHandler(docsGoogleConfig, { tokenStore: hybridTokenStore });\n",
|
|
588
588
|
"app/api/auth/docs-google/route.ts": "import { createOAuthInitHandler, docsGoogleConfig } from \"veryfront/oauth\";\nimport { oauthMemoryTokenStore } from \"../../../../../lib/oauth-memory-store.ts\";\n\n// TODO: Replace with real user ID from your auth system (e.g., session cookie, JWT).\n// NEVER return a shared constant in production - it breaks per-user token isolation (VULN-AUTH-2).\nfunction getUserId(_request: Request): string {\n return \"current-user\";\n}\n\nexport const GET = createOAuthInitHandler(docsGoogleConfig, {\n tokenStore: oauthMemoryTokenStore,\n getUserId,\n});"
|
|
589
589
|
}
|
|
590
|
+
},
|
|
591
|
+
"ai-rules:claude-code.md": {
|
|
592
|
+
"files": {
|
|
593
|
+
"claude-code.md": "# Veryfront Project\n\nZero-config React meta-framework for AI-native applications.\n\n## Quick Reference\n\n| Command | Purpose |\n| -------------------------------- | ---------------------------------------- |\n| `veryfront dev` | Start dev server (http://localhost:3000) |\n| `veryfront build` | Production build |\n| `veryfront deploy` | Deploy to Veryfront cloud |\n| `veryfront generate page <name>` | Generate new page |\n| `veryfront generate api <name>` | Generate API route |\n\n## Project Structure\n\n- `src/pages/*.tsx` → Routes (file-based routing)\n- `src/api/*.ts` → API endpoints (`/api/*`)\n- `src/components/` → Shared components\n- `agents/` → AI agents\n- `tools/` → MCP tools\n\n## When Asked to Add Features\n\n1. **Pages**: Create in `src/pages/` (e.g., `about.tsx` → `/about`)\n2. **APIs**: Create in `src/api/` (e.g., `users.ts` → `/api/users`)\n3. **Components**: Create in `src/components/`\n4. **AI Agents**: Create in `agents/`\n\n## Code Patterns\n\n```tsx\n// Page (src/pages/about.tsx)\nexport default function About() {\n return <h1>About</h1>;\n}\n\n// API (src/api/hello.ts)\nexport function GET() {\n return Response.json({ message: \"Hello\" });\n}\n\n// Dynamic API (src/api/users/[id].ts)\nexport function GET(_req: Request, { params }: { params: { id: string } }) {\n return Response.json({ id: params.id });\n}\n```\n\n## Conventions\n\n- Use TypeScript\n- Use React 19 features\n- Use Tailwind for styling\n- Co-locate tests (`*.test.ts`)\n- Use `#veryfront/*` imports\n\n## Testing\n\n- Run `veryfront dev` and check browser\n- API endpoints at `/api/*`\n- Run `deno task test` for tests\n"
|
|
594
|
+
}
|
|
595
|
+
},
|
|
596
|
+
"ai-rules:skill.md": {
|
|
597
|
+
"files": {
|
|
598
|
+
"skill.md": "---\nname: veryfront\ndescription: Build and deploy fullstack AI-native React apps with Veryfront CLI\nlicense: MIT\ncompatibility: Claude Code, Cursor, VS Code, Codex, Gemini CLI\nmetadata:\n author: veryfront\n version: \"1.0\"\n---\n\n# Veryfront\n\nZero-config React meta-framework for AI-native applications.\n\n## Commands\n\n| Command | Purpose |\n| -------------------------------- | --------------------------------- |\n| `veryfront dev` | Start development server with HMR |\n| `veryfront build` | Build for production |\n| `veryfront deploy` | Deploy to Veryfront cloud |\n| `veryfront generate page <name>` | Generate a new page |\n| `veryfront generate api <name>` | Generate an API route |\n\n## Project Structure\n\n```\nsrc/\n├── pages/ # File-based routing (*.tsx → routes)\n├── api/ # API routes (*.ts → /api/*)\n├── components/ # Shared React components\n├── ai/\n│ ├── agents/ # AI agents\n│ └── tools/ # MCP tools\n└── styles/ # Global styles\n```\n\n## Adding Features\n\n- **New page**: Create `src/pages/about.tsx` → `/about`\n- **API endpoint**: Create `src/api/users.ts` → `/api/users`\n- **AI agent**: Create `agents/assistant.ts`\n- **MCP tool**: Create `tools/search.ts`\n\n## Code Examples\n\n### Page Component\n\n```tsx\n// src/pages/about.tsx\nexport default function About() {\n return <h1>About</h1>;\n}\n```\n\n### API Route\n\n```ts\n// src/api/hello.ts\nexport function GET() {\n return Response.json({ message: \"Hello\" });\n}\n```\n\n### Dynamic API Route\n\n```ts\n// src/api/users/[id].ts\nexport function GET(_req: Request, { params }: { params: { id: string } }) {\n return Response.json({ id: params.id });\n}\n```\n\n## Conventions\n\n- TypeScript required\n- React 19 features (use, Server Components)\n- Tailwind CSS for styling\n- Co-locate tests with implementation\n- Use `#veryfront/*` imports for framework modules\n\n## Testing\n\n- Development: `veryfront dev` (http://localhost:3000)\n- API endpoints: `/api/*`\n- Run tests: `deno task test`\n"
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
"ai-rules:copilot.md": {
|
|
602
|
+
"files": {
|
|
603
|
+
"copilot.md": "# Veryfront Project Instructions\n\nThis is a Veryfront project - a zero-config React meta-framework for AI-native applications.\n\n## CLI Commands\n\n- `veryfront dev` - Start development server with hot module replacement\n- `veryfront build` - Build for production deployment\n- `veryfront deploy` - Deploy to Veryfront cloud\n- `veryfront generate page <name>` - Scaffold a new page\n- `veryfront generate api <name>` - Scaffold an API route\n\n## File Structure\n\nThe project uses file-based routing:\n\n- `src/pages/*.tsx` - React pages (automatically become routes)\n- `src/api/*.ts` - API endpoints (accessible at `/api/*`)\n- `src/components/` - Shared React components\n- `agents/` - AI agent definitions\n- `tools/` - MCP tool implementations\n\n## Code Patterns\n\n### Creating a Page\n\n```tsx\n// src/pages/about.tsx → accessible at /about\nexport default function About() {\n return <h1>About</h1>;\n}\n```\n\n### Creating an API Endpoint\n\n```ts\n// src/api/hello.ts → accessible at /api/hello\nexport function GET() {\n return Response.json({ message: \"Hello\" });\n}\n\nexport function POST(request: Request) {\n // Handle POST request\n return Response.json({ success: true });\n}\n```\n\n### Dynamic Routes\n\n```ts\n// src/api/users/[id].ts → accessible at /api/users/:id\nexport function GET(_req: Request, { params }: { params: { id: string } }) {\n return Response.json({ userId: params.id });\n}\n```\n\n## Technology Stack\n\n- Runtime: Deno\n- UI: React 19 with Server Components\n- Styling: Tailwind CSS\n- Language: TypeScript (required)\n\n## Best Practices\n\n- Co-locate test files with implementation (`*.test.ts`)\n- Use `#veryfront/*` import aliases for framework modules\n- Follow React 19 patterns (use hook, Server Components)\n- Use Response.json() for API responses\n"
|
|
604
|
+
}
|
|
605
|
+
},
|
|
606
|
+
"ai-rules:windsurf.md": {
|
|
607
|
+
"files": {
|
|
608
|
+
"windsurf.md": "# Veryfront Project\n\nYou are in a Veryfront project - zero-config React meta-framework for AI-native applications.\n\n## Commands\n\n- `veryfront dev` - Start development server with HMR\n- `veryfront build` - Build for production\n- `veryfront deploy` - Deploy to Veryfront cloud\n- `veryfront generate page <name>` - Generate a new page\n- `veryfront generate api <name>` - Generate an API route\n\n## Project Structure\n\n```\nsrc/\n├── pages/ # File-based routing (pages/*.tsx → routes)\n├── api/ # API routes (api/*.ts → /api/*)\n├── components/ # Shared React components\n├── ai/\n│ ├── agents/ # AI agents\n│ └── tools/ # MCP tools\n└── styles/ # Global styles\n```\n\n## Adding Features\n\n- **New page**: Create `src/pages/about.tsx` → accessible at `/about`\n- **API endpoint**: Create `src/api/users.ts` → accessible at `/api/users`\n- **AI agent**: Create `agents/assistant.ts`\n- **MCP tool**: Create `tools/search.ts`\n\n## Conventions\n\n- TypeScript required\n- React 19 features (use, Server Components)\n- Tailwind CSS for styling\n- Co-locate tests with implementation (`*.test.ts`)\n- Use `#veryfront/*` imports for framework modules\n\n## File Patterns\n\n```tsx\n// Page component (src/pages/about.tsx)\nexport default function About() {\n return <h1>About</h1>;\n}\n\n// API route (src/api/hello.ts)\nexport function GET() {\n return Response.json({ message: \"Hello\" });\n}\n\n// API with params (src/api/users/[id].ts)\nexport function GET(_req: Request, { params }: { params: { id: string } }) {\n return Response.json({ id: params.id });\n}\n```\n\n## Testing\n\n- Run `veryfront dev` and check browser at http://localhost:3000\n- API endpoints available at `/api/*`\n- Use `deno task test` to run tests\n"
|
|
609
|
+
}
|
|
610
|
+
},
|
|
611
|
+
"ai-rules:agents.md": {
|
|
612
|
+
"files": {
|
|
613
|
+
"agents.md": "# Veryfront Agent Instructions\n\nThis is a Veryfront project. Veryfront is a zero-config React meta-framework for AI-native applications.\n\n## Commands\n\n- `npx veryfront dev` - Start development server\n- `npx veryfront build` - Build for production\n- `npx veryfront deploy` - Deploy to cloud\n- `npx veryfront generate page <name>` - Generate a page\n- `npx veryfront generate api <name>` - Generate an API route\n\n## File Conventions\n\n- **Pages**: `src/pages/*.tsx` (file-based routing)\n- **APIs**: `src/api/*.ts` (serverless functions at `/api/*`)\n- **Components**: `src/components/*.tsx`\n- **AI Agents**: `agents/*.ts`\n- **MCP Tools**: `tools/*.ts`\n\n## Examples\n\n### Create a new page\n\n```tsx\n// src/pages/about.tsx\nexport default function About() {\n return <h1>About</h1>;\n}\n```\n\nThis page will be accessible at `/about`.\n\n### Create an API endpoint\n\n```ts\n// src/api/hello.ts\nexport function GET() {\n return Response.json({ message: \"Hello\" });\n}\n\nexport function POST(request: Request) {\n return Response.json({ success: true });\n}\n```\n\nThis API will be accessible at `/api/hello`.\n\n### Create a dynamic API route\n\n```ts\n// src/api/users/[id].ts\nexport function GET(_req: Request, { params }: { params: { id: string } }) {\n return Response.json({ userId: params.id });\n}\n```\n\nThis API will be accessible at `/api/users/:id`.\n\n## Technology Stack\n\n- **Runtime**: Deno\n- **UI Framework**: React 19\n- **Styling**: Tailwind CSS\n- **Language**: TypeScript\n\n## Best Practices\n\n- Co-locate tests with implementation files (`*.test.ts`)\n- Use `#veryfront/*` import aliases\n- Use React 19 features (use hook, Server Components)\n- Return `Response.json()` from API routes\n"
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
"ai-rules:cursor.md": {
|
|
617
|
+
"files": {
|
|
618
|
+
"cursor.md": "# Veryfront Project\n\nYou are in a Veryfront project - zero-config React meta-framework for AI-native applications.\n\n## Commands\n\n- `veryfront dev` - Start development server with HMR\n- `veryfront build` - Build for production\n- `veryfront deploy` - Deploy to Veryfront cloud\n- `veryfront generate page <name>` - Generate a new page\n- `veryfront generate api <name>` - Generate an API route\n\n## Project Structure\n\n```\nsrc/\n├── pages/ # File-based routing (pages/*.tsx → routes)\n├── api/ # API routes (api/*.ts → /api/*)\n├── components/ # Shared React components\n├── ai/\n│ ├── agents/ # AI agents\n│ └── tools/ # MCP tools\n└── styles/ # Global styles\n```\n\n## Adding Features\n\n- **New page**: Create `src/pages/about.tsx` → accessible at `/about`\n- **API endpoint**: Create `src/api/users.ts` → accessible at `/api/users`\n- **AI agent**: Create `agents/assistant.ts`\n- **MCP tool**: Create `tools/search.ts`\n\n## Conventions\n\n- TypeScript required\n- React 19 features (use, Server Components)\n- Tailwind CSS for styling\n- Co-locate tests with implementation (`*.test.ts`)\n- Use `#veryfront/*` imports for framework modules\n\n## File Patterns\n\n```tsx\n// Page component (src/pages/about.tsx)\nexport default function About() {\n return <h1>About</h1>;\n}\n\n// API route (src/api/hello.ts)\nexport function GET() {\n return Response.json({ message: \"Hello\" });\n}\n\n// API with params (src/api/users/[id].ts)\nexport function GET(_req: Request, { params }: { params: { id: string } }) {\n return Response.json({ id: params.id });\n}\n```\n\n## Testing\n\n- Run `veryfront dev` and check browser at http://localhost:3000\n- API endpoints available at `/api/*`\n- Use `deno task test` to run tests\n"
|
|
619
|
+
}
|
|
590
620
|
}
|
|
591
621
|
}
|
|
592
622
|
};
|
package/src/deno.js
CHANGED
|
@@ -12,6 +12,92 @@ export interface ConversationHostedTerminalStateInput {
|
|
|
12
12
|
terminalErrorMessage?: string | null;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
export const CONVERSATION_HOSTED_STREAM_ERROR_TERMINAL_ERROR_CODE = "STREAM_ERROR";
|
|
16
|
+
export const CONVERSATION_HOSTED_ABORTED_TERMINAL_ERROR_CODE = "ABORTED";
|
|
17
|
+
export const CONVERSATION_HOSTED_INCOMPLETE_TOOL_CALLS_TERMINAL_ERROR_CODE =
|
|
18
|
+
"INCOMPLETE_TOOL_CALLS";
|
|
19
|
+
|
|
20
|
+
const DEFAULT_CONVERSATION_HOSTED_ABORTED_TERMINAL_ERROR_MESSAGE = "Chat stream aborted";
|
|
21
|
+
const DEFAULT_CONVERSATION_HOSTED_INCOMPLETE_TOOL_CALLS_TERMINAL_ERROR_MESSAGE =
|
|
22
|
+
"Assistant completed before tool execution completed";
|
|
23
|
+
|
|
24
|
+
export interface ResolveConversationHostedTerminalStateInput {
|
|
25
|
+
isAborted: boolean;
|
|
26
|
+
hasIncompleteToolParts: boolean;
|
|
27
|
+
abortedTerminalErrorMessage?: string;
|
|
28
|
+
incompleteToolCallsTerminalErrorMessage?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type ConversationHostedTerminalStateResolution = Pick<
|
|
32
|
+
ConversationHostedTerminalStateInput,
|
|
33
|
+
"status" | "terminalErrorCode" | "terminalErrorMessage"
|
|
34
|
+
>;
|
|
35
|
+
|
|
36
|
+
export function resolveConversationHostedTerminalState(
|
|
37
|
+
input: ResolveConversationHostedTerminalStateInput,
|
|
38
|
+
): ConversationHostedTerminalStateResolution {
|
|
39
|
+
if (input.isAborted) {
|
|
40
|
+
return {
|
|
41
|
+
status: "cancelled",
|
|
42
|
+
terminalErrorCode: CONVERSATION_HOSTED_ABORTED_TERMINAL_ERROR_CODE,
|
|
43
|
+
terminalErrorMessage: input.abortedTerminalErrorMessage ??
|
|
44
|
+
DEFAULT_CONVERSATION_HOSTED_ABORTED_TERMINAL_ERROR_MESSAGE,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (input.hasIncompleteToolParts) {
|
|
49
|
+
return {
|
|
50
|
+
status: "failed",
|
|
51
|
+
terminalErrorCode: CONVERSATION_HOSTED_INCOMPLETE_TOOL_CALLS_TERMINAL_ERROR_CODE,
|
|
52
|
+
terminalErrorMessage: input.incompleteToolCallsTerminalErrorMessage ??
|
|
53
|
+
DEFAULT_CONVERSATION_HOSTED_INCOMPLETE_TOOL_CALLS_TERMINAL_ERROR_MESSAGE,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { status: "completed" };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function resolveConversationHostedStreamErrorState(
|
|
61
|
+
error: unknown,
|
|
62
|
+
): ConversationHostedTerminalStateResolution {
|
|
63
|
+
return {
|
|
64
|
+
status: "failed",
|
|
65
|
+
terminalErrorCode: CONVERSATION_HOSTED_STREAM_ERROR_TERMINAL_ERROR_CODE,
|
|
66
|
+
terminalErrorMessage: error instanceof Error ? error.message : String(error),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface ConversationHostedTerminalRuntimeAdapter {
|
|
71
|
+
terminal: Pick<
|
|
72
|
+
ConversationHostedTerminalAdapter,
|
|
73
|
+
"toTerminalState" | "finalizeRun" | "cancelRun" | "onTerminalState"
|
|
74
|
+
>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function dispatchConversationHostedTerminalState(
|
|
78
|
+
adapter: ConversationHostedTerminalRuntimeAdapter,
|
|
79
|
+
state: ConversationHostedTerminalStateInput,
|
|
80
|
+
): Promise<HostedLifecycleTerminalState> {
|
|
81
|
+
const terminalState = adapter.terminal.toTerminalState(state);
|
|
82
|
+
if (terminalState.status === "cancelled") {
|
|
83
|
+
await adapter.terminal.cancelRun(terminalState);
|
|
84
|
+
} else {
|
|
85
|
+
await adapter.terminal.finalizeRun(terminalState);
|
|
86
|
+
}
|
|
87
|
+
await adapter.terminal.onTerminalState(terminalState);
|
|
88
|
+
return terminalState;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function dispatchConversationHostedStreamErrorState(
|
|
92
|
+
adapter: ConversationHostedTerminalRuntimeAdapter,
|
|
93
|
+
error: unknown,
|
|
94
|
+
): Promise<HostedLifecycleTerminalState> {
|
|
95
|
+
return dispatchConversationHostedTerminalState(
|
|
96
|
+
adapter,
|
|
97
|
+
resolveConversationHostedStreamErrorState(error),
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
15
101
|
export interface CreateConversationHostedTerminalAdapterOptions {
|
|
16
102
|
authToken: string;
|
|
17
103
|
apiUrl: string;
|
|
@@ -30,6 +30,33 @@ export function isHostedChildTerminalErrorCode(
|
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export interface HostedChildSameTurnRetryBlockSignal {
|
|
34
|
+
terminalErrorCode?: string | null;
|
|
35
|
+
terminalErrorMessage?: string | null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getOptionalStringProperty(value: object, property: string): string | null {
|
|
39
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, property);
|
|
40
|
+
return typeof descriptor?.value === "string" ? descriptor.value : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function shouldBlockHostedChildSameTurnRetry(
|
|
44
|
+
result: unknown,
|
|
45
|
+
): result is HostedChildSameTurnRetryBlockSignal {
|
|
46
|
+
if (typeof result !== "object" || result === null) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const terminalErrorCode = getOptionalStringProperty(result, "terminalErrorCode");
|
|
51
|
+
const terminalErrorMessage = getOptionalStringProperty(result, "terminalErrorMessage");
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
terminalErrorCode === "CANCELLED" ||
|
|
55
|
+
terminalErrorCode === hostedChildTerminalErrorCodes.cancelled ||
|
|
56
|
+
terminalErrorMessage === "Child run cancelled"
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
33
60
|
export type HostedChildTerminalStatus = Extract<
|
|
34
61
|
HostedConversationRunStatus,
|
|
35
62
|
"completed" | "failed" | "cancelled"
|
package/src/src/agent/index.ts
CHANGED
|
@@ -495,10 +495,20 @@ export {
|
|
|
495
495
|
createConversationHostedStreamLifecycleAdapter,
|
|
496
496
|
} from "./conversation-hosted-lifecycle.js";
|
|
497
497
|
export {
|
|
498
|
+
CONVERSATION_HOSTED_ABORTED_TERMINAL_ERROR_CODE,
|
|
499
|
+
CONVERSATION_HOSTED_INCOMPLETE_TOOL_CALLS_TERMINAL_ERROR_CODE,
|
|
500
|
+
CONVERSATION_HOSTED_STREAM_ERROR_TERMINAL_ERROR_CODE,
|
|
498
501
|
type ConversationHostedTerminalAdapter,
|
|
502
|
+
type ConversationHostedTerminalRuntimeAdapter,
|
|
499
503
|
type ConversationHostedTerminalStateInput,
|
|
504
|
+
type ConversationHostedTerminalStateResolution,
|
|
500
505
|
createConversationHostedTerminalAdapter,
|
|
501
506
|
type CreateConversationHostedTerminalAdapterOptions,
|
|
507
|
+
dispatchConversationHostedStreamErrorState,
|
|
508
|
+
dispatchConversationHostedTerminalState,
|
|
509
|
+
resolveConversationHostedStreamErrorState,
|
|
510
|
+
resolveConversationHostedTerminalState,
|
|
511
|
+
type ResolveConversationHostedTerminalStateInput,
|
|
502
512
|
toConversationHostedTerminalState,
|
|
503
513
|
} from "./conversation-hosted-terminal.js";
|
|
504
514
|
export {
|
|
@@ -261,6 +261,22 @@ export const veryfrontConfigSchema = z
|
|
|
261
261
|
})
|
|
262
262
|
.partial()
|
|
263
263
|
.optional(),
|
|
264
|
+
logging: z
|
|
265
|
+
.object({
|
|
266
|
+
file: z
|
|
267
|
+
.object({
|
|
268
|
+
enabled: z.boolean().optional(),
|
|
269
|
+
path: z.string().optional(),
|
|
270
|
+
maxSize: z.union([z.number().int().positive(), z.string()]).optional(),
|
|
271
|
+
maxFiles: z.number().int().positive().optional(),
|
|
272
|
+
level: z.enum(["debug", "info", "warn", "error"]).optional(),
|
|
273
|
+
format: z.enum(["json", "text"]).optional(),
|
|
274
|
+
})
|
|
275
|
+
.partial()
|
|
276
|
+
.optional(),
|
|
277
|
+
})
|
|
278
|
+
.partial()
|
|
279
|
+
.optional(),
|
|
264
280
|
})
|
|
265
281
|
.partial()
|
|
266
282
|
.optional(),
|