@granular-software/sdk 0.4.44 → 0.4.46
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/agent-evals.d.mts +7 -3
- package/dist/agent-evals.d.ts +7 -3
- package/dist/agent-evals.js +423 -37
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +423 -37
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/agent-harness.d.mts +1 -0
- package/dist/agent-harness.d.ts +1 -0
- package/dist/agent-harness.js +87 -11
- package/dist/agent-harness.js.map +1 -1
- package/dist/agent-harness.mjs +87 -11
- package/dist/agent-harness.mjs.map +1 -1
- package/dist/cli/index.js +114 -18
- package/dist/{client-BZ8NuQ_e.d.ts → client-ButG6ePW.d.ts} +7 -1
- package/dist/{client-CBQFvuKf.d.mts → client-C1UqPDwe.d.mts} +7 -1
- package/dist/index.d.mts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +201 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +201 -29
- package/dist/index.mjs.map +1 -1
- package/dist/{spend-tAz2a16I.d.mts → spend-D2Vy3N1D.d.mts} +113 -4
- package/dist/{spend-tAz2a16I.d.ts → spend-D2Vy3N1D.d.ts} +113 -4
- package/dist/spend.d.mts +1 -2
- package/dist/spend.d.ts +1 -2
- package/package.json +2 -2
package/dist/agent-harness.d.mts
CHANGED
package/dist/agent-harness.d.ts
CHANGED
package/dist/agent-harness.js
CHANGED
|
@@ -1558,7 +1558,8 @@ function buildGranularAgentSessionBlock(sessionContext) {
|
|
|
1558
1558
|
runtimeId: sessionContext?.sandboxId || null,
|
|
1559
1559
|
environmentId: sessionContext?.environmentId || null,
|
|
1560
1560
|
userName: sessionContext?.userName || null,
|
|
1561
|
-
domainRevision: sessionContext?.domainRevision || null
|
|
1561
|
+
domainRevision: sessionContext?.domainRevision || null,
|
|
1562
|
+
uiContext: sessionContext?.uiContext || null
|
|
1562
1563
|
});
|
|
1563
1564
|
}
|
|
1564
1565
|
function buildGranularAgentHeapBlock(heapSummary) {
|
|
@@ -1805,7 +1806,7 @@ function buildGranularAgentToolBlock(tools, capabilityOverrides) {
|
|
|
1805
1806
|
const rightScope = `${right.className || "global"}:${right.static ? "static" : "instance"}`;
|
|
1806
1807
|
return leftScope.localeCompare(rightScope) || left.name.localeCompare(right.name);
|
|
1807
1808
|
});
|
|
1808
|
-
const
|
|
1809
|
+
const availableActions = normalizedTools.filter((tool) => tool.ready !== false).map((tool) => {
|
|
1809
1810
|
const scope = tool.className ? `${tool.static ? "class" : "record"}:${tool.className}` : "global";
|
|
1810
1811
|
return {
|
|
1811
1812
|
name: tool.name,
|
|
@@ -1816,7 +1817,8 @@ function buildGranularAgentToolBlock(tools, capabilityOverrides) {
|
|
|
1816
1817
|
const capabilities = {
|
|
1817
1818
|
executeCode: resolvedCapabilities.executeCode,
|
|
1818
1819
|
readEntities: resolvedCapabilities.readEntities,
|
|
1819
|
-
|
|
1820
|
+
availableActions,
|
|
1821
|
+
writeActions: availableActions,
|
|
1820
1822
|
workflowHelpers: resolvedCapabilities.workflowHelpers,
|
|
1821
1823
|
savedData: resolvedCapabilities.savedData,
|
|
1822
1824
|
showRecords: resolvedCapabilities.showRecords
|
|
@@ -1830,7 +1832,7 @@ function buildGranularAgentActionIndex(tools) {
|
|
|
1830
1832
|
return leftScope.localeCompare(rightScope) || left.name.localeCompare(right.name);
|
|
1831
1833
|
});
|
|
1832
1834
|
if (normalizedTools.length === 0) {
|
|
1833
|
-
return "No
|
|
1835
|
+
return "No executable actions are available.";
|
|
1834
1836
|
}
|
|
1835
1837
|
const globalTools = normalizedTools.filter((tool) => !tool.className);
|
|
1836
1838
|
const staticTools = normalizedTools.filter(
|
|
@@ -1924,6 +1926,76 @@ function splitDomainDocumentation(domainDocumentation) {
|
|
|
1924
1926
|
}
|
|
1925
1927
|
return { types: normalized, docs: "" };
|
|
1926
1928
|
}
|
|
1929
|
+
var DOMAIN_HELPER_FUNCTION_NAMES = /* @__PURE__ */ new Set([
|
|
1930
|
+
"agent_heap_objects",
|
|
1931
|
+
"agent_message",
|
|
1932
|
+
"agent_text_message"
|
|
1933
|
+
]);
|
|
1934
|
+
function inferGlobalActionToolsFromDomainTypes(domainTypes) {
|
|
1935
|
+
const inferred = [];
|
|
1936
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1937
|
+
const declarationPattern = /(?:export\s+)?declare\s+function\s+([A-Za-z_$][\w$]*)\s*\(/g;
|
|
1938
|
+
let match;
|
|
1939
|
+
while (match = declarationPattern.exec(domainTypes)) {
|
|
1940
|
+
const name = match[1];
|
|
1941
|
+
if (!name || DOMAIN_HELPER_FUNCTION_NAMES.has(name) || seen.has(name)) {
|
|
1942
|
+
continue;
|
|
1943
|
+
}
|
|
1944
|
+
seen.add(name);
|
|
1945
|
+
inferred.push({
|
|
1946
|
+
name,
|
|
1947
|
+
description: "Executable global action declared by the domain runtime."
|
|
1948
|
+
});
|
|
1949
|
+
}
|
|
1950
|
+
const actionLinePattern = /^-\s*([A-Za-z_$][\w$]*)\s+\(global\):\s*(.+)$/gm;
|
|
1951
|
+
while (match = actionLinePattern.exec(domainTypes)) {
|
|
1952
|
+
const name = match[1];
|
|
1953
|
+
if (!name || DOMAIN_HELPER_FUNCTION_NAMES.has(name) || seen.has(name)) {
|
|
1954
|
+
continue;
|
|
1955
|
+
}
|
|
1956
|
+
seen.add(name);
|
|
1957
|
+
inferred.push({
|
|
1958
|
+
name,
|
|
1959
|
+
description: match[2]?.trim() || "Executable global action declared by the domain runtime."
|
|
1960
|
+
});
|
|
1961
|
+
}
|
|
1962
|
+
const scopedActionLinePattern = /^-\s*([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)\s+\((record|class)\):\s*(.+)$/gm;
|
|
1963
|
+
while (match = scopedActionLinePattern.exec(domainTypes)) {
|
|
1964
|
+
const className = match[1]?.toLowerCase();
|
|
1965
|
+
const name = match[2];
|
|
1966
|
+
const scope = match[3];
|
|
1967
|
+
if (!className || !name || DOMAIN_HELPER_FUNCTION_NAMES.has(name)) {
|
|
1968
|
+
continue;
|
|
1969
|
+
}
|
|
1970
|
+
const key = `${className}:${scope}:${name}`;
|
|
1971
|
+
if (seen.has(key)) {
|
|
1972
|
+
continue;
|
|
1973
|
+
}
|
|
1974
|
+
seen.add(key);
|
|
1975
|
+
inferred.push({
|
|
1976
|
+
name,
|
|
1977
|
+
className,
|
|
1978
|
+
static: scope === "class",
|
|
1979
|
+
description: match[4]?.trim() || "Executable action declared by the domain runtime."
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
return inferred;
|
|
1983
|
+
}
|
|
1984
|
+
function resolvePromptTools(tools, domainTypes) {
|
|
1985
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
1986
|
+
for (const tool of tools || []) {
|
|
1987
|
+
if (!tool?.name) continue;
|
|
1988
|
+
const key = `${tool.className || "global"}:${tool.static ? "static" : "instance"}:${tool.name}`;
|
|
1989
|
+
byKey.set(key, tool);
|
|
1990
|
+
}
|
|
1991
|
+
for (const tool of inferGlobalActionToolsFromDomainTypes(domainTypes)) {
|
|
1992
|
+
const key = `global:instance:${tool.name}`;
|
|
1993
|
+
if (!byKey.has(key)) {
|
|
1994
|
+
byKey.set(key, tool);
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
return [...byKey.values()];
|
|
1998
|
+
}
|
|
1927
1999
|
function buildGranularAgentCheckpointBlock(checkpoint) {
|
|
1928
2000
|
if (!checkpoint) {
|
|
1929
2001
|
return renderConstBlock("previousCodeResult", null);
|
|
@@ -1996,12 +2068,13 @@ function buildGranularAgentSystemPrompt(input) {
|
|
|
1996
2068
|
const outputMode = input.outputMode || "agentMessages";
|
|
1997
2069
|
const promptCapabilities = resolvePromptCapabilities(input.capabilities);
|
|
1998
2070
|
const domainSections = splitDomainDocumentation(input.domainDocumentation);
|
|
2071
|
+
const promptTools = resolvePromptTools(input.tools, domainSections.types);
|
|
1999
2072
|
const sessionBlock = buildGranularAgentSessionBlock(input.sessionContext);
|
|
2000
2073
|
const toolBlock = buildGranularAgentToolBlock(
|
|
2001
|
-
|
|
2074
|
+
promptTools,
|
|
2002
2075
|
input.capabilities
|
|
2003
2076
|
);
|
|
2004
|
-
const actionIndex = buildGranularAgentActionIndex(
|
|
2077
|
+
const actionIndex = buildGranularAgentActionIndex(promptTools);
|
|
2005
2078
|
const domainBlock = buildGranularAgentDomainBlock(domainSections.types);
|
|
2006
2079
|
const workflowBlock = buildGranularAgentWorkflowBlock(input.workflowSummary);
|
|
2007
2080
|
const checkpointBlock = buildGranularAgentCheckpointBlock(input.checkpoint);
|
|
@@ -2029,7 +2102,7 @@ function buildGranularAgentSystemPrompt(input) {
|
|
|
2029
2102
|
- When \`agent_text_message(...)\` mentions a grounded record that should remain clickable/referable, wrap only the visible record label in a self-closing inline reference tag: \`<granular-object class="class_name" id="stable_id_or_path" label="Visible label" />\`. Use the actual class name and stable id/path from the runtime record or effect result; do not invent ids, field names, or snake/camel-case aliases that are not present in the type declarations or returned object.
|
|
2030
2103
|
- Treat \`agent_heap_objects(...)\` as the UI display call for user-visible records, not as a general storage helper. Do not wrap records under an \`items\` key.
|
|
2031
2104
|
- When records should remain reusable for follow-ups, first save the runtime record or ordered record array with \`await heap.setVar("stable_selection_name", value)\`, then display that saved selection exactly once with \`await agent_heap_objects({ variableNames: ["stable_selection_name"] })\`.
|
|
2032
|
-
- \`heap.setVar(...)\` only accepts scalar values, runtime records/sandbox instances, or arrays of runtime records/sandbox instances. Do not save plain action/effect result objects. If an action returns
|
|
2105
|
+
- \`heap.setVar(...)\` only accepts scalar values, runtime records/sandbox instances, or arrays of runtime records/sandbox instances from one class. Do not save plain action/effect result objects or arrays of JSON summaries returned by actions. If an action returns ids/paths for records that should remain referable or displayed as records, fetch the matching runtime records first with the generated class \`.get(...)\`/query API, then save/display those fetched records. If the action returned only structured summaries, answer from those summaries with \`agent_text_message(...)\`.
|
|
2033
2106
|
- Do not use \`agent_heap_objects({ entries: [...] })\` or \`agent_heap_objects({ saveAs, entries })\` as a shortcut for ordered pages, queues, search results, or ranked lists; those forms can create duplicate or poorly labelled displays. Save the selection with \`heap.setVar(...)\` and display it via \`variableNames\` instead.
|
|
2034
2107
|
- Use \`entryPaths\` only for a few already-known individual records and \`listNames\` only for a host-created list that you intentionally want to show. Do not display both an entry/list selection and a heap variable for the same records.
|
|
2035
2108
|
- When the user asks to show, list, display, open, or "show them" for records you found, call \`agent_heap_objects(...)\`; do not answer only with a count or text summary.
|
|
@@ -2079,10 +2152,11 @@ ${outputRules}` : `Code:
|
|
|
2079
2152
|
- Use choice only for 2 to 5 short grounded options.
|
|
2080
2153
|
- For record choices, set each option value to a stable scalar such as the record \`_graphPath\` or \`id\`, not a label-only value.
|
|
2081
2154
|
- After \`await loop.ask_user(...)\` returns from a choice prompt, tolerate either the option value, the option object, or a human-readable label by matching against value, id/path, label, and description before failing. If a returned label is a prefix or substring of exactly one option label, treat it as that option.
|
|
2082
|
-
- Use \`loop.confirm(...)\` for yes/no confirmation only when the user explicitly asks for
|
|
2155
|
+
- Use \`loop.confirm(...)\` for yes/no confirmation only when the user explicitly asks for a separate confirmation step, policy requires confirmation outside the action runtime, or material uncertainty remains after grounding.
|
|
2156
|
+
- If action, effect, tool, or permission metadata already marks the invoked action as confirmation-gated, do not call \`loop.confirm(...)\` before invoking it. Ground the target and input, then call the action once; the runtime action policy will surface the confirmation prompt and resume the same invocation after approval.
|
|
2083
2157
|
- Do not add a generic yes/no confirmation after the user has already made a grounded choice, unless one of those confirmation conditions still applies.
|
|
2084
|
-
- Do not add confirmation only because an allowed mutation is visible to other people, customer-facing, or consequential. If the user clearly requested the mutation and the grounded target, action, and condition are unique, perform the mutation unless confirmation is required
|
|
2085
|
-
- A conditional request such as "if this is true, do that" is authorization to perform the requested action after you verify the condition. Once the condition, target, and action are grounded uniquely, call the action directly; do not ask "should I perform/post/send this?" unless the user, policy
|
|
2158
|
+
- Do not add confirmation only because an allowed mutation is visible to other people, customer-facing, or consequential. If the user clearly requested the mutation and the grounded target, action, and condition are unique, perform the mutation unless confirmation is required outside the action runtime or remaining material uncertainty exists.
|
|
2159
|
+
- A conditional request such as "if this is true, do that" is authorization to perform the requested action after you verify the condition. Once the condition, target, and action are grounded uniquely, call the action directly; do not ask "should I perform/post/send this?" unless the user, policy outside the action runtime, or unresolved material uncertainty requires confirmation. The visibility or impact of an allowed action is not by itself unresolved uncertainty.
|
|
2086
2160
|
- If the user explicitly asks you to stop for confirmation, natural-language text such as "please confirm" is not enough: call \`await loop.confirm(...)\` before the mutation, then perform the approved mutation in the same resumed job when it returns true.
|
|
2087
2161
|
- Reuse existing task, decision, and closure ids from [State].
|
|
2088
2162
|
- If a user request matches both a domain record/action and a workflow helper, prefer the domain capability.` : "";
|
|
@@ -2228,7 +2302,8 @@ Query policy:
|
|
|
2228
2302
|
- For operational blocker, risk, status, or "what is happening" questions, inspect the relevant record's scalar fields such as status, priority, blocker, summary, latest update/message, due date, amount, and other domain-specific descriptive fields before answering.
|
|
2229
2303
|
- For read-only readiness, risk, health, or status summaries, call any visible read-only assessment/status action on the grounded primary record before ad-hoc aggregation when such an action semantically matches the request. Use the returned fields in the reply and supplement with counts or record reads only when useful.
|
|
2230
2304
|
- Do not hide required visible read-only assessment/status actions inside broad try/catch blocks. The runtime action surface should show that the assessment action ran.
|
|
2231
|
-
- Treat action/effect results as structured values, not necessarily arrays. Before indexing, iterating, checking \`.length\`, or calling array methods, normalize the result first: use the result itself only when \`Array.isArray(result)\`; otherwise read the exact array field shown in the output schema, or a documented array field such as \`items\`, \`matches\`, \`results\`, \`records\`, \`entries\`, \`candidates\`, \`options\`, or
|
|
2305
|
+
- Treat action/effect results as structured values, not necessarily arrays. Before indexing, iterating, checking \`.length\`, or calling array methods, normalize the result first: use the result itself only when \`Array.isArray(result)\`; otherwise read the exact array field shown in the output schema, or a documented array field such as \`items\`, \`matches\`, \`results\`, \`records\`, \`entries\`, \`candidates\`, \`options\`, \`requests\`, \`vendors\`, \`transactions\`, \`approvals\`, \`receipts\`, or another domain-specific array field. If a structured result has \`count > 0\`, never conclude there are no matches until you inspect every array-valued field on that result object, especially fields named by the output schema. Never convert a non-array object result to \`[]\` before checking its documented fields.
|
|
2306
|
+
- Plain JSON objects returned by actions are not sandbox record instances, even when they contain ids, titles, labels, or status fields. Use them for reasoning and text responses. Do not pass action-returned JSON objects or arrays directly to \`heap.setVar(...)\` or \`agent_heap_objects(...)\`; fetch corresponding runtime records first when the user needs record display or follow-up references.
|
|
2232
2307
|
- When a visible search, lookup, availability, or assessment action returns candidates or matches, treat those returned records as already scoped by the action inputs unless the output schema gives reliable fields for further narrowing. When matching returned candidates to grounded records, use the output schema's actual identifier fields, including \`id\`, \`path\`, or fields ending in \`Id\`; do not assume candidates have \`_graphPath\`. Do not discard all returned candidates by re-filtering on guessed property names.
|
|
2233
2308
|
- For scheduling actions, convert relative wording into concrete ISO timestamps before mutating records.
|
|
2234
2309
|
- When a decision depends on fresh external state and a visible read-only status/lookup action exists on the grounded record, call it before deciding, mutating, or refusing based on stale stored fields.
|
|
@@ -2290,6 +2365,7 @@ ${domainSections.docs}
|
|
|
2290
2365
|
|
|
2291
2366
|
Actions:
|
|
2292
2367
|
${actionIndex}
|
|
2368
|
+
- Global actions are executable functions exported by "./sandbox-tools"; import each global action you call, e.g. \`import { some_action } from "./sandbox-tools"; await some_action(...)\`. This includes frontend actions such as opening, focusing, or navigating the host UI.
|
|
2293
2369
|
- Actions listed under "Record-level" are instance methods. First fetch or find the specific record, then call the action on that instance, e.g. \`const item = await Item.get({ path }); await item.action_name(...)\`.
|
|
2294
2370
|
- Actions listed under "Class-level" are class/static methods. Call them on the imported class, e.g. \`await Item.action_name(...)\`.
|
|
2295
2371
|
- The action index is the visibility contract. If an action is listed for a class, call it directly on fetched/listed instances of that class; do not use \`typeof record.action_name === "function"\` as a discovery gate. If an action is not listed, do not call it.
|