primitive-admin 1.2.0-alpha.5 → 1.2.0-alpha.7
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/README.md +1 -1
- package/dist/src/commands/apps-children.d.ts +1 -1
- package/dist/src/commands/apps-children.js +170 -28
- package/dist/src/commands/apps-children.js.map +1 -1
- package/dist/src/commands/auth.js +41 -6
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/config.js +43 -4
- package/dist/src/commands/config.js.map +1 -1
- package/dist/src/commands/databases.js +130 -53
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/init.d.ts +7 -0
- package/dist/src/commands/init.js +9 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/sync.d.ts +118 -6
- package/dist/src/commands/sync.js +594 -55
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/lib/child-apps-local.d.ts +45 -21
- package/dist/src/lib/child-apps-local.js +68 -30
- package/dist/src/lib/child-apps-local.js.map +1 -1
- package/dist/src/lib/credentials-store.d.ts +38 -3
- package/dist/src/lib/credentials-store.js +175 -9
- package/dist/src/lib/credentials-store.js.map +1 -1
- package/dist/src/lib/function-collect.d.ts +1 -1
- package/dist/src/lib/function-collect.js +4 -0
- package/dist/src/lib/function-collect.js.map +1 -1
- package/dist/src/lib/generated-config-surfaces.d.ts +148 -0
- package/dist/src/lib/generated-config-surfaces.js +208 -25
- package/dist/src/lib/generated-config-surfaces.js.map +1 -1
- package/dist/src/lib/generated-sdk-types.d.ts +1 -1
- package/dist/src/lib/generated-sdk-types.js +1 -1
- package/dist/src/lib/generated-sdk-types.js.map +1 -1
- package/dist/src/lib/local-state.d.ts +21 -6
- package/dist/src/lib/local-state.js +78 -34
- package/dist/src/lib/local-state.js.map +1 -1
- package/dist/src/lib/push-failure-report.d.ts +45 -0
- package/dist/src/lib/push-failure-report.js +57 -0
- package/dist/src/lib/push-failure-report.js.map +1 -0
- package/dist/src/lib/sync-selectors.d.ts +5 -1
- package/dist/src/lib/sync-selectors.js +23 -13
- package/dist/src/lib/sync-selectors.js.map +1 -1
- package/dist/src/lib/transient-retry.d.ts +9 -0
- package/dist/src/lib/transient-retry.js +37 -0
- package/dist/src/lib/transient-retry.js.map +1 -1
- package/dist/src/lib/vars-override.d.ts +105 -0
- package/dist/src/lib/vars-override.js +143 -0
- package/dist/src/lib/vars-override.js.map +1 -0
- package/package.json +2 -2
|
@@ -6255,35 +6255,82 @@ export function agentDeclarationFunctionKeys(agent) {
|
|
|
6255
6255
|
return [];
|
|
6256
6256
|
return [...new Set(agentFunctionReferences(parsed).map((ref) => ref.key))];
|
|
6257
6257
|
}
|
|
6258
|
-
|
|
6258
|
+
/**
|
|
6259
|
+
* Every function reference of a declaration (tools, turn context, history), in
|
|
6260
|
+
* declaration order, with the path that makes it. `[]` for a block that is
|
|
6261
|
+
* absent or does not parse. A declaration written as one JSON string is read
|
|
6262
|
+
* as the object it encodes.
|
|
6263
|
+
*/
|
|
6264
|
+
export function agentDeclarationFunctionReferences(agent) {
|
|
6265
|
+
const parsed = parseAgentBlock(agent);
|
|
6266
|
+
return parsed ? agentFunctionReferences(parsed) : [];
|
|
6267
|
+
}
|
|
6268
|
+
/**
|
|
6269
|
+
* Every deficit of a declaration's function references against `functions`:
|
|
6270
|
+
* an absent function (`null`, or missing from the map), and for a tool a
|
|
6271
|
+
* missing `inputSchema` and a missing `outputSchema`, each on its own. `[]` for
|
|
6272
|
+
* a block that is absent or does not parse.
|
|
6273
|
+
*/
|
|
6274
|
+
export function agentFunctionDeficits(agent, functions) {
|
|
6259
6275
|
const out = [];
|
|
6260
|
-
for (const ref of
|
|
6261
|
-
const
|
|
6262
|
-
|
|
6263
|
-
: ref.
|
|
6276
|
+
for (const ref of agentDeclarationFunctionReferences(agent)) {
|
|
6277
|
+
const at = {
|
|
6278
|
+
path: ref.path,
|
|
6279
|
+
...(ref.tool !== undefined ? { tool: ref.tool } : {}),
|
|
6280
|
+
key: ref.key,
|
|
6281
|
+
};
|
|
6264
6282
|
const facts = Object.prototype.hasOwnProperty.call(functions, ref.key)
|
|
6265
6283
|
? functions[ref.key]
|
|
6266
6284
|
: null;
|
|
6267
6285
|
if (!facts) {
|
|
6268
|
-
out.push(
|
|
6269
|
-
"does not have. Push the function first, or include its file in " +
|
|
6270
|
-
"this push"));
|
|
6286
|
+
out.push({ ...at, kind: "absent" });
|
|
6271
6287
|
continue;
|
|
6272
6288
|
}
|
|
6273
6289
|
if (!ref.needsSchemas)
|
|
6274
6290
|
continue;
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6291
|
+
if (!facts.hasInputSchema)
|
|
6292
|
+
out.push({ ...at, kind: "inputSchemaMissing" });
|
|
6293
|
+
if (!facts.hasOutputSchema)
|
|
6294
|
+
out.push({ ...at, kind: "outputSchemaMissing" });
|
|
6295
|
+
}
|
|
6296
|
+
return out;
|
|
6297
|
+
}
|
|
6298
|
+
/**
|
|
6299
|
+
* The refusals for a list of deficits: one `AGENT_TOOL_FUNCTION_MISSING` per
|
|
6300
|
+
* absent reference, and one `AGENT_TOOL_FUNCTION_SCHEMA_MISSING` per tool
|
|
6301
|
+
* reference naming every schema it lacks.
|
|
6302
|
+
*/
|
|
6303
|
+
export function agentFunctionDeficitRefusals(deficits) {
|
|
6304
|
+
const out = [];
|
|
6305
|
+
const byPath = new Map();
|
|
6306
|
+
for (const deficit of deficits) {
|
|
6307
|
+
const list = byPath.get(deficit.path);
|
|
6308
|
+
if (list)
|
|
6309
|
+
list.push(deficit);
|
|
6310
|
+
else
|
|
6311
|
+
byPath.set(deficit.path, [deficit]);
|
|
6312
|
+
}
|
|
6313
|
+
for (const list of byPath.values()) {
|
|
6314
|
+
const { path, tool, key } = list[0];
|
|
6315
|
+
const subject = tool ? `tool "${tool}" (${path})` : path;
|
|
6316
|
+
if (list.some((deficit) => deficit.kind === "absent")) {
|
|
6317
|
+
out.push(agentRefusal("AGENT_TOOL_FUNCTION_MISSING", `${AGENT_BLOCK} ${subject} names function "${key}", which this app ` +
|
|
6318
|
+
"does not have. Push the function first, or include its file in " +
|
|
6319
|
+
"this push"));
|
|
6320
|
+
continue;
|
|
6321
|
+
}
|
|
6322
|
+
const missing = ["inputSchema", "outputSchema"].filter((name) => list.some((deficit) => deficit.kind === `${name}Missing`));
|
|
6279
6323
|
if (missing.length > 0) {
|
|
6280
|
-
out.push(agentRefusal("AGENT_TOOL_FUNCTION_SCHEMA_MISSING", `${AGENT_BLOCK} ${subject} names function "${
|
|
6324
|
+
out.push(agentRefusal("AGENT_TOOL_FUNCTION_SCHEMA_MISSING", `${AGENT_BLOCK} ${subject} names function "${key}", which declares ` +
|
|
6281
6325
|
`no ${missing.join(" or ")}. A tool's schemas are its function's: ` +
|
|
6282
|
-
`declare ${missing.join(" and ")} in functions/${
|
|
6326
|
+
`declare ${missing.join(" and ")} in functions/${key}.toml`));
|
|
6283
6327
|
}
|
|
6284
6328
|
}
|
|
6285
6329
|
return out;
|
|
6286
6330
|
}
|
|
6331
|
+
function agentFunctionRefusals(agent, functions) {
|
|
6332
|
+
return agentFunctionDeficitRefusals(agentFunctionDeficits(agent, functions));
|
|
6333
|
+
}
|
|
6287
6334
|
/**
|
|
6288
6335
|
* The one rule: is this `[prompt.agent]` declaration (with the prompt's kind
|
|
6289
6336
|
* and `outputSchema`) something the platform can run?
|
|
@@ -7068,6 +7115,14 @@ function configList(configNames) {
|
|
|
7068
7115
|
* A declaration with no tools and no events reads no function schema at all.
|
|
7069
7116
|
*/
|
|
7070
7117
|
export function agentSchemaTranslationRefusals(input) {
|
|
7118
|
+
return agentSchemaTranslationDeficits(input).map(agentSchemaDeficitRefusal);
|
|
7119
|
+
}
|
|
7120
|
+
/**
|
|
7121
|
+
* Every deficit `agentSchemaTranslationRefusals` reports, in the same order,
|
|
7122
|
+
* before it is rendered. One per (schema, path, keyword, provider), and one
|
|
7123
|
+
* per server-tool schema that does not parse.
|
|
7124
|
+
*/
|
|
7125
|
+
export function agentSchemaTranslationDeficits(input) {
|
|
7071
7126
|
const declaration = parseAgentDeclarationBlock(input.declaration);
|
|
7072
7127
|
if (!declaration)
|
|
7073
7128
|
return [];
|
|
@@ -7081,11 +7136,9 @@ export function agentSchemaTranslationRefusals(input) {
|
|
|
7081
7136
|
for (const subject of subjects) {
|
|
7082
7137
|
if (subject.unparsable !== undefined) {
|
|
7083
7138
|
out.push({
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
`any provider. Fix ${subject.which} in ` +
|
|
7088
|
-
`functions/${subject.unparsable}.toml`,
|
|
7139
|
+
subject: subject.subject,
|
|
7140
|
+
which: subject.which,
|
|
7141
|
+
unparsable: subject.unparsable,
|
|
7089
7142
|
});
|
|
7090
7143
|
continue;
|
|
7091
7144
|
}
|
|
@@ -7095,18 +7148,148 @@ export function agentSchemaTranslationRefusals(input) {
|
|
|
7095
7148
|
continue;
|
|
7096
7149
|
for (const refusal of result.refusals) {
|
|
7097
7150
|
out.push({
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7151
|
+
subject: subject.subject,
|
|
7152
|
+
which: subject.which,
|
|
7153
|
+
provider,
|
|
7154
|
+
configNames,
|
|
7155
|
+
schemaPath: refusal.path,
|
|
7156
|
+
keyword: refusal.keyword,
|
|
7157
|
+
reason: refusal.reason,
|
|
7104
7158
|
});
|
|
7105
7159
|
}
|
|
7106
7160
|
}
|
|
7107
7161
|
}
|
|
7108
7162
|
return out;
|
|
7109
7163
|
}
|
|
7164
|
+
/** The `AGENT_SCHEMA_NOT_TRANSLATABLE` refusal one deficit renders as. */
|
|
7165
|
+
export function agentSchemaDeficitRefusal(deficit) {
|
|
7166
|
+
if ("unparsable" in deficit) {
|
|
7167
|
+
return {
|
|
7168
|
+
code: "AGENT_SCHEMA_NOT_TRANSLATABLE",
|
|
7169
|
+
message: `${AGENT_BLOCK_LABEL} ${deficit.subject} ${deficit.which} is not a ` +
|
|
7170
|
+
`JSON Schema the platform can read, so it cannot be translated for ` +
|
|
7171
|
+
`any provider. Fix ${deficit.which} in ` +
|
|
7172
|
+
`functions/${deficit.unparsable}.toml`,
|
|
7173
|
+
};
|
|
7174
|
+
}
|
|
7175
|
+
const { provider } = deficit;
|
|
7176
|
+
return {
|
|
7177
|
+
code: "AGENT_SCHEMA_NOT_TRANSLATABLE",
|
|
7178
|
+
message: `${AGENT_BLOCK_LABEL} ${deficit.subject} ${deficit.which} at ` +
|
|
7179
|
+
`${schemaPathLabel(deficit.schemaPath)}: ${deficit.keyword} cannot be ` +
|
|
7180
|
+
`translated for ${provider} without losing meaning — ` +
|
|
7181
|
+
`${deficit.reason}. ${configList(deficit.configNames)} run on ${provider}; ` +
|
|
7182
|
+
`rewrite the schema, or archive every ${provider} config of this prompt`,
|
|
7183
|
+
};
|
|
7184
|
+
}
|
|
7185
|
+
// ── src/config-surface/agent-function-change.ts ──────────────────────────
|
|
7186
|
+
/**
|
|
7187
|
+
* A change to a server function that an agent uses — issue #4441.
|
|
7188
|
+
*
|
|
7189
|
+
* An agent names server functions as its tools, its turn-context hook and its
|
|
7190
|
+
* history hook. The agent's own writes are checked against those functions
|
|
7191
|
+
* (`resolveAgentDeclaration`, `agentSchemaTranslationRefusals`), but a change
|
|
7192
|
+
* to the FUNCTION — archiving it, deleting it, changing its schemas — used to
|
|
7193
|
+
* be accepted and fail at the agent's next turn. This module is the rule for
|
|
7194
|
+
* that change: given one agent's declaration and configs, and the functions it
|
|
7195
|
+
* names before and after the change, which refusals does the change introduce?
|
|
7196
|
+
*
|
|
7197
|
+
* The admin function routes refuse such a change with `FUNCTION_USED_BY_AGENT`,
|
|
7198
|
+
* and `config push`'s preflight runs the same rule through the vendored
|
|
7199
|
+
* artifact, so the two cannot disagree.
|
|
7200
|
+
*
|
|
7201
|
+
* ONLY WHAT THE CHANGE INTRODUCES. Both states are reduced to structured
|
|
7202
|
+
* deficits (`agentFunctionDeficits`, `agentSchemaTranslationDeficits`) and the
|
|
7203
|
+
* ones already present before the change are dropped. An agent that is broken
|
|
7204
|
+
* for another reason does not block an unrelated change, and a partial repair
|
|
7205
|
+
* — restoring one of two missing schemas, removing one of two `$ref`s — is
|
|
7206
|
+
* accepted. Messages are rendered only afterwards, by the sibling rules' own
|
|
7207
|
+
* builders, so they read exactly as an agent write's refusals do.
|
|
7208
|
+
*
|
|
7209
|
+
* Pure and dependency-free, like every module under `src/config-surface/`.
|
|
7210
|
+
*/
|
|
7211
|
+
/** The code a function route answers when an agent cannot take the change. */
|
|
7212
|
+
export const FUNCTION_USED_BY_AGENT = "FUNCTION_USED_BY_AGENT";
|
|
7213
|
+
function functionDeficitIdentity(deficit) {
|
|
7214
|
+
return `${deficit.path}\u0000${deficit.kind}`;
|
|
7215
|
+
}
|
|
7216
|
+
function schemaDeficitIdentity(deficit) {
|
|
7217
|
+
if ("unparsable" in deficit) {
|
|
7218
|
+
return [deficit.subject, deficit.which, "unparsable", deficit.unparsable].join("\u0000");
|
|
7219
|
+
}
|
|
7220
|
+
return [
|
|
7221
|
+
deficit.subject,
|
|
7222
|
+
deficit.which,
|
|
7223
|
+
deficit.provider,
|
|
7224
|
+
deficit.schemaPath,
|
|
7225
|
+
deficit.keyword,
|
|
7226
|
+
].join("\u0000");
|
|
7227
|
+
}
|
|
7228
|
+
/**
|
|
7229
|
+
* Every refusal the change introduces for this agent: a reference whose
|
|
7230
|
+
* function goes away (`AGENT_TOOL_FUNCTION_MISSING`), a tool schema that goes
|
|
7231
|
+
* away (`AGENT_TOOL_FUNCTION_SCHEMA_MISSING`), and a schema a non-archived
|
|
7232
|
+
* config's provider cannot carry where the previous one could
|
|
7233
|
+
* (`AGENT_SCHEMA_NOT_TRANSLATABLE`). `[]` when the agent can take the change,
|
|
7234
|
+
* and for a declaration that does not parse (it names nothing).
|
|
7235
|
+
*/
|
|
7236
|
+
export function agentFunctionChangeRefusals(input) {
|
|
7237
|
+
const { declaration, configs, before, after } = input;
|
|
7238
|
+
if (agentDeclarationFunctionReferences(declaration).length === 0)
|
|
7239
|
+
return [];
|
|
7240
|
+
const functionBefore = new Set(agentFunctionDeficits(declaration, before).map(functionDeficitIdentity));
|
|
7241
|
+
const functionIntroduced = agentFunctionDeficits(declaration, after).filter((deficit) => !functionBefore.has(functionDeficitIdentity(deficit)));
|
|
7242
|
+
const schemaBefore = new Set(agentSchemaTranslationDeficits({ declaration, functions: before, configs }).map(schemaDeficitIdentity));
|
|
7243
|
+
const schemaIntroduced = agentSchemaTranslationDeficits({
|
|
7244
|
+
declaration,
|
|
7245
|
+
functions: after,
|
|
7246
|
+
configs,
|
|
7247
|
+
}).filter((deficit) => !schemaBefore.has(schemaDeficitIdentity(deficit)));
|
|
7248
|
+
return [
|
|
7249
|
+
...agentFunctionDeficitRefusals(functionIntroduced),
|
|
7250
|
+
...schemaIntroduced.map(agentSchemaDeficitRefusal),
|
|
7251
|
+
];
|
|
7252
|
+
}
|
|
7253
|
+
/**
|
|
7254
|
+
* How an agent uses one function: each tool's name (or its path when the tool
|
|
7255
|
+
* has none), and `turnContext.function` / `history.function` for a hook, in
|
|
7256
|
+
* declaration order. `[]` when the declaration does not name the function.
|
|
7257
|
+
*/
|
|
7258
|
+
export function agentFunctionUses(declaration, functionKey) {
|
|
7259
|
+
return agentDeclarationFunctionReferences(declaration)
|
|
7260
|
+
.filter((ref) => ref.key === functionKey)
|
|
7261
|
+
.map((ref) => ref.tool ?? ref.path);
|
|
7262
|
+
}
|
|
7263
|
+
/** `tool "lookup"` for a tool's name, the path itself for a hook. */
|
|
7264
|
+
function useLabel(use) {
|
|
7265
|
+
return use.includes(".") ? use : `tool "${use}"`;
|
|
7266
|
+
}
|
|
7267
|
+
/**
|
|
7268
|
+
* The sentence a function route refuses with: the function, then one sentence
|
|
7269
|
+
* per agent naming its key and each use, then the remedy. A schema change also
|
|
7270
|
+
* carries each agent's refusals, since the remedy depends on which schema broke.
|
|
7271
|
+
*/
|
|
7272
|
+
export function functionUsedByAgentMessage(functionKey, change, agents) {
|
|
7273
|
+
const verb = change === "archive"
|
|
7274
|
+
? "cannot be archived"
|
|
7275
|
+
: change === "delete"
|
|
7276
|
+
? "cannot be deleted"
|
|
7277
|
+
: "cannot take this schema change";
|
|
7278
|
+
const uses = agents.map((agent) => {
|
|
7279
|
+
const labels = agent.tools.map(useLabel).join(", ");
|
|
7280
|
+
const why = change === "schema" && agent.refusals.length > 0
|
|
7281
|
+
? `: ${agent.refusals.map((refusal) => refusal.message).join("; ")}`
|
|
7282
|
+
: "";
|
|
7283
|
+
return `It is used by agent "${agent.promptKey}" as ${labels}${why}.`;
|
|
7284
|
+
});
|
|
7285
|
+
const files = agents.map((agent) => `prompts/${agent.promptKey}.toml`).join(", ");
|
|
7286
|
+
const remedy = change === "schema"
|
|
7287
|
+
? `Change the agent in the same push (${files}) so it no longer needs ` +
|
|
7288
|
+
"what this change removes, or retire the agent, then retry."
|
|
7289
|
+
: `Remove the reference from [prompt.agent] in ${files} and push it, or ` +
|
|
7290
|
+
"retire the agent, then retry.";
|
|
7291
|
+
return `Function "${functionKey}" ${verb} while an agent uses it. ${uses.join(" ")} ${remedy}`;
|
|
7292
|
+
}
|
|
7110
7293
|
// ── src/config-surface/agent-test-case.ts ────────────────────────────────
|
|
7111
7294
|
/**
|
|
7112
7295
|
* What an agent test case may say — issue #4262 (single-round prompt tests
|