unbrowse 9.0.1 → 9.0.3
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/package.json +1 -1
- package/runtime/cli.js +118 -2
- package/runtime/mcp.js +242 -4
- package/vendor/kuri/darwin-arm64/libkuri_ffi.dylib +0 -0
- package/vendor/kuri/darwin-x64/libkuri_ffi.dylib +0 -0
- package/vendor/kuri/linux-arm64/libkuri_ffi.so +0 -0
- package/vendor/kuri/linux-x64/kuri +0 -0
- package/vendor/kuri/linux-x64/libkuri_ffi.so +0 -0
- package/vendor/kuri/manifest.json +7 -7
- package/vendor/kuri/win-x64/kuri.exe +0 -0
package/package.json
CHANGED
package/runtime/cli.js
CHANGED
|
@@ -177653,6 +177653,49 @@ function writeSkillSnapshot(cacheKey2, skill) {
|
|
|
177653
177653
|
return;
|
|
177654
177654
|
}
|
|
177655
177655
|
}
|
|
177656
|
+
function compositeSnapshotDir() {
|
|
177657
|
+
return process.env.UNBROWSE_COMPOSITE_DIR ?? join45(process.env.HOME ?? "/tmp", ".unbrowse", "composites");
|
|
177658
|
+
}
|
|
177659
|
+
function compositeAddress(domain, target, steps, edges) {
|
|
177660
|
+
const canonical2 = [
|
|
177661
|
+
`domain:${domain}`,
|
|
177662
|
+
`target:${target}`,
|
|
177663
|
+
`steps:${steps.map((s) => s.endpoint_id).join(">")}`,
|
|
177664
|
+
`edges:${edges.map((e) => `${e.from}.${e.binding}->${e.to}`).sort().join("|")}`
|
|
177665
|
+
].join("::");
|
|
177666
|
+
return `composite:${createHash35("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
|
|
177667
|
+
}
|
|
177668
|
+
function compositeLookupKey(domain, target) {
|
|
177669
|
+
const canonical2 = `domain:${domain}::target:${target}`;
|
|
177670
|
+
return `lookup:${createHash35("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
|
|
177671
|
+
}
|
|
177672
|
+
function compositeFilePath(lookupKey2) {
|
|
177673
|
+
return join45(compositeSnapshotDir(), `${lookupKey2.replace(/[^a-z0-9]/gi, "_")}.json`);
|
|
177674
|
+
}
|
|
177675
|
+
function writeComposite(c) {
|
|
177676
|
+
if (process.env.UNBROWSE_STATELESS === "1")
|
|
177677
|
+
return;
|
|
177678
|
+
if (process.env.UNBROWSE_LOCAL_CACHES !== "1")
|
|
177679
|
+
return;
|
|
177680
|
+
try {
|
|
177681
|
+
mkdirSync21(compositeSnapshotDir(), { recursive: true });
|
|
177682
|
+
const target = compositeFilePath(compositeLookupKey(c.domain, c.target));
|
|
177683
|
+
writeFileSync18(target, JSON.stringify(c), "utf-8");
|
|
177684
|
+
return target;
|
|
177685
|
+
} catch {
|
|
177686
|
+
return;
|
|
177687
|
+
}
|
|
177688
|
+
}
|
|
177689
|
+
function readComposite(domain, target) {
|
|
177690
|
+
try {
|
|
177691
|
+
const path17 = compositeFilePath(compositeLookupKey(domain, target));
|
|
177692
|
+
if (!existsSync38(path17))
|
|
177693
|
+
return;
|
|
177694
|
+
return JSON.parse(readFileSync26(path17, "utf-8"));
|
|
177695
|
+
} catch {
|
|
177696
|
+
return;
|
|
177697
|
+
}
|
|
177698
|
+
}
|
|
177656
177699
|
function hasSearchBindings(endpoint) {
|
|
177657
177700
|
const haystack = JSON.stringify({
|
|
177658
177701
|
url: endpoint.url_template,
|
|
@@ -178709,6 +178752,27 @@ function extractSearchTermsFromIntent(intent) {
|
|
|
178709
178752
|
}
|
|
178710
178753
|
return terms || null;
|
|
178711
178754
|
}
|
|
178755
|
+
function buildCompositeEdges(target, steps, boundKeys) {
|
|
178756
|
+
return boundKeys.map((binding) => {
|
|
178757
|
+
const from = steps.find((s) => s.yielded.includes(binding));
|
|
178758
|
+
return from ? { from: from.endpoint_id, binding, to: target } : null;
|
|
178759
|
+
}).filter((e) => e !== null);
|
|
178760
|
+
}
|
|
178761
|
+
function planPrereqOrder(livePrereqOrder, persisted, isReplayable) {
|
|
178762
|
+
if (persisted && persisted.steps.length > 0) {
|
|
178763
|
+
const recordedOrder = persisted.steps.map((s) => s.endpoint_id);
|
|
178764
|
+
if (recordedOrder.every((id) => isReplayable(id))) {
|
|
178765
|
+
return {
|
|
178766
|
+
prereqOrder: [
|
|
178767
|
+
...recordedOrder,
|
|
178768
|
+
...livePrereqOrder.filter((p) => !recordedOrder.includes(p))
|
|
178769
|
+
],
|
|
178770
|
+
replayedCompositeId: persisted.composite_id
|
|
178771
|
+
};
|
|
178772
|
+
}
|
|
178773
|
+
}
|
|
178774
|
+
return { prereqOrder: livePrereqOrder };
|
|
178775
|
+
}
|
|
178712
178776
|
async function walkPrerequisiteChain(skill, unboundParams, prerequisiteOrder, baseParams, queryIntent, projection, options, steps) {
|
|
178713
178777
|
const resolved = {};
|
|
178714
178778
|
const executed = new Map;
|
|
@@ -179989,13 +180053,65 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
|
|
|
179989
180053
|
};
|
|
179990
180054
|
const stillUnbound = [...candidate.endpoint.url_template.matchAll(/\{([^}]+)\}/g)].map((m) => m[1]).filter((name) => allBound[name] == null || allBound[name] === "");
|
|
179991
180055
|
let chainBound = {};
|
|
179992
|
-
|
|
180056
|
+
let prereqOrder = dagPlan?.prerequisite_order ?? [];
|
|
180057
|
+
let replayedCompositeId;
|
|
180058
|
+
if (stillUnbound.length > 0) {
|
|
180059
|
+
const replayDomain = skill.domain ?? (() => {
|
|
180060
|
+
try {
|
|
180061
|
+
return new URL(candidate.endpoint.url_template).hostname;
|
|
180062
|
+
} catch {
|
|
180063
|
+
return "";
|
|
180064
|
+
}
|
|
180065
|
+
})();
|
|
180066
|
+
const persisted = readComposite(replayDomain, candidate.endpoint.endpoint_id);
|
|
180067
|
+
const decision = planPrereqOrder(prereqOrder, persisted, (id) => {
|
|
180068
|
+
const ep = skill.endpoints.find((e) => e.endpoint_id === id);
|
|
180069
|
+
return ep != null && canAutoExecuteEndpoint(ep);
|
|
180070
|
+
});
|
|
180071
|
+
prereqOrder = decision.prereqOrder;
|
|
180072
|
+
replayedCompositeId = decision.replayedCompositeId;
|
|
180073
|
+
if (replayedCompositeId) {
|
|
180074
|
+
console.log(`[chain] composite replay → ${candidate.endpoint.endpoint_id} (${replayedCompositeId})`);
|
|
180075
|
+
}
|
|
180076
|
+
}
|
|
179993
180077
|
if (stillUnbound.length > 0 && prereqOrder.length > 0) {
|
|
179994
180078
|
const chainSteps = [];
|
|
179995
180079
|
chainBound = await walkPrerequisiteChain(skill, stillUnbound, prereqOrder, { ...templateDefaults, ...endpointParams, ...syncInferred, ...searchOverrides }, queryIntent, projection, { ...options, intent: queryIntent, contextUrl: context?.url }, chainSteps);
|
|
179996
180080
|
if (chainSteps.length > 0) {
|
|
180081
|
+
const compositeEdges = buildCompositeEdges(candidate.endpoint.endpoint_id, chainSteps, Object.keys(chainBound));
|
|
180082
|
+
const compositeDomain = skill.domain ?? (() => {
|
|
180083
|
+
try {
|
|
180084
|
+
return new URL(candidate.endpoint.url_template).hostname;
|
|
180085
|
+
} catch {
|
|
180086
|
+
return "";
|
|
180087
|
+
}
|
|
180088
|
+
})();
|
|
180089
|
+
const compositeIntentSig = (queryIntent ?? "").trim().toLowerCase();
|
|
180090
|
+
const compositeId = compositeAddress(compositeDomain, candidate.endpoint.endpoint_id, chainSteps, compositeEdges);
|
|
180091
|
+
const composite = {
|
|
180092
|
+
composite_id: compositeId,
|
|
180093
|
+
target: candidate.endpoint.endpoint_id,
|
|
180094
|
+
steps: chainSteps,
|
|
180095
|
+
edges: compositeEdges,
|
|
180096
|
+
mode: replayedCompositeId === compositeId ? "composite_replay" : "composite_walk"
|
|
180097
|
+
};
|
|
179997
180098
|
decisionTrace.prerequisite_chain = chainSteps;
|
|
179998
|
-
|
|
180099
|
+
decisionTrace.composite = composite;
|
|
180100
|
+
if (chainSteps.every((s) => s.ok) && canAutoExecuteEndpoint(candidate.endpoint)) {
|
|
180101
|
+
const persistedPath = writeComposite({
|
|
180102
|
+
composite_id: compositeId,
|
|
180103
|
+
intent_signature: compositeIntentSig,
|
|
180104
|
+
domain: compositeDomain,
|
|
180105
|
+
target: composite.target,
|
|
180106
|
+
steps: chainSteps,
|
|
180107
|
+
edges: compositeEdges,
|
|
180108
|
+
created_at: new Date().toISOString()
|
|
180109
|
+
});
|
|
180110
|
+
if (persistedPath) {
|
|
180111
|
+
decisionTrace.composite_persisted = compositeId;
|
|
180112
|
+
}
|
|
180113
|
+
}
|
|
180114
|
+
console.log(`[chain] composite → ${composite.target} via ` + composite.edges.map((e) => `${e.from}.${e.binding}`).join(" + ") || "(no edges)");
|
|
179999
180115
|
}
|
|
180000
180116
|
}
|
|
180001
180117
|
const chainResolvedKeys = new Set(Object.keys(chainBound));
|
package/runtime/mcp.js
CHANGED
|
@@ -124931,6 +124931,49 @@ function writeSkillSnapshot(cacheKey2, skill) {
|
|
|
124931
124931
|
return;
|
|
124932
124932
|
}
|
|
124933
124933
|
}
|
|
124934
|
+
function compositeSnapshotDir() {
|
|
124935
|
+
return process.env.UNBROWSE_COMPOSITE_DIR ?? join26(process.env.HOME ?? "/tmp", ".unbrowse", "composites");
|
|
124936
|
+
}
|
|
124937
|
+
function compositeAddress(domain, target, steps, edges) {
|
|
124938
|
+
const canonical2 = [
|
|
124939
|
+
`domain:${domain}`,
|
|
124940
|
+
`target:${target}`,
|
|
124941
|
+
`steps:${steps.map((s) => s.endpoint_id).join(">")}`,
|
|
124942
|
+
`edges:${edges.map((e) => `${e.from}.${e.binding}->${e.to}`).sort().join("|")}`
|
|
124943
|
+
].join("::");
|
|
124944
|
+
return `composite:${createHash9("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
|
|
124945
|
+
}
|
|
124946
|
+
function compositeLookupKey(domain, target) {
|
|
124947
|
+
const canonical2 = `domain:${domain}::target:${target}`;
|
|
124948
|
+
return `lookup:${createHash9("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
|
|
124949
|
+
}
|
|
124950
|
+
function compositeFilePath(lookupKey) {
|
|
124951
|
+
return join26(compositeSnapshotDir(), `${lookupKey.replace(/[^a-z0-9]/gi, "_")}.json`);
|
|
124952
|
+
}
|
|
124953
|
+
function writeComposite(c) {
|
|
124954
|
+
if (process.env.UNBROWSE_STATELESS === "1")
|
|
124955
|
+
return;
|
|
124956
|
+
if (process.env.UNBROWSE_LOCAL_CACHES !== "1")
|
|
124957
|
+
return;
|
|
124958
|
+
try {
|
|
124959
|
+
mkdirSync15(compositeSnapshotDir(), { recursive: true });
|
|
124960
|
+
const target = compositeFilePath(compositeLookupKey(c.domain, c.target));
|
|
124961
|
+
writeFileSync13(target, JSON.stringify(c), "utf-8");
|
|
124962
|
+
return target;
|
|
124963
|
+
} catch {
|
|
124964
|
+
return;
|
|
124965
|
+
}
|
|
124966
|
+
}
|
|
124967
|
+
function readComposite(domain, target) {
|
|
124968
|
+
try {
|
|
124969
|
+
const path8 = compositeFilePath(compositeLookupKey(domain, target));
|
|
124970
|
+
if (!existsSync23(path8))
|
|
124971
|
+
return;
|
|
124972
|
+
return JSON.parse(readFileSync18(path8, "utf-8"));
|
|
124973
|
+
} catch {
|
|
124974
|
+
return;
|
|
124975
|
+
}
|
|
124976
|
+
}
|
|
124934
124977
|
function hasSearchBindings(endpoint) {
|
|
124935
124978
|
const haystack = JSON.stringify({
|
|
124936
124979
|
url: endpoint.url_template,
|
|
@@ -125987,6 +126030,27 @@ function extractSearchTermsFromIntent(intent) {
|
|
|
125987
126030
|
}
|
|
125988
126031
|
return terms || null;
|
|
125989
126032
|
}
|
|
126033
|
+
function buildCompositeEdges(target, steps, boundKeys) {
|
|
126034
|
+
return boundKeys.map((binding) => {
|
|
126035
|
+
const from = steps.find((s) => s.yielded.includes(binding));
|
|
126036
|
+
return from ? { from: from.endpoint_id, binding, to: target } : null;
|
|
126037
|
+
}).filter((e) => e !== null);
|
|
126038
|
+
}
|
|
126039
|
+
function planPrereqOrder(livePrereqOrder, persisted, isReplayable) {
|
|
126040
|
+
if (persisted && persisted.steps.length > 0) {
|
|
126041
|
+
const recordedOrder = persisted.steps.map((s) => s.endpoint_id);
|
|
126042
|
+
if (recordedOrder.every((id) => isReplayable(id))) {
|
|
126043
|
+
return {
|
|
126044
|
+
prereqOrder: [
|
|
126045
|
+
...recordedOrder,
|
|
126046
|
+
...livePrereqOrder.filter((p) => !recordedOrder.includes(p))
|
|
126047
|
+
],
|
|
126048
|
+
replayedCompositeId: persisted.composite_id
|
|
126049
|
+
};
|
|
126050
|
+
}
|
|
126051
|
+
}
|
|
126052
|
+
return { prereqOrder: livePrereqOrder };
|
|
126053
|
+
}
|
|
125990
126054
|
async function walkPrerequisiteChain(skill, unboundParams, prerequisiteOrder, baseParams, queryIntent, projection, options, steps) {
|
|
125991
126055
|
const resolved = {};
|
|
125992
126056
|
const executed = new Map;
|
|
@@ -127267,13 +127331,65 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
|
|
|
127267
127331
|
};
|
|
127268
127332
|
const stillUnbound = [...candidate.endpoint.url_template.matchAll(/\{([^}]+)\}/g)].map((m) => m[1]).filter((name) => allBound[name] == null || allBound[name] === "");
|
|
127269
127333
|
let chainBound = {};
|
|
127270
|
-
|
|
127334
|
+
let prereqOrder = dagPlan?.prerequisite_order ?? [];
|
|
127335
|
+
let replayedCompositeId;
|
|
127336
|
+
if (stillUnbound.length > 0) {
|
|
127337
|
+
const replayDomain = skill.domain ?? (() => {
|
|
127338
|
+
try {
|
|
127339
|
+
return new URL(candidate.endpoint.url_template).hostname;
|
|
127340
|
+
} catch {
|
|
127341
|
+
return "";
|
|
127342
|
+
}
|
|
127343
|
+
})();
|
|
127344
|
+
const persisted = readComposite(replayDomain, candidate.endpoint.endpoint_id);
|
|
127345
|
+
const decision = planPrereqOrder(prereqOrder, persisted, (id) => {
|
|
127346
|
+
const ep = skill.endpoints.find((e) => e.endpoint_id === id);
|
|
127347
|
+
return ep != null && canAutoExecuteEndpoint(ep);
|
|
127348
|
+
});
|
|
127349
|
+
prereqOrder = decision.prereqOrder;
|
|
127350
|
+
replayedCompositeId = decision.replayedCompositeId;
|
|
127351
|
+
if (replayedCompositeId) {
|
|
127352
|
+
console.log(`[chain] composite replay → ${candidate.endpoint.endpoint_id} (${replayedCompositeId})`);
|
|
127353
|
+
}
|
|
127354
|
+
}
|
|
127271
127355
|
if (stillUnbound.length > 0 && prereqOrder.length > 0) {
|
|
127272
127356
|
const chainSteps = [];
|
|
127273
127357
|
chainBound = await walkPrerequisiteChain(skill, stillUnbound, prereqOrder, { ...templateDefaults, ...endpointParams, ...syncInferred, ...searchOverrides }, queryIntent, projection, { ...options, intent: queryIntent, contextUrl: context?.url }, chainSteps);
|
|
127274
127358
|
if (chainSteps.length > 0) {
|
|
127359
|
+
const compositeEdges = buildCompositeEdges(candidate.endpoint.endpoint_id, chainSteps, Object.keys(chainBound));
|
|
127360
|
+
const compositeDomain = skill.domain ?? (() => {
|
|
127361
|
+
try {
|
|
127362
|
+
return new URL(candidate.endpoint.url_template).hostname;
|
|
127363
|
+
} catch {
|
|
127364
|
+
return "";
|
|
127365
|
+
}
|
|
127366
|
+
})();
|
|
127367
|
+
const compositeIntentSig = (queryIntent ?? "").trim().toLowerCase();
|
|
127368
|
+
const compositeId = compositeAddress(compositeDomain, candidate.endpoint.endpoint_id, chainSteps, compositeEdges);
|
|
127369
|
+
const composite = {
|
|
127370
|
+
composite_id: compositeId,
|
|
127371
|
+
target: candidate.endpoint.endpoint_id,
|
|
127372
|
+
steps: chainSteps,
|
|
127373
|
+
edges: compositeEdges,
|
|
127374
|
+
mode: replayedCompositeId === compositeId ? "composite_replay" : "composite_walk"
|
|
127375
|
+
};
|
|
127275
127376
|
decisionTrace.prerequisite_chain = chainSteps;
|
|
127276
|
-
|
|
127377
|
+
decisionTrace.composite = composite;
|
|
127378
|
+
if (chainSteps.every((s) => s.ok) && canAutoExecuteEndpoint(candidate.endpoint)) {
|
|
127379
|
+
const persistedPath = writeComposite({
|
|
127380
|
+
composite_id: compositeId,
|
|
127381
|
+
intent_signature: compositeIntentSig,
|
|
127382
|
+
domain: compositeDomain,
|
|
127383
|
+
target: composite.target,
|
|
127384
|
+
steps: chainSteps,
|
|
127385
|
+
edges: compositeEdges,
|
|
127386
|
+
created_at: new Date().toISOString()
|
|
127387
|
+
});
|
|
127388
|
+
if (persistedPath) {
|
|
127389
|
+
decisionTrace.composite_persisted = compositeId;
|
|
127390
|
+
}
|
|
127391
|
+
}
|
|
127392
|
+
console.log(`[chain] composite → ${composite.target} via ` + composite.edges.map((e) => `${e.from}.${e.binding}`).join(" + ") || "(no edges)");
|
|
127277
127393
|
}
|
|
127278
127394
|
}
|
|
127279
127395
|
const chainResolvedKeys = new Set(Object.keys(chainBound));
|
|
@@ -191623,6 +191739,7 @@ var init_flex_pay2 = __esm(() => {
|
|
|
191623
191739
|
var exports_orchestrator = {};
|
|
191624
191740
|
__export(exports_orchestrator, {
|
|
191625
191741
|
writeSkillSnapshot: () => writeSkillSnapshot2,
|
|
191742
|
+
writeComposite: () => writeComposite2,
|
|
191626
191743
|
tryDirectJsonFetch: () => tryDirectJsonFetch2,
|
|
191627
191744
|
summarizeSchema: () => summarizeSchema2,
|
|
191628
191745
|
snapshotPathForCacheKey: () => snapshotPathForCacheKey2,
|
|
@@ -191636,10 +191753,12 @@ __export(exports_orchestrator, {
|
|
|
191636
191753
|
resolveEndpointTemplateBindings: () => resolveEndpointTemplateBindings2,
|
|
191637
191754
|
resolveAndExecute: () => resolveAndExecute2,
|
|
191638
191755
|
readSkillSnapshot: () => readSkillSnapshot2,
|
|
191756
|
+
readComposite: () => readComposite2,
|
|
191639
191757
|
pruneLocalCacheEntriesForSkill: () => pruneLocalCacheEntriesForSkill2,
|
|
191640
191758
|
promoteExplicitExecution: () => promoteExplicitExecution2,
|
|
191641
191759
|
probeLooksLikeFetchableHtmlDocument: () => probeLooksLikeFetchableHtmlDocument2,
|
|
191642
191760
|
probeLooksLikeDirectJsonApi: () => probeLooksLikeDirectJsonApi2,
|
|
191761
|
+
planPrereqOrder: () => planPrereqOrder2,
|
|
191643
191762
|
pickPreferredSkillSnapshot: () => pickPreferredSkillSnapshot2,
|
|
191644
191763
|
persistDomainCache: () => persistDomainCache2,
|
|
191645
191764
|
marketplaceSkillMatchesContext: () => marketplaceSkillMatchesContext2,
|
|
@@ -191656,8 +191775,11 @@ __export(exports_orchestrator, {
|
|
|
191656
191775
|
extractSampleValues: () => extractSampleValues2,
|
|
191657
191776
|
extractLiteralSearchTermsFromIntent: () => extractLiteralSearchTermsFromIntent2,
|
|
191658
191777
|
domainSkillCache: () => domainSkillCache2,
|
|
191778
|
+
compositeLookupKey: () => compositeLookupKey2,
|
|
191779
|
+
compositeAddress: () => compositeAddress2,
|
|
191659
191780
|
chooseBestRouteCacheCandidate: () => chooseBestRouteCacheCandidate2,
|
|
191660
191781
|
buildResolveCacheKey: () => buildResolveCacheKey2,
|
|
191782
|
+
buildCompositeEdges: () => buildCompositeEdges2,
|
|
191661
191783
|
assessLocalExecutionResult: () => assessLocalExecutionResult2
|
|
191662
191784
|
});
|
|
191663
191785
|
import { existsSync as existsSync50, writeFileSync as writeFileSync26, readFileSync as readFileSync39, mkdirSync as mkdirSync30, readdirSync as readdirSync17 } from "node:fs";
|
|
@@ -191834,6 +191956,49 @@ function writeSkillSnapshot2(cacheKey2, skill) {
|
|
|
191834
191956
|
return;
|
|
191835
191957
|
}
|
|
191836
191958
|
}
|
|
191959
|
+
function compositeSnapshotDir2() {
|
|
191960
|
+
return process.env.UNBROWSE_COMPOSITE_DIR ?? join58(process.env.HOME ?? "/tmp", ".unbrowse", "composites");
|
|
191961
|
+
}
|
|
191962
|
+
function compositeAddress2(domain, target, steps, edges) {
|
|
191963
|
+
const canonical2 = [
|
|
191964
|
+
`domain:${domain}`,
|
|
191965
|
+
`target:${target}`,
|
|
191966
|
+
`steps:${steps.map((s) => s.endpoint_id).join(">")}`,
|
|
191967
|
+
`edges:${edges.map((e) => `${e.from}.${e.binding}->${e.to}`).sort().join("|")}`
|
|
191968
|
+
].join("::");
|
|
191969
|
+
return `composite:${createHash40("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
|
|
191970
|
+
}
|
|
191971
|
+
function compositeLookupKey2(domain, target) {
|
|
191972
|
+
const canonical2 = `domain:${domain}::target:${target}`;
|
|
191973
|
+
return `lookup:${createHash40("sha256").update(canonical2).digest("hex").slice(0, 32)}`;
|
|
191974
|
+
}
|
|
191975
|
+
function compositeFilePath2(lookupKey2) {
|
|
191976
|
+
return join58(compositeSnapshotDir2(), `${lookupKey2.replace(/[^a-z0-9]/gi, "_")}.json`);
|
|
191977
|
+
}
|
|
191978
|
+
function writeComposite2(c) {
|
|
191979
|
+
if (process.env.UNBROWSE_STATELESS === "1")
|
|
191980
|
+
return;
|
|
191981
|
+
if (process.env.UNBROWSE_LOCAL_CACHES !== "1")
|
|
191982
|
+
return;
|
|
191983
|
+
try {
|
|
191984
|
+
mkdirSync30(compositeSnapshotDir2(), { recursive: true });
|
|
191985
|
+
const target = compositeFilePath2(compositeLookupKey2(c.domain, c.target));
|
|
191986
|
+
writeFileSync26(target, JSON.stringify(c), "utf-8");
|
|
191987
|
+
return target;
|
|
191988
|
+
} catch {
|
|
191989
|
+
return;
|
|
191990
|
+
}
|
|
191991
|
+
}
|
|
191992
|
+
function readComposite2(domain, target) {
|
|
191993
|
+
try {
|
|
191994
|
+
const path23 = compositeFilePath2(compositeLookupKey2(domain, target));
|
|
191995
|
+
if (!existsSync50(path23))
|
|
191996
|
+
return;
|
|
191997
|
+
return JSON.parse(readFileSync39(path23, "utf-8"));
|
|
191998
|
+
} catch {
|
|
191999
|
+
return;
|
|
192000
|
+
}
|
|
192001
|
+
}
|
|
191837
192002
|
function hasSearchBindings2(endpoint) {
|
|
191838
192003
|
const haystack = JSON.stringify({
|
|
191839
192004
|
url: endpoint.url_template,
|
|
@@ -192895,6 +193060,27 @@ function extractSearchTermsFromIntent2(intent) {
|
|
|
192895
193060
|
}
|
|
192896
193061
|
return terms || null;
|
|
192897
193062
|
}
|
|
193063
|
+
function buildCompositeEdges2(target, steps, boundKeys) {
|
|
193064
|
+
return boundKeys.map((binding) => {
|
|
193065
|
+
const from = steps.find((s) => s.yielded.includes(binding));
|
|
193066
|
+
return from ? { from: from.endpoint_id, binding, to: target } : null;
|
|
193067
|
+
}).filter((e) => e !== null);
|
|
193068
|
+
}
|
|
193069
|
+
function planPrereqOrder2(livePrereqOrder, persisted, isReplayable) {
|
|
193070
|
+
if (persisted && persisted.steps.length > 0) {
|
|
193071
|
+
const recordedOrder = persisted.steps.map((s) => s.endpoint_id);
|
|
193072
|
+
if (recordedOrder.every((id) => isReplayable(id))) {
|
|
193073
|
+
return {
|
|
193074
|
+
prereqOrder: [
|
|
193075
|
+
...recordedOrder,
|
|
193076
|
+
...livePrereqOrder.filter((p) => !recordedOrder.includes(p))
|
|
193077
|
+
],
|
|
193078
|
+
replayedCompositeId: persisted.composite_id
|
|
193079
|
+
};
|
|
193080
|
+
}
|
|
193081
|
+
}
|
|
193082
|
+
return { prereqOrder: livePrereqOrder };
|
|
193083
|
+
}
|
|
192898
193084
|
async function walkPrerequisiteChain2(skill, unboundParams, prerequisiteOrder, baseParams, queryIntent, projection, options, steps) {
|
|
192899
193085
|
const resolved = {};
|
|
192900
193086
|
const executed = new Map;
|
|
@@ -194175,13 +194361,65 @@ async function resolveAndExecute2(intent, params = {}, context, projection, opti
|
|
|
194175
194361
|
};
|
|
194176
194362
|
const stillUnbound = [...candidate.endpoint.url_template.matchAll(/\{([^}]+)\}/g)].map((m) => m[1]).filter((name) => allBound[name] == null || allBound[name] === "");
|
|
194177
194363
|
let chainBound = {};
|
|
194178
|
-
|
|
194364
|
+
let prereqOrder = dagPlan?.prerequisite_order ?? [];
|
|
194365
|
+
let replayedCompositeId;
|
|
194366
|
+
if (stillUnbound.length > 0) {
|
|
194367
|
+
const replayDomain = skill.domain ?? (() => {
|
|
194368
|
+
try {
|
|
194369
|
+
return new URL(candidate.endpoint.url_template).hostname;
|
|
194370
|
+
} catch {
|
|
194371
|
+
return "";
|
|
194372
|
+
}
|
|
194373
|
+
})();
|
|
194374
|
+
const persisted = readComposite2(replayDomain, candidate.endpoint.endpoint_id);
|
|
194375
|
+
const decision = planPrereqOrder2(prereqOrder, persisted, (id) => {
|
|
194376
|
+
const ep = skill.endpoints.find((e) => e.endpoint_id === id);
|
|
194377
|
+
return ep != null && canAutoExecuteEndpoint(ep);
|
|
194378
|
+
});
|
|
194379
|
+
prereqOrder = decision.prereqOrder;
|
|
194380
|
+
replayedCompositeId = decision.replayedCompositeId;
|
|
194381
|
+
if (replayedCompositeId) {
|
|
194382
|
+
console.log(`[chain] composite replay → ${candidate.endpoint.endpoint_id} (${replayedCompositeId})`);
|
|
194383
|
+
}
|
|
194384
|
+
}
|
|
194179
194385
|
if (stillUnbound.length > 0 && prereqOrder.length > 0) {
|
|
194180
194386
|
const chainSteps = [];
|
|
194181
194387
|
chainBound = await walkPrerequisiteChain2(skill, stillUnbound, prereqOrder, { ...templateDefaults, ...endpointParams, ...syncInferred, ...searchOverrides }, queryIntent, projection, { ...options, intent: queryIntent, contextUrl: context?.url }, chainSteps);
|
|
194182
194388
|
if (chainSteps.length > 0) {
|
|
194389
|
+
const compositeEdges = buildCompositeEdges2(candidate.endpoint.endpoint_id, chainSteps, Object.keys(chainBound));
|
|
194390
|
+
const compositeDomain = skill.domain ?? (() => {
|
|
194391
|
+
try {
|
|
194392
|
+
return new URL(candidate.endpoint.url_template).hostname;
|
|
194393
|
+
} catch {
|
|
194394
|
+
return "";
|
|
194395
|
+
}
|
|
194396
|
+
})();
|
|
194397
|
+
const compositeIntentSig = (queryIntent ?? "").trim().toLowerCase();
|
|
194398
|
+
const compositeId = compositeAddress2(compositeDomain, candidate.endpoint.endpoint_id, chainSteps, compositeEdges);
|
|
194399
|
+
const composite = {
|
|
194400
|
+
composite_id: compositeId,
|
|
194401
|
+
target: candidate.endpoint.endpoint_id,
|
|
194402
|
+
steps: chainSteps,
|
|
194403
|
+
edges: compositeEdges,
|
|
194404
|
+
mode: replayedCompositeId === compositeId ? "composite_replay" : "composite_walk"
|
|
194405
|
+
};
|
|
194183
194406
|
decisionTrace.prerequisite_chain = chainSteps;
|
|
194184
|
-
|
|
194407
|
+
decisionTrace.composite = composite;
|
|
194408
|
+
if (chainSteps.every((s) => s.ok) && canAutoExecuteEndpoint(candidate.endpoint)) {
|
|
194409
|
+
const persistedPath = writeComposite2({
|
|
194410
|
+
composite_id: compositeId,
|
|
194411
|
+
intent_signature: compositeIntentSig,
|
|
194412
|
+
domain: compositeDomain,
|
|
194413
|
+
target: composite.target,
|
|
194414
|
+
steps: chainSteps,
|
|
194415
|
+
edges: compositeEdges,
|
|
194416
|
+
created_at: new Date().toISOString()
|
|
194417
|
+
});
|
|
194418
|
+
if (persistedPath) {
|
|
194419
|
+
decisionTrace.composite_persisted = compositeId;
|
|
194420
|
+
}
|
|
194421
|
+
}
|
|
194422
|
+
console.log(`[chain] composite → ${composite.target} via ` + composite.edges.map((e) => `${e.from}.${e.binding}`).join(" + ") || "(no edges)");
|
|
194185
194423
|
}
|
|
194186
194424
|
}
|
|
194187
194425
|
const chainResolvedKeys = new Set(Object.keys(chainBound));
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"repo_url": "https://github.com/justrach/kuri.git",
|
|
3
3
|
"branch": "adding-extensions",
|
|
4
4
|
"source_sha": "8938f89f3d0c032bd19c59db0de4eadca18a1800",
|
|
5
|
-
"built_at": "2026-06-
|
|
5
|
+
"built_at": "2026-06-14T04:09:29.728Z",
|
|
6
6
|
"binaries": {
|
|
7
7
|
"darwin-arm64": {
|
|
8
8
|
"zig_target": "aarch64-macos",
|
|
@@ -21,33 +21,33 @@
|
|
|
21
21
|
},
|
|
22
22
|
"linux-x64": {
|
|
23
23
|
"zig_target": "x86_64-linux",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "287c37dd7c9409214b638ba588e26d160fd5078d7b50c0e8673eec64086692c1"
|
|
25
25
|
},
|
|
26
26
|
"win-x64": {
|
|
27
27
|
"zig_target": "x86_64-windows-gnu",
|
|
28
|
-
"sha256": "
|
|
28
|
+
"sha256": "12374edb4547931d6efe8c187dc91c92984f0305fe7cc32276a9a7eddda17808"
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"ffi": {
|
|
32
32
|
"darwin-arm64": {
|
|
33
33
|
"zig_target": "aarch64-macos",
|
|
34
34
|
"lib": "libkuri_ffi.dylib",
|
|
35
|
-
"sha256": "
|
|
35
|
+
"sha256": "e4d25d11504e9f366ff4fca192dd5bfc7d3475a483157541816ff6b75329b498"
|
|
36
36
|
},
|
|
37
37
|
"darwin-x64": {
|
|
38
38
|
"zig_target": "x86_64-macos",
|
|
39
39
|
"lib": "libkuri_ffi.dylib",
|
|
40
|
-
"sha256": "
|
|
40
|
+
"sha256": "c3858a4d4d9f2a713c19835c3f2de15687aaadb6a8f091455920708eda84d069"
|
|
41
41
|
},
|
|
42
42
|
"linux-arm64": {
|
|
43
43
|
"zig_target": "aarch64-linux",
|
|
44
44
|
"lib": "libkuri_ffi.so",
|
|
45
|
-
"sha256": "
|
|
45
|
+
"sha256": "21418a3144796ddcec50721f6a2a6ee86c9518e4515cfdd45a644ee026bc4433"
|
|
46
46
|
},
|
|
47
47
|
"linux-x64": {
|
|
48
48
|
"zig_target": "x86_64-linux",
|
|
49
49
|
"lib": "libkuri_ffi.so",
|
|
50
|
-
"sha256": "
|
|
50
|
+
"sha256": "58c61c8bcaaa9d49e78077732d5e4493cad9d684853eb6f501da810d5d3550a4"
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
}
|
|
Binary file
|