@anuma/sdk 6.39.0 → 6.39.2
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/expo/index.cjs +186 -59
- package/dist/expo/index.d.mts +133 -2
- package/dist/expo/index.d.ts +133 -2
- package/dist/expo/index.mjs +185 -59
- package/dist/index.cjs +50 -34
- package/dist/index.mjs +50 -34
- package/dist/react/index.cjs +186 -59
- package/dist/react/index.d.mts +133 -2
- package/dist/react/index.d.ts +133 -2
- package/dist/react/index.mjs +185 -59
- package/dist/server/index.cjs +50 -34
- package/dist/server/index.d.mts +5 -1
- package/dist/server/index.d.ts +5 -1
- package/dist/server/index.mjs +50 -34
- package/dist/tools/index.cjs +10 -8
- package/dist/tools/index.d.mts +10 -6
- package/dist/tools/index.d.ts +10 -6
- package/dist/tools/index.mjs +10 -8
- package/dist/tools/selection/index.cjs +50 -34
- package/dist/tools/selection/index.d.mts +5 -1
- package/dist/tools/selection/index.d.ts +5 -1
- package/dist/tools/selection/index.mjs +50 -34
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3261,15 +3261,17 @@ Build ONLY when the user gives an explicit instruction to build, create, generat
|
|
|
3261
3261
|
|
|
3262
3262
|
Once the user HAS given an explicit build instruction, you are in App Builder mode: you produce polished, production-quality React apps that feel designed \u2014 not generic.
|
|
3263
3263
|
|
|
3264
|
-
DESIGN: on the initial build, before writing code, briefly state (2-3 sentences) what you want this app to feel like \u2014 name the specific fonts, the palette in hex, and one signature detail. Be concrete: "Fraunces display + Inter body + JetBrains Mono metadata, terracotta #b75432 accent on bone #f3efe6, paper-grain texture via inline SVG noise" is the kind of specificity that anchors the build. Default to nothing: don't pick "safe modern productivity" unless the brief literally asks for utilitarian. On later turns, state a design brief only when the change is visual (a restyle, new theme, or new UI); for a logic, data, or behavior-only change, skip the brief and just make the change.
|
|
3264
|
+
DESIGN: on the initial build, before writing code, briefly state (2-3 sentences) what you want this app to feel like \u2014 name the specific fonts, the palette in hex, and one signature detail. Be concrete: "Fraunces display + Inter body + JetBrains Mono metadata, terracotta #b75432 accent on bone #f3efe6, paper-grain texture via inline SVG noise" is the kind of specificity that anchors the build. Default to nothing: don't pick "safe modern productivity" unless the brief literally asks for utilitarian. On later turns, state a design brief only when the change is visual (a restyle, new theme, or new UI); for a text, logic, data, or behavior-only change, skip the brief and just make the change.
|
|
3265
|
+
|
|
3266
|
+
EDIT SCOPE: Change only the files and lines required by the current user request. A title rename is a text edit, not a design change. Preserve styles, dependencies, and unrelated logic on text edits. Design feedback does not authorize unrelated edits.
|
|
3265
3267
|
|
|
3266
3268
|
WORKFLOW:
|
|
3267
3269
|
1. NEVER output code as text or markdown. ALWAYS use tools.
|
|
3268
3270
|
2. Initial build: state your design brief, then create_file with a "files" array writing ALL files in one call. The preview renders automatically.
|
|
3269
3271
|
3. patch_file requires read_file for that path earlier in the conversation (or create_file in the same conversation, which counts). read_file output is numbered "42: <text>" \u2014 the prefix is display-only; never copy it into "find". Each "find" must match exactly one location \u2014 include 2-3 lines of surrounding context. Pass multiple patches per call to change distinct locations.
|
|
3270
3272
|
4. Prefer patch_file for changes to existing files \u2014 surgical, reviewable, preserves surrounding code. Reserve create_file overwrites for substantial restructuring. Inserts: find the line before, replace with that line + the new line. Deletes: empty replace.
|
|
3271
|
-
5.
|
|
3272
|
-
6. Before declaring done, call verify_app. The host's preview runtime reports whether your app actually mounted and surfaces any errors it captured \u2014 hallucinated imports, syntax the bundler rejected, undefined components, runtime crashes. If \`rendered\` is false or \`errors\` is non-empty, fix every error before the next message. If the response includes a \`note\` that verify_app isn't wired in this host, skip
|
|
3273
|
+
5. On the initial build, when adding new UI, or after user-requested design changes, call critique_design first and then audit_design. Critique checks taste, hierarchy, and distinctiveness. Audit checks tokens, focus states, aria-labels, alt text, and heading order. Patch only issues within the current user request. For text, logic, or data edits, skip both design tools.
|
|
3274
|
+
6. Before declaring done, call verify_app. The host's preview runtime reports whether your app actually mounted and surfaces any errors it captured \u2014 hallucinated imports, syntax the bundler rejected, undefined components, runtime crashes. If \`rendered\` is false or \`errors\` is non-empty, fix every error before the next message. If the response includes a \`note\` that verify_app isn't wired in this host, skip runtime verification. An unavailable runtime verifier does not authorize design changes. Use audit_design and critique_design only for the initial build, adding new UI, or user-requested design changes.
|
|
3273
3275
|
7. Keep responses to a sentence or two. Exception: when responding to critique_design, write a substantive paragraph per rubric question.
|
|
3274
3276
|
|
|
3275
3277
|
STRUCTURE:
|
|
@@ -3432,12 +3434,13 @@ function isCacheExpired(cache, expirationMs = DEFAULT_CACHE_EXPIRATION_MS) {
|
|
|
3432
3434
|
if (!cache) return true;
|
|
3433
3435
|
return Date.now() - cache.timestamp > expirationMs;
|
|
3434
3436
|
}
|
|
3435
|
-
function buildCacheEntry(tools, checksum) {
|
|
3437
|
+
function buildCacheEntry(tools, checksum, etag) {
|
|
3436
3438
|
return {
|
|
3437
3439
|
tools,
|
|
3438
3440
|
timestamp: Date.now(),
|
|
3439
3441
|
version: CACHE_VERSION,
|
|
3440
|
-
...checksum && { checksum }
|
|
3442
|
+
...checksum && { checksum },
|
|
3443
|
+
...etag && { etag }
|
|
3441
3444
|
};
|
|
3442
3445
|
}
|
|
3443
3446
|
function writeLocalStorageCache(entry) {
|
|
@@ -3457,19 +3460,36 @@ var localStorageToolsCache = {
|
|
|
3457
3460
|
set: writeLocalStorageCache,
|
|
3458
3461
|
clear: removeLocalStorageCache
|
|
3459
3462
|
};
|
|
3460
|
-
async function fetchServerToolsFromApi(baseUrl,
|
|
3461
|
-
const
|
|
3463
|
+
async function fetchServerToolsFromApi(baseUrl, authHeaders, etag) {
|
|
3464
|
+
const request = (validator) => fetch(`${baseUrl}/api/v1/tools`, {
|
|
3462
3465
|
method: "GET",
|
|
3463
3466
|
headers: {
|
|
3464
|
-
|
|
3465
|
-
"Content-Type": "application/json"
|
|
3467
|
+
...authHeaders,
|
|
3468
|
+
"Content-Type": "application/json",
|
|
3469
|
+
...validator && { "If-None-Match": validator }
|
|
3466
3470
|
}
|
|
3467
3471
|
});
|
|
3472
|
+
let response;
|
|
3473
|
+
try {
|
|
3474
|
+
response = await request(etag);
|
|
3475
|
+
} catch (error) {
|
|
3476
|
+
if (!etag || !(error instanceof TypeError)) throw error;
|
|
3477
|
+
etag = void 0;
|
|
3478
|
+
response = await request();
|
|
3479
|
+
}
|
|
3480
|
+
if (etag && response.status === 304) {
|
|
3481
|
+
return { notModified: true };
|
|
3482
|
+
}
|
|
3468
3483
|
if (!response.ok) {
|
|
3469
3484
|
throw new Error(`Failed to fetch server tools: ${response.status}`);
|
|
3470
3485
|
}
|
|
3471
3486
|
const data = await response.json();
|
|
3472
|
-
|
|
3487
|
+
const responseEtag = response.headers?.get("ETag") ?? void 0;
|
|
3488
|
+
return {
|
|
3489
|
+
notModified: false,
|
|
3490
|
+
...convertServerToolsResponse(data),
|
|
3491
|
+
...responseEtag && { etag: responseEtag }
|
|
3492
|
+
};
|
|
3473
3493
|
}
|
|
3474
3494
|
async function getServerTools(options) {
|
|
3475
3495
|
const {
|
|
@@ -3501,34 +3521,30 @@ async function getServerTools(options) {
|
|
|
3501
3521
|
try {
|
|
3502
3522
|
const { BASE_URL: BASE_URL2 } = await Promise.resolve().then(() => (init_clientConfig(), clientConfig_exports));
|
|
3503
3523
|
const effectiveBaseUrl = baseUrl ?? BASE_URL2;
|
|
3524
|
+
const validator = cached && !forceRefresh ? cached.etag : void 0;
|
|
3525
|
+
let authHeaders;
|
|
3504
3526
|
if (apiKey) {
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
}
|
|
3511
|
-
});
|
|
3512
|
-
if (!response.ok) {
|
|
3513
|
-
throw new Error(`Failed to fetch server tools: ${response.status}`);
|
|
3527
|
+
authHeaders = { "X-API-Key": apiKey };
|
|
3528
|
+
} else {
|
|
3529
|
+
if (!getToken) {
|
|
3530
|
+
getLogger().warn("[serverTools] No auth method available for fetching tools");
|
|
3531
|
+
return cached?.tools ?? [];
|
|
3514
3532
|
}
|
|
3515
|
-
const
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
getLogger().warn("[serverTools] No auth method available for fetching tools");
|
|
3522
|
-
return cached?.tools ?? [];
|
|
3533
|
+
const token = await getToken();
|
|
3534
|
+
if (!token) {
|
|
3535
|
+
getLogger().warn("[serverTools] No auth token available for fetching tools");
|
|
3536
|
+
return cached?.tools ?? [];
|
|
3537
|
+
}
|
|
3538
|
+
authHeaders = { Authorization: `Bearer ${token}` };
|
|
3523
3539
|
}
|
|
3524
|
-
const
|
|
3525
|
-
if (
|
|
3526
|
-
|
|
3527
|
-
|
|
3540
|
+
const result = await fetchServerToolsFromApi(effectiveBaseUrl, authHeaders, validator);
|
|
3541
|
+
if (result.notModified) {
|
|
3542
|
+
const confirmed = cached;
|
|
3543
|
+
await persistCache({ ...confirmed, timestamp: Date.now() });
|
|
3544
|
+
return confirmed.tools;
|
|
3528
3545
|
}
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
return tools;
|
|
3546
|
+
await persistCache(buildCacheEntry(result.tools, result.checksum, result.etag));
|
|
3547
|
+
return result.tools;
|
|
3532
3548
|
} catch (error) {
|
|
3533
3549
|
getLogger().error("[serverTools] Failed to fetch server tools:", error);
|
|
3534
3550
|
if (cached?.tools) {
|
package/dist/index.mjs
CHANGED
|
@@ -3056,15 +3056,17 @@ Build ONLY when the user gives an explicit instruction to build, create, generat
|
|
|
3056
3056
|
|
|
3057
3057
|
Once the user HAS given an explicit build instruction, you are in App Builder mode: you produce polished, production-quality React apps that feel designed \u2014 not generic.
|
|
3058
3058
|
|
|
3059
|
-
DESIGN: on the initial build, before writing code, briefly state (2-3 sentences) what you want this app to feel like \u2014 name the specific fonts, the palette in hex, and one signature detail. Be concrete: "Fraunces display + Inter body + JetBrains Mono metadata, terracotta #b75432 accent on bone #f3efe6, paper-grain texture via inline SVG noise" is the kind of specificity that anchors the build. Default to nothing: don't pick "safe modern productivity" unless the brief literally asks for utilitarian. On later turns, state a design brief only when the change is visual (a restyle, new theme, or new UI); for a logic, data, or behavior-only change, skip the brief and just make the change.
|
|
3059
|
+
DESIGN: on the initial build, before writing code, briefly state (2-3 sentences) what you want this app to feel like \u2014 name the specific fonts, the palette in hex, and one signature detail. Be concrete: "Fraunces display + Inter body + JetBrains Mono metadata, terracotta #b75432 accent on bone #f3efe6, paper-grain texture via inline SVG noise" is the kind of specificity that anchors the build. Default to nothing: don't pick "safe modern productivity" unless the brief literally asks for utilitarian. On later turns, state a design brief only when the change is visual (a restyle, new theme, or new UI); for a text, logic, data, or behavior-only change, skip the brief and just make the change.
|
|
3060
|
+
|
|
3061
|
+
EDIT SCOPE: Change only the files and lines required by the current user request. A title rename is a text edit, not a design change. Preserve styles, dependencies, and unrelated logic on text edits. Design feedback does not authorize unrelated edits.
|
|
3060
3062
|
|
|
3061
3063
|
WORKFLOW:
|
|
3062
3064
|
1. NEVER output code as text or markdown. ALWAYS use tools.
|
|
3063
3065
|
2. Initial build: state your design brief, then create_file with a "files" array writing ALL files in one call. The preview renders automatically.
|
|
3064
3066
|
3. patch_file requires read_file for that path earlier in the conversation (or create_file in the same conversation, which counts). read_file output is numbered "42: <text>" \u2014 the prefix is display-only; never copy it into "find". Each "find" must match exactly one location \u2014 include 2-3 lines of surrounding context. Pass multiple patches per call to change distinct locations.
|
|
3065
3067
|
4. Prefer patch_file for changes to existing files \u2014 surgical, reviewable, preserves surrounding code. Reserve create_file overwrites for substantial restructuring. Inserts: find the line before, replace with that line + the new line. Deletes: empty replace.
|
|
3066
|
-
5.
|
|
3067
|
-
6. Before declaring done, call verify_app. The host's preview runtime reports whether your app actually mounted and surfaces any errors it captured \u2014 hallucinated imports, syntax the bundler rejected, undefined components, runtime crashes. If \`rendered\` is false or \`errors\` is non-empty, fix every error before the next message. If the response includes a \`note\` that verify_app isn't wired in this host, skip
|
|
3068
|
+
5. On the initial build, when adding new UI, or after user-requested design changes, call critique_design first and then audit_design. Critique checks taste, hierarchy, and distinctiveness. Audit checks tokens, focus states, aria-labels, alt text, and heading order. Patch only issues within the current user request. For text, logic, or data edits, skip both design tools.
|
|
3069
|
+
6. Before declaring done, call verify_app. The host's preview runtime reports whether your app actually mounted and surfaces any errors it captured \u2014 hallucinated imports, syntax the bundler rejected, undefined components, runtime crashes. If \`rendered\` is false or \`errors\` is non-empty, fix every error before the next message. If the response includes a \`note\` that verify_app isn't wired in this host, skip runtime verification. An unavailable runtime verifier does not authorize design changes. Use audit_design and critique_design only for the initial build, adding new UI, or user-requested design changes.
|
|
3068
3070
|
7. Keep responses to a sentence or two. Exception: when responding to critique_design, write a substantive paragraph per rubric question.
|
|
3069
3071
|
|
|
3070
3072
|
STRUCTURE:
|
|
@@ -3227,12 +3229,13 @@ function isCacheExpired(cache, expirationMs = DEFAULT_CACHE_EXPIRATION_MS) {
|
|
|
3227
3229
|
if (!cache) return true;
|
|
3228
3230
|
return Date.now() - cache.timestamp > expirationMs;
|
|
3229
3231
|
}
|
|
3230
|
-
function buildCacheEntry(tools, checksum) {
|
|
3232
|
+
function buildCacheEntry(tools, checksum, etag) {
|
|
3231
3233
|
return {
|
|
3232
3234
|
tools,
|
|
3233
3235
|
timestamp: Date.now(),
|
|
3234
3236
|
version: CACHE_VERSION,
|
|
3235
|
-
...checksum && { checksum }
|
|
3237
|
+
...checksum && { checksum },
|
|
3238
|
+
...etag && { etag }
|
|
3236
3239
|
};
|
|
3237
3240
|
}
|
|
3238
3241
|
function writeLocalStorageCache(entry) {
|
|
@@ -3252,19 +3255,36 @@ var localStorageToolsCache = {
|
|
|
3252
3255
|
set: writeLocalStorageCache,
|
|
3253
3256
|
clear: removeLocalStorageCache
|
|
3254
3257
|
};
|
|
3255
|
-
async function fetchServerToolsFromApi(baseUrl,
|
|
3256
|
-
const
|
|
3258
|
+
async function fetchServerToolsFromApi(baseUrl, authHeaders, etag) {
|
|
3259
|
+
const request = (validator) => fetch(`${baseUrl}/api/v1/tools`, {
|
|
3257
3260
|
method: "GET",
|
|
3258
3261
|
headers: {
|
|
3259
|
-
|
|
3260
|
-
"Content-Type": "application/json"
|
|
3262
|
+
...authHeaders,
|
|
3263
|
+
"Content-Type": "application/json",
|
|
3264
|
+
...validator && { "If-None-Match": validator }
|
|
3261
3265
|
}
|
|
3262
3266
|
});
|
|
3267
|
+
let response;
|
|
3268
|
+
try {
|
|
3269
|
+
response = await request(etag);
|
|
3270
|
+
} catch (error) {
|
|
3271
|
+
if (!etag || !(error instanceof TypeError)) throw error;
|
|
3272
|
+
etag = void 0;
|
|
3273
|
+
response = await request();
|
|
3274
|
+
}
|
|
3275
|
+
if (etag && response.status === 304) {
|
|
3276
|
+
return { notModified: true };
|
|
3277
|
+
}
|
|
3263
3278
|
if (!response.ok) {
|
|
3264
3279
|
throw new Error(`Failed to fetch server tools: ${response.status}`);
|
|
3265
3280
|
}
|
|
3266
3281
|
const data = await response.json();
|
|
3267
|
-
|
|
3282
|
+
const responseEtag = response.headers?.get("ETag") ?? void 0;
|
|
3283
|
+
return {
|
|
3284
|
+
notModified: false,
|
|
3285
|
+
...convertServerToolsResponse(data),
|
|
3286
|
+
...responseEtag && { etag: responseEtag }
|
|
3287
|
+
};
|
|
3268
3288
|
}
|
|
3269
3289
|
async function getServerTools(options) {
|
|
3270
3290
|
const {
|
|
@@ -3296,34 +3316,30 @@ async function getServerTools(options) {
|
|
|
3296
3316
|
try {
|
|
3297
3317
|
const { BASE_URL: BASE_URL2 } = await import("./clientConfig-WITO4T6L.mjs");
|
|
3298
3318
|
const effectiveBaseUrl = baseUrl ?? BASE_URL2;
|
|
3319
|
+
const validator = cached && !forceRefresh ? cached.etag : void 0;
|
|
3320
|
+
let authHeaders;
|
|
3299
3321
|
if (apiKey) {
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
}
|
|
3306
|
-
});
|
|
3307
|
-
if (!response.ok) {
|
|
3308
|
-
throw new Error(`Failed to fetch server tools: ${response.status}`);
|
|
3322
|
+
authHeaders = { "X-API-Key": apiKey };
|
|
3323
|
+
} else {
|
|
3324
|
+
if (!getToken) {
|
|
3325
|
+
getLogger().warn("[serverTools] No auth method available for fetching tools");
|
|
3326
|
+
return cached?.tools ?? [];
|
|
3309
3327
|
}
|
|
3310
|
-
const
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
getLogger().warn("[serverTools] No auth method available for fetching tools");
|
|
3317
|
-
return cached?.tools ?? [];
|
|
3328
|
+
const token = await getToken();
|
|
3329
|
+
if (!token) {
|
|
3330
|
+
getLogger().warn("[serverTools] No auth token available for fetching tools");
|
|
3331
|
+
return cached?.tools ?? [];
|
|
3332
|
+
}
|
|
3333
|
+
authHeaders = { Authorization: `Bearer ${token}` };
|
|
3318
3334
|
}
|
|
3319
|
-
const
|
|
3320
|
-
if (
|
|
3321
|
-
|
|
3322
|
-
|
|
3335
|
+
const result = await fetchServerToolsFromApi(effectiveBaseUrl, authHeaders, validator);
|
|
3336
|
+
if (result.notModified) {
|
|
3337
|
+
const confirmed = cached;
|
|
3338
|
+
await persistCache({ ...confirmed, timestamp: Date.now() });
|
|
3339
|
+
return confirmed.tools;
|
|
3323
3340
|
}
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
return tools;
|
|
3341
|
+
await persistCache(buildCacheEntry(result.tools, result.checksum, result.etag));
|
|
3342
|
+
return result.tools;
|
|
3327
3343
|
} catch (error) {
|
|
3328
3344
|
getLogger().error("[serverTools] Failed to fetch server tools:", error);
|
|
3329
3345
|
if (cached?.tools) {
|
package/dist/react/index.cjs
CHANGED
|
@@ -1511,6 +1511,7 @@ __export(index_exports, {
|
|
|
1511
1511
|
clearKeyPair: () => clearKeyPair,
|
|
1512
1512
|
clearLazyTitleCache: () => clearLazyTitleCache,
|
|
1513
1513
|
clearMemoryTopicsOverrideOp: () => clearMemoryTopicsOverrideOp,
|
|
1514
|
+
clearModelsCache: () => clearModelsCache,
|
|
1514
1515
|
clearNotionToken: () => clearNotionToken,
|
|
1515
1516
|
clearServerToolsCache: () => clearServerToolsCache,
|
|
1516
1517
|
consoleLogger: () => consoleLogger,
|
|
@@ -7869,15 +7870,17 @@ Build ONLY when the user gives an explicit instruction to build, create, generat
|
|
|
7869
7870
|
|
|
7870
7871
|
Once the user HAS given an explicit build instruction, you are in App Builder mode: you produce polished, production-quality React apps that feel designed \u2014 not generic.
|
|
7871
7872
|
|
|
7872
|
-
DESIGN: on the initial build, before writing code, briefly state (2-3 sentences) what you want this app to feel like \u2014 name the specific fonts, the palette in hex, and one signature detail. Be concrete: "Fraunces display + Inter body + JetBrains Mono metadata, terracotta #b75432 accent on bone #f3efe6, paper-grain texture via inline SVG noise" is the kind of specificity that anchors the build. Default to nothing: don't pick "safe modern productivity" unless the brief literally asks for utilitarian. On later turns, state a design brief only when the change is visual (a restyle, new theme, or new UI); for a logic, data, or behavior-only change, skip the brief and just make the change.
|
|
7873
|
+
DESIGN: on the initial build, before writing code, briefly state (2-3 sentences) what you want this app to feel like \u2014 name the specific fonts, the palette in hex, and one signature detail. Be concrete: "Fraunces display + Inter body + JetBrains Mono metadata, terracotta #b75432 accent on bone #f3efe6, paper-grain texture via inline SVG noise" is the kind of specificity that anchors the build. Default to nothing: don't pick "safe modern productivity" unless the brief literally asks for utilitarian. On later turns, state a design brief only when the change is visual (a restyle, new theme, or new UI); for a text, logic, data, or behavior-only change, skip the brief and just make the change.
|
|
7874
|
+
|
|
7875
|
+
EDIT SCOPE: Change only the files and lines required by the current user request. A title rename is a text edit, not a design change. Preserve styles, dependencies, and unrelated logic on text edits. Design feedback does not authorize unrelated edits.
|
|
7873
7876
|
|
|
7874
7877
|
WORKFLOW:
|
|
7875
7878
|
1. NEVER output code as text or markdown. ALWAYS use tools.
|
|
7876
7879
|
2. Initial build: state your design brief, then create_file with a "files" array writing ALL files in one call. The preview renders automatically.
|
|
7877
7880
|
3. patch_file requires read_file for that path earlier in the conversation (or create_file in the same conversation, which counts). read_file output is numbered "42: <text>" \u2014 the prefix is display-only; never copy it into "find". Each "find" must match exactly one location \u2014 include 2-3 lines of surrounding context. Pass multiple patches per call to change distinct locations.
|
|
7878
7881
|
4. Prefer patch_file for changes to existing files \u2014 surgical, reviewable, preserves surrounding code. Reserve create_file overwrites for substantial restructuring. Inserts: find the line before, replace with that line + the new line. Deletes: empty replace.
|
|
7879
|
-
5.
|
|
7880
|
-
6. Before declaring done, call verify_app. The host's preview runtime reports whether your app actually mounted and surfaces any errors it captured \u2014 hallucinated imports, syntax the bundler rejected, undefined components, runtime crashes. If \`rendered\` is false or \`errors\` is non-empty, fix every error before the next message. If the response includes a \`note\` that verify_app isn't wired in this host, skip
|
|
7882
|
+
5. On the initial build, when adding new UI, or after user-requested design changes, call critique_design first and then audit_design. Critique checks taste, hierarchy, and distinctiveness. Audit checks tokens, focus states, aria-labels, alt text, and heading order. Patch only issues within the current user request. For text, logic, or data edits, skip both design tools.
|
|
7883
|
+
6. Before declaring done, call verify_app. The host's preview runtime reports whether your app actually mounted and surfaces any errors it captured \u2014 hallucinated imports, syntax the bundler rejected, undefined components, runtime crashes. If \`rendered\` is false or \`errors\` is non-empty, fix every error before the next message. If the response includes a \`note\` that verify_app isn't wired in this host, skip runtime verification. An unavailable runtime verifier does not authorize design changes. Use audit_design and critique_design only for the initial build, adding new UI, or user-requested design changes.
|
|
7881
7884
|
7. Keep responses to a sentence or two. Exception: when responding to critique_design, write a substantive paragraph per rubric question.
|
|
7882
7885
|
|
|
7883
7886
|
STRUCTURE:
|
|
@@ -8044,12 +8047,13 @@ function isCacheExpired(cache, expirationMs = DEFAULT_CACHE_EXPIRATION_MS) {
|
|
|
8044
8047
|
if (!cache) return true;
|
|
8045
8048
|
return Date.now() - cache.timestamp > expirationMs;
|
|
8046
8049
|
}
|
|
8047
|
-
function buildCacheEntry(tools, checksum) {
|
|
8050
|
+
function buildCacheEntry(tools, checksum, etag) {
|
|
8048
8051
|
return {
|
|
8049
8052
|
tools,
|
|
8050
8053
|
timestamp: Date.now(),
|
|
8051
8054
|
version: CACHE_VERSION,
|
|
8052
|
-
...checksum && { checksum }
|
|
8055
|
+
...checksum && { checksum },
|
|
8056
|
+
...etag && { etag }
|
|
8053
8057
|
};
|
|
8054
8058
|
}
|
|
8055
8059
|
function writeLocalStorageCache(entry) {
|
|
@@ -8084,19 +8088,36 @@ function shouldRefreshTools(responseChecksum, cache = localStorageToolsCache) {
|
|
|
8084
8088
|
const cachedChecksum = getToolsChecksum2(cache);
|
|
8085
8089
|
return cachedChecksum instanceof Promise ? cachedChecksum.then(decide) : decide(cachedChecksum);
|
|
8086
8090
|
}
|
|
8087
|
-
async function fetchServerToolsFromApi(baseUrl,
|
|
8088
|
-
const
|
|
8091
|
+
async function fetchServerToolsFromApi(baseUrl, authHeaders, etag) {
|
|
8092
|
+
const request = (validator) => fetch(`${baseUrl}/api/v1/tools`, {
|
|
8089
8093
|
method: "GET",
|
|
8090
8094
|
headers: {
|
|
8091
|
-
|
|
8092
|
-
"Content-Type": "application/json"
|
|
8095
|
+
...authHeaders,
|
|
8096
|
+
"Content-Type": "application/json",
|
|
8097
|
+
...validator && { "If-None-Match": validator }
|
|
8093
8098
|
}
|
|
8094
8099
|
});
|
|
8100
|
+
let response;
|
|
8101
|
+
try {
|
|
8102
|
+
response = await request(etag);
|
|
8103
|
+
} catch (error) {
|
|
8104
|
+
if (!etag || !(error instanceof TypeError)) throw error;
|
|
8105
|
+
etag = void 0;
|
|
8106
|
+
response = await request();
|
|
8107
|
+
}
|
|
8108
|
+
if (etag && response.status === 304) {
|
|
8109
|
+
return { notModified: true };
|
|
8110
|
+
}
|
|
8095
8111
|
if (!response.ok) {
|
|
8096
8112
|
throw new Error(`Failed to fetch server tools: ${response.status}`);
|
|
8097
8113
|
}
|
|
8098
8114
|
const data = await response.json();
|
|
8099
|
-
|
|
8115
|
+
const responseEtag = response.headers?.get("ETag") ?? void 0;
|
|
8116
|
+
return {
|
|
8117
|
+
notModified: false,
|
|
8118
|
+
...convertServerToolsResponse(data),
|
|
8119
|
+
...responseEtag && { etag: responseEtag }
|
|
8120
|
+
};
|
|
8100
8121
|
}
|
|
8101
8122
|
async function getServerTools(options) {
|
|
8102
8123
|
const {
|
|
@@ -8128,34 +8149,30 @@ async function getServerTools(options) {
|
|
|
8128
8149
|
try {
|
|
8129
8150
|
const { BASE_URL: BASE_URL2 } = await Promise.resolve().then(() => (init_clientConfig(), clientConfig_exports));
|
|
8130
8151
|
const effectiveBaseUrl = baseUrl ?? BASE_URL2;
|
|
8152
|
+
const validator = cached && !forceRefresh ? cached.etag : void 0;
|
|
8153
|
+
let authHeaders;
|
|
8131
8154
|
if (apiKey) {
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
}
|
|
8138
|
-
});
|
|
8139
|
-
if (!response.ok) {
|
|
8140
|
-
throw new Error(`Failed to fetch server tools: ${response.status}`);
|
|
8155
|
+
authHeaders = { "X-API-Key": apiKey };
|
|
8156
|
+
} else {
|
|
8157
|
+
if (!getToken) {
|
|
8158
|
+
getLogger().warn("[serverTools] No auth method available for fetching tools");
|
|
8159
|
+
return cached?.tools ?? [];
|
|
8141
8160
|
}
|
|
8142
|
-
const
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
getLogger().warn("[serverTools] No auth method available for fetching tools");
|
|
8149
|
-
return cached?.tools ?? [];
|
|
8161
|
+
const token = await getToken();
|
|
8162
|
+
if (!token) {
|
|
8163
|
+
getLogger().warn("[serverTools] No auth token available for fetching tools");
|
|
8164
|
+
return cached?.tools ?? [];
|
|
8165
|
+
}
|
|
8166
|
+
authHeaders = { Authorization: `Bearer ${token}` };
|
|
8150
8167
|
}
|
|
8151
|
-
const
|
|
8152
|
-
if (
|
|
8153
|
-
|
|
8154
|
-
|
|
8168
|
+
const result = await fetchServerToolsFromApi(effectiveBaseUrl, authHeaders, validator);
|
|
8169
|
+
if (result.notModified) {
|
|
8170
|
+
const confirmed = cached;
|
|
8171
|
+
await persistCache({ ...confirmed, timestamp: Date.now() });
|
|
8172
|
+
return confirmed.tools;
|
|
8155
8173
|
}
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
return tools;
|
|
8174
|
+
await persistCache(buildCacheEntry(result.tools, result.checksum, result.etag));
|
|
8175
|
+
return result.tools;
|
|
8159
8176
|
} catch (error) {
|
|
8160
8177
|
getLogger().error("[serverTools] Failed to fetch server tools:", error);
|
|
8161
8178
|
if (cached?.tools) {
|
|
@@ -32328,6 +32345,7 @@ function useChat(options) {
|
|
|
32328
32345
|
apiType: defaultApiType = "auto",
|
|
32329
32346
|
smoothing,
|
|
32330
32347
|
preProcessors,
|
|
32348
|
+
hooks,
|
|
32331
32349
|
piiRedaction,
|
|
32332
32350
|
onPiiRedacted
|
|
32333
32351
|
} = options || {};
|
|
@@ -32499,6 +32517,7 @@ function useChat(options) {
|
|
|
32499
32517
|
onToolCallArgumentsDelta,
|
|
32500
32518
|
onStepFinish,
|
|
32501
32519
|
preProcessors,
|
|
32520
|
+
hooks,
|
|
32502
32521
|
piiRedaction: requestPiiRedaction ?? resolvedPiiRedaction,
|
|
32503
32522
|
onPiiRedacted
|
|
32504
32523
|
});
|
|
@@ -32536,6 +32555,7 @@ function useChat(options) {
|
|
|
32536
32555
|
defaultApiType,
|
|
32537
32556
|
smoothing,
|
|
32538
32557
|
preProcessors,
|
|
32558
|
+
hooks,
|
|
32539
32559
|
resolvedPiiRedaction,
|
|
32540
32560
|
onPiiRedacted
|
|
32541
32561
|
]
|
|
@@ -33750,6 +33770,7 @@ function useChatStorage(options) {
|
|
|
33750
33770
|
minContentLength = DEFAULT_MIN_CONTENT_LENGTH,
|
|
33751
33771
|
mcpR2Domain = MCP_R2_DOMAIN,
|
|
33752
33772
|
preProcessors,
|
|
33773
|
+
hooks,
|
|
33753
33774
|
smoothing,
|
|
33754
33775
|
piiRedaction,
|
|
33755
33776
|
onPiiRedacted,
|
|
@@ -34324,6 +34345,7 @@ function useChatStorage(options) {
|
|
|
34324
34345
|
onStreamMeta,
|
|
34325
34346
|
apiType,
|
|
34326
34347
|
preProcessors,
|
|
34348
|
+
hooks,
|
|
34327
34349
|
smoothing,
|
|
34328
34350
|
piiRedaction: resolvedPiiRedaction,
|
|
34329
34351
|
onPiiRedacted
|
|
@@ -36727,6 +36749,128 @@ function useICloudBackup(options) {
|
|
|
36727
36749
|
// src/react/useModels.ts
|
|
36728
36750
|
var import_react17 = require("react");
|
|
36729
36751
|
init_clientConfig();
|
|
36752
|
+
var MODELS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
36753
|
+
var modelsCache = /* @__PURE__ */ new Map();
|
|
36754
|
+
var modelsInFlight = /* @__PURE__ */ new Map();
|
|
36755
|
+
var cacheGeneration = 0;
|
|
36756
|
+
function clearModelsCache() {
|
|
36757
|
+
cacheGeneration++;
|
|
36758
|
+
modelsCache.clear();
|
|
36759
|
+
modelsInFlight.clear();
|
|
36760
|
+
}
|
|
36761
|
+
function pruneStaleTokenEntries(newKey) {
|
|
36762
|
+
const [newBaseUrl, newProvider] = JSON.parse(newKey);
|
|
36763
|
+
for (const existingKey of modelsCache.keys()) {
|
|
36764
|
+
if (existingKey === newKey) continue;
|
|
36765
|
+
const [existingBaseUrl, existingProvider] = JSON.parse(existingKey);
|
|
36766
|
+
if (existingBaseUrl === newBaseUrl && existingProvider === newProvider) {
|
|
36767
|
+
modelsCache.delete(existingKey);
|
|
36768
|
+
}
|
|
36769
|
+
}
|
|
36770
|
+
}
|
|
36771
|
+
function fingerprintToken(token) {
|
|
36772
|
+
if (!token) return "anon";
|
|
36773
|
+
let h1 = 3735928559;
|
|
36774
|
+
let h2 = 1103547991;
|
|
36775
|
+
for (let i = 0; i < token.length; i++) {
|
|
36776
|
+
const ch = token.charCodeAt(i);
|
|
36777
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
36778
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
36779
|
+
}
|
|
36780
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
36781
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
36782
|
+
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
|
|
36783
|
+
}
|
|
36784
|
+
function modelsCacheKey(baseUrl, provider, token) {
|
|
36785
|
+
return JSON.stringify([baseUrl, provider ?? null, fingerprintToken(token)]);
|
|
36786
|
+
}
|
|
36787
|
+
async function fetchAllModelPages(baseUrl, provider, headers, previous, signal) {
|
|
36788
|
+
const pages = /* @__PURE__ */ new Map();
|
|
36789
|
+
const models = [];
|
|
36790
|
+
let pageToken;
|
|
36791
|
+
do {
|
|
36792
|
+
const pageKey = pageToken ?? "";
|
|
36793
|
+
const stored2 = previous?.pages.get(pageKey);
|
|
36794
|
+
const request = (etag) => getApiV1Models({
|
|
36795
|
+
baseUrl,
|
|
36796
|
+
headers: etag ? { ...headers, "If-None-Match": etag } : headers,
|
|
36797
|
+
query: { provider, page_token: pageToken },
|
|
36798
|
+
signal
|
|
36799
|
+
});
|
|
36800
|
+
let response = await request(stored2?.etag);
|
|
36801
|
+
if (stored2?.etag && !response.response && response.error) {
|
|
36802
|
+
response = await request();
|
|
36803
|
+
}
|
|
36804
|
+
let page;
|
|
36805
|
+
if (response.response?.status === 304) {
|
|
36806
|
+
if (!stored2) throw new Error("Failed to fetch models");
|
|
36807
|
+
page = stored2;
|
|
36808
|
+
} else {
|
|
36809
|
+
if (response.error) {
|
|
36810
|
+
const errorMsg = response.error.error ?? "Failed to fetch models";
|
|
36811
|
+
throw new Error(errorMsg);
|
|
36812
|
+
}
|
|
36813
|
+
page = {
|
|
36814
|
+
body: response.data ?? {},
|
|
36815
|
+
etag: response.response?.headers?.get("ETag") ?? void 0
|
|
36816
|
+
};
|
|
36817
|
+
}
|
|
36818
|
+
pages.set(pageKey, page);
|
|
36819
|
+
models.push(...page.body.data || []);
|
|
36820
|
+
pageToken = page.body.next_page_token;
|
|
36821
|
+
} while (pageToken);
|
|
36822
|
+
return { pages, models, fetchedAt: Date.now() };
|
|
36823
|
+
}
|
|
36824
|
+
function loadModels(key, baseUrl, provider, headers, force, signal) {
|
|
36825
|
+
const cached = modelsCache.get(key);
|
|
36826
|
+
if (cached && !force && Date.now() - cached.fetchedAt < MODELS_CACHE_TTL_MS) {
|
|
36827
|
+
return Promise.resolve([...cached.models]);
|
|
36828
|
+
}
|
|
36829
|
+
const shared = (force ? void 0 : modelsInFlight.get(key)) ?? startSharedRequest(key, baseUrl, provider, headers, cached);
|
|
36830
|
+
return waitForSharedRequest(key, shared, signal).then((models) => [...models]);
|
|
36831
|
+
}
|
|
36832
|
+
function startSharedRequest(key, baseUrl, provider, headers, previous) {
|
|
36833
|
+
const controller = new AbortController();
|
|
36834
|
+
const generation = cacheGeneration;
|
|
36835
|
+
const shared = {
|
|
36836
|
+
controller,
|
|
36837
|
+
waiters: 0,
|
|
36838
|
+
promise: Promise.resolve([])
|
|
36839
|
+
};
|
|
36840
|
+
shared.promise = fetchAllModelPages(baseUrl, provider, headers, previous, controller.signal).then((entry) => {
|
|
36841
|
+
if (modelsInFlight.get(key) === shared && generation === cacheGeneration) {
|
|
36842
|
+
pruneStaleTokenEntries(key);
|
|
36843
|
+
modelsCache.set(key, entry);
|
|
36844
|
+
}
|
|
36845
|
+
return entry.models;
|
|
36846
|
+
}).finally(() => {
|
|
36847
|
+
if (modelsInFlight.get(key) === shared) modelsInFlight.delete(key);
|
|
36848
|
+
});
|
|
36849
|
+
modelsInFlight.set(key, shared);
|
|
36850
|
+
return shared;
|
|
36851
|
+
}
|
|
36852
|
+
function waitForSharedRequest(key, shared, signal) {
|
|
36853
|
+
shared.waiters++;
|
|
36854
|
+
let left = false;
|
|
36855
|
+
const leave = () => {
|
|
36856
|
+
if (left) return;
|
|
36857
|
+
left = true;
|
|
36858
|
+
shared.waiters--;
|
|
36859
|
+
if (shared.waiters === 0) {
|
|
36860
|
+
shared.controller.abort();
|
|
36861
|
+
if (modelsInFlight.get(key) === shared) modelsInFlight.delete(key);
|
|
36862
|
+
}
|
|
36863
|
+
};
|
|
36864
|
+
if (signal.aborted) {
|
|
36865
|
+
leave();
|
|
36866
|
+
} else {
|
|
36867
|
+
signal.addEventListener("abort", leave, { once: true });
|
|
36868
|
+
}
|
|
36869
|
+
return shared.promise.finally(() => {
|
|
36870
|
+
left = true;
|
|
36871
|
+
signal.removeEventListener("abort", leave);
|
|
36872
|
+
});
|
|
36873
|
+
}
|
|
36730
36874
|
function useModels(options = {}) {
|
|
36731
36875
|
const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
|
|
36732
36876
|
const [models, setModels] = (0, import_react17.useState)([]);
|
|
@@ -36749,7 +36893,7 @@ function useModels(options = {}) {
|
|
|
36749
36893
|
}
|
|
36750
36894
|
};
|
|
36751
36895
|
}, []);
|
|
36752
|
-
const fetchModels = (0, import_react17.useCallback)(async () => {
|
|
36896
|
+
const fetchModels = (0, import_react17.useCallback)(async (force = false) => {
|
|
36753
36897
|
if (abortControllerRef.current) {
|
|
36754
36898
|
abortControllerRef.current.abort();
|
|
36755
36899
|
}
|
|
@@ -36768,35 +36912,17 @@ function useModels(options = {}) {
|
|
|
36768
36912
|
if (token) {
|
|
36769
36913
|
headers["Authorization"] = `Bearer ${token}`;
|
|
36770
36914
|
}
|
|
36771
|
-
|
|
36772
|
-
|
|
36773
|
-
|
|
36774
|
-
|
|
36775
|
-
const response = await getApiV1Models({
|
|
36776
|
-
baseUrl: baseUrlRef.current,
|
|
36777
|
-
headers,
|
|
36778
|
-
query: {
|
|
36779
|
-
provider: providerRef.current,
|
|
36780
|
-
page_token: nextPageToken
|
|
36781
|
-
},
|
|
36782
|
-
signal
|
|
36783
|
-
});
|
|
36784
|
-
if (response.error) {
|
|
36785
|
-
const errorMsg = response.error.error ?? "Failed to fetch models";
|
|
36786
|
-
throw new Error(errorMsg);
|
|
36787
|
-
}
|
|
36788
|
-
if (response.data) {
|
|
36789
|
-
const newModels = response.data.data || [];
|
|
36790
|
-
allModels = [...allModels, ...newModels];
|
|
36791
|
-
nextPageToken = response.data.next_page_token;
|
|
36792
|
-
}
|
|
36793
|
-
} while (nextPageToken);
|
|
36915
|
+
const baseUrl2 = baseUrlRef.current;
|
|
36916
|
+
const provider2 = providerRef.current;
|
|
36917
|
+
const key = modelsCacheKey(baseUrl2, provider2, token);
|
|
36918
|
+
const allModels = await loadModels(key, baseUrl2, provider2, headers, force, signal);
|
|
36794
36919
|
if (signal.aborted) return;
|
|
36795
36920
|
setModels(allModels);
|
|
36796
36921
|
} catch (err) {
|
|
36797
36922
|
if (err instanceof Error && err.name === "AbortError") {
|
|
36798
36923
|
return;
|
|
36799
36924
|
}
|
|
36925
|
+
if (signal.aborted) return;
|
|
36800
36926
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
36801
36927
|
} finally {
|
|
36802
36928
|
if (!signal.aborted) {
|
|
@@ -36809,7 +36935,7 @@ function useModels(options = {}) {
|
|
|
36809
36935
|
}, []);
|
|
36810
36936
|
const refetch = (0, import_react17.useCallback)(async () => {
|
|
36811
36937
|
setModels([]);
|
|
36812
|
-
await fetchModels();
|
|
36938
|
+
await fetchModels(true);
|
|
36813
36939
|
}, [fetchModels]);
|
|
36814
36940
|
const hasFetchedRef = (0, import_react17.useRef)(false);
|
|
36815
36941
|
(0, import_react17.useEffect)(() => {
|
|
@@ -38861,6 +38987,7 @@ function useWalletBinding(options = {}) {
|
|
|
38861
38987
|
clearKeyPair,
|
|
38862
38988
|
clearLazyTitleCache,
|
|
38863
38989
|
clearMemoryTopicsOverrideOp,
|
|
38990
|
+
clearModelsCache,
|
|
38864
38991
|
clearNotionToken,
|
|
38865
38992
|
clearServerToolsCache,
|
|
38866
38993
|
consoleLogger,
|