@lunnoa/client 1.0.0 → 1.1.0
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 +7 -1
- package/dist/cli.js +97 -3
- package/dist/index.cjs +45 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1092 -932
- package/dist/index.d.ts +1092 -932
- package/dist/index.js +44 -2
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +28 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +741 -630
- package/dist/react.d.ts +741 -630
- package/dist/react.js +28 -0
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -266,7 +266,13 @@ Re-run codegen whenever entity types, workflows, or agents change on the deploym
|
|
|
266
266
|
|
|
267
267
|
## Define, run, and CLI deploy
|
|
268
268
|
|
|
269
|
-
Author local definitions with `defineWorkflow` / `defineAgent`, run linear chains with `lunnoa.runs.start`, and upsert
|
|
269
|
+
Author local definitions with `defineWorkflow` / `defineAgent` / `defineEntityType`, run linear chains with `lunnoa.runs.start`, and upsert with the CLI (prefer CLI over calling upsert from app code). Entity types are workspace-scoped (no `--project-id`); instance writes reject unknown attribute keys unless `allowUnknownAttributes` is true — use the reserved `extensions` object for flexible bags:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
npx @lunnoa/client entity-types deploy ./human.ts --url https://lunnoa.example --api-key lna_...
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Workflows and agents:
|
|
270
276
|
|
|
271
277
|
```bash
|
|
272
278
|
npx @lunnoa/client workflows deploy ./workflows/sync-orders.ts \
|
package/dist/cli.js
CHANGED
|
@@ -537,7 +537,8 @@ var DEFINE_KINDS = {
|
|
|
537
537
|
aiConnection: "aiConnection",
|
|
538
538
|
action: "action",
|
|
539
539
|
workflow: "workflow",
|
|
540
|
-
agent: "agent"
|
|
540
|
+
agent: "agent",
|
|
541
|
+
entityType: "entityType"
|
|
541
542
|
};
|
|
542
543
|
function resolveActionAppId(action) {
|
|
543
544
|
if (action.appId?.trim()) {
|
|
@@ -1016,6 +1017,21 @@ var EntitiesResource = class {
|
|
|
1016
1017
|
};
|
|
1017
1018
|
|
|
1018
1019
|
// src/resources/entity-types.ts
|
|
1020
|
+
function entityTypeDefinitionToUpsert(def) {
|
|
1021
|
+
return {
|
|
1022
|
+
slug: def.slug,
|
|
1023
|
+
name: def.name,
|
|
1024
|
+
namePlural: def.namePlural,
|
|
1025
|
+
description: def.description,
|
|
1026
|
+
icon: def.icon,
|
|
1027
|
+
color: def.color,
|
|
1028
|
+
attributeSchema: def.attributeSchema,
|
|
1029
|
+
stateSchema: def.stateSchema,
|
|
1030
|
+
isEnabled: def.isEnabled,
|
|
1031
|
+
allowUnknownAttributes: def.allowUnknownAttributes ?? false,
|
|
1032
|
+
managedByCode: true
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1019
1035
|
var EntityTypesResource = class {
|
|
1020
1036
|
constructor(http) {
|
|
1021
1037
|
this.http = http;
|
|
@@ -1046,6 +1062,19 @@ var EntityTypesResource = class {
|
|
|
1046
1062
|
query: { expansion: serializeCsv(options.expansion) }
|
|
1047
1063
|
});
|
|
1048
1064
|
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Creates or updates an entity type by workspace-scoped slug.
|
|
1067
|
+
* Prefer the CLI (`npx @lunnoa/client entity-types deploy`) for happy-path deploy.
|
|
1068
|
+
*/
|
|
1069
|
+
upsertBySlug(definition) {
|
|
1070
|
+
const payload = "kind" in definition && definition.kind === "entityType" ? entityTypeDefinitionToUpsert(definition) : definition;
|
|
1071
|
+
return this.http.post("/api/object-types/upsert", {
|
|
1072
|
+
body: payload,
|
|
1073
|
+
query: {
|
|
1074
|
+
expansion: "attributeSchema,stateSchema,description"
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1049
1078
|
};
|
|
1050
1079
|
|
|
1051
1080
|
// src/resources/approvals.ts
|
|
@@ -2021,6 +2050,14 @@ var LunnoaClient = class {
|
|
|
2021
2050
|
};
|
|
2022
2051
|
|
|
2023
2052
|
// src/cli/generate.ts
|
|
2053
|
+
function computeDeploymentSchemaFingerprint(entityTypes) {
|
|
2054
|
+
const parts = [...entityTypes].map((type) => {
|
|
2055
|
+
const revision = type.schemaRevision ?? 1;
|
|
2056
|
+
const allowUnknown = type.allowUnknownAttributes ?? false;
|
|
2057
|
+
return `${type.slug}:${revision}:${allowUnknown ? 1 : 0}`;
|
|
2058
|
+
}).sort();
|
|
2059
|
+
return parts.join("|") || "empty";
|
|
2060
|
+
}
|
|
2024
2061
|
function toCamelCase(input) {
|
|
2025
2062
|
const parts = input.replace(/[^a-zA-Z0-9]+/g, " ").trim().split(/\s+/);
|
|
2026
2063
|
if (parts.length === 0 || parts[0] === "") {
|
|
@@ -2140,6 +2177,9 @@ function isFieldRequired(field) {
|
|
|
2140
2177
|
}
|
|
2141
2178
|
function generateDeploymentModule(definitions) {
|
|
2142
2179
|
const chunks = [];
|
|
2180
|
+
const schemaFingerprint = computeDeploymentSchemaFingerprint(
|
|
2181
|
+
definitions.entityTypes
|
|
2182
|
+
);
|
|
2143
2183
|
chunks.push(
|
|
2144
2184
|
`/* eslint-disable */
|
|
2145
2185
|
/**
|
|
@@ -2148,8 +2188,23 @@ function generateDeploymentModule(definitions) {
|
|
|
2148
2188
|
* Generated by \`npx @lunnoa/client codegen\` \u2014 do not edit by hand.
|
|
2149
2189
|
* Re-run codegen whenever entity types, workflows, or agents change on
|
|
2150
2190
|
* the deployment.
|
|
2191
|
+
*
|
|
2192
|
+
* Schema fingerprint: ${schemaFingerprint}
|
|
2151
2193
|
*/
|
|
2152
2194
|
import type { LunnoaClient, Entity, Execution, ExecuteWorkflowResult, PaginatedEntities, Task, AgentChatStream, WaitUntilFinishedOptions, ListEntitiesOptions, UIMessage } from '@lunnoa/client';
|
|
2195
|
+
|
|
2196
|
+
/** Fingerprint of entity-type schemas at codegen time (slug:revision:allowUnknown). */
|
|
2197
|
+
export const DEPLOYMENT_SCHEMA_FINGERPRINT = ${JSON.stringify(schemaFingerprint)};
|
|
2198
|
+
|
|
2199
|
+
/** Per-type schemaRevision values captured at codegen time. */
|
|
2200
|
+
export const ENTITY_TYPE_SCHEMA_REVISIONS = ${JSON.stringify(
|
|
2201
|
+
Object.fromEntries(
|
|
2202
|
+
definitions.entityTypes.map((type) => [
|
|
2203
|
+
type.slug,
|
|
2204
|
+
type.schemaRevision ?? 1
|
|
2205
|
+
])
|
|
2206
|
+
)
|
|
2207
|
+
)} as const;
|
|
2153
2208
|
`
|
|
2154
2209
|
);
|
|
2155
2210
|
chunks.push(GENERATED_RUNTIME_HELPERS);
|
|
@@ -2438,6 +2493,21 @@ function pickAgentDefinition(mod) {
|
|
|
2438
2493
|
"No defineAgent() export found. Export the definition as default or `agent`."
|
|
2439
2494
|
);
|
|
2440
2495
|
}
|
|
2496
|
+
function pickEntityTypeDefinition(mod) {
|
|
2497
|
+
const candidates = [
|
|
2498
|
+
mod.default,
|
|
2499
|
+
mod.entityType,
|
|
2500
|
+
...Object.values(mod)
|
|
2501
|
+
];
|
|
2502
|
+
for (const value of candidates) {
|
|
2503
|
+
if (value && typeof value === "object" && value.kind === DEFINE_KINDS.entityType) {
|
|
2504
|
+
return value;
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
throw new Error(
|
|
2508
|
+
"No defineEntityType() export found. Export the definition as default or `entityType`."
|
|
2509
|
+
);
|
|
2510
|
+
}
|
|
2441
2511
|
async function loadOptionalConfig() {
|
|
2442
2512
|
const candidates = [
|
|
2443
2513
|
"lunnoa.config.ts",
|
|
@@ -2470,7 +2540,7 @@ async function loadOptionalConfig() {
|
|
|
2470
2540
|
function parseArgs(argv) {
|
|
2471
2541
|
const args = { command: argv[0], out: "./src/lunnoa" };
|
|
2472
2542
|
let i = 1;
|
|
2473
|
-
if (args.command === "workflows" || args.command === "agents") {
|
|
2543
|
+
if (args.command === "workflows" || args.command === "agents" || args.command === "entity-types") {
|
|
2474
2544
|
args.subcommand = argv[1];
|
|
2475
2545
|
i = 2;
|
|
2476
2546
|
if (argv[2] && !argv[2].startsWith("--")) {
|
|
@@ -2516,16 +2586,20 @@ var USAGE = `Usage:
|
|
|
2516
2586
|
npx @lunnoa/client codegen --url <deployment-url> --api-key <lna_key> [--out <dir>]
|
|
2517
2587
|
npx @lunnoa/client workflows deploy <path> --url <url> --api-key <key> --project-id <uuid>
|
|
2518
2588
|
npx @lunnoa/client agents deploy <path> --url <url> --api-key <key> --project-id <uuid>
|
|
2589
|
+
npx @lunnoa/client entity-types deploy <path> --url <url> --api-key <key>
|
|
2519
2590
|
|
|
2520
2591
|
Options:
|
|
2521
2592
|
--url Base URL of the Lunnoa Automate deployment
|
|
2522
2593
|
--api-key Machine API key (lna_...)
|
|
2523
2594
|
--access-token User JWT as an alternative to --api-key
|
|
2524
|
-
--project-id Project UUID (required for deploy)
|
|
2595
|
+
--project-id Project UUID (required for workflow/agent deploy)
|
|
2525
2596
|
--out Output directory for lunnoa.generated.ts (codegen; default: ./src/lunnoa)
|
|
2526
2597
|
|
|
2527
2598
|
Environment: LUNNOA_URL, LUNNOA_API_KEY, LUNNOA_PROJECT_ID
|
|
2528
2599
|
Optional config file: lunnoa.config.ts | .mjs | .js | .json
|
|
2600
|
+
|
|
2601
|
+
Entity-type deploy is workspace-scoped (no --project-id). Unknown instance
|
|
2602
|
+
attributes are rejected unless allowUnknownAttributes is true; use extensions.
|
|
2529
2603
|
`;
|
|
2530
2604
|
async function bindClient(args) {
|
|
2531
2605
|
const fileConfig = await loadOptionalConfig();
|
|
@@ -2636,6 +2710,22 @@ async function deployAgent(args) {
|
|
|
2636
2710
|
const result = await client.agents.upsertBySlug(projectId, payload);
|
|
2637
2711
|
console.log(`Upserted agent ${result.id} (${payload.slug})`);
|
|
2638
2712
|
}
|
|
2713
|
+
async function deployEntityType(args) {
|
|
2714
|
+
if (!args.path) {
|
|
2715
|
+
throw new Error(
|
|
2716
|
+
"Missing definition path. Example: entity-types deploy ./entity-type.ts"
|
|
2717
|
+
);
|
|
2718
|
+
}
|
|
2719
|
+
const { client } = await bindClient(args);
|
|
2720
|
+
const mod = await loadDefinitionModule(args.path);
|
|
2721
|
+
const def = pickEntityTypeDefinition(mod);
|
|
2722
|
+
const payload = entityTypeDefinitionToUpsert(def);
|
|
2723
|
+
console.log(`Deploying entity type slug="${payload.slug}" ...`);
|
|
2724
|
+
const result = await client.entityTypes.upsertBySlug(payload);
|
|
2725
|
+
console.log(
|
|
2726
|
+
`Upserted entity type ${result.id} (${payload.slug})` + (typeof result.schemaRevision === "number" ? ` schemaRevision=${result.schemaRevision}` : "")
|
|
2727
|
+
);
|
|
2728
|
+
}
|
|
2639
2729
|
async function main() {
|
|
2640
2730
|
const args = parseArgs(process.argv.slice(2));
|
|
2641
2731
|
if (!args.command || args.command === "--help" || args.command === "help") {
|
|
@@ -2654,6 +2744,10 @@ async function main() {
|
|
|
2654
2744
|
await deployAgent(args);
|
|
2655
2745
|
return;
|
|
2656
2746
|
}
|
|
2747
|
+
if (args.command === "entity-types" && args.subcommand === "deploy") {
|
|
2748
|
+
await deployEntityType(args);
|
|
2749
|
+
return;
|
|
2750
|
+
}
|
|
2657
2751
|
console.error(`Unknown command: ${args.command} ${args.subcommand ?? ""}
|
|
2658
2752
|
`);
|
|
2659
2753
|
console.log(USAGE);
|
package/dist/index.cjs
CHANGED
|
@@ -533,7 +533,8 @@ var DEFINE_KINDS = {
|
|
|
533
533
|
aiConnection: "aiConnection",
|
|
534
534
|
action: "action",
|
|
535
535
|
workflow: "workflow",
|
|
536
|
-
agent: "agent"
|
|
536
|
+
agent: "agent",
|
|
537
|
+
entityType: "entityType"
|
|
537
538
|
};
|
|
538
539
|
function defineConnection(config = {}) {
|
|
539
540
|
return { kind: DEFINE_KINDS.connection, ...config };
|
|
@@ -568,6 +569,19 @@ function defineAgent(config) {
|
|
|
568
569
|
}
|
|
569
570
|
return { kind: DEFINE_KINDS.agent, ...config };
|
|
570
571
|
}
|
|
572
|
+
function defineEntityType(config) {
|
|
573
|
+
if (!config.slug?.trim()) {
|
|
574
|
+
throw new Error("defineEntityType requires slug");
|
|
575
|
+
}
|
|
576
|
+
if (!config.attributeSchema || typeof config.attributeSchema !== "object" || Array.isArray(config.attributeSchema)) {
|
|
577
|
+
throw new Error("defineEntityType requires attributeSchema object");
|
|
578
|
+
}
|
|
579
|
+
return {
|
|
580
|
+
kind: DEFINE_KINDS.entityType,
|
|
581
|
+
allowUnknownAttributes: false,
|
|
582
|
+
...config
|
|
583
|
+
};
|
|
584
|
+
}
|
|
571
585
|
function resolveActionAppId(action) {
|
|
572
586
|
if (action.appId?.trim()) {
|
|
573
587
|
return action.appId.trim();
|
|
@@ -1045,6 +1059,21 @@ var EntitiesResource = class {
|
|
|
1045
1059
|
};
|
|
1046
1060
|
|
|
1047
1061
|
// src/resources/entity-types.ts
|
|
1062
|
+
function entityTypeDefinitionToUpsert(def) {
|
|
1063
|
+
return {
|
|
1064
|
+
slug: def.slug,
|
|
1065
|
+
name: def.name,
|
|
1066
|
+
namePlural: def.namePlural,
|
|
1067
|
+
description: def.description,
|
|
1068
|
+
icon: def.icon,
|
|
1069
|
+
color: def.color,
|
|
1070
|
+
attributeSchema: def.attributeSchema,
|
|
1071
|
+
stateSchema: def.stateSchema,
|
|
1072
|
+
isEnabled: def.isEnabled,
|
|
1073
|
+
allowUnknownAttributes: def.allowUnknownAttributes ?? false,
|
|
1074
|
+
managedByCode: true
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1048
1077
|
var EntityTypesResource = class {
|
|
1049
1078
|
constructor(http) {
|
|
1050
1079
|
this.http = http;
|
|
@@ -1075,6 +1104,19 @@ var EntityTypesResource = class {
|
|
|
1075
1104
|
query: { expansion: serializeCsv(options.expansion) }
|
|
1076
1105
|
});
|
|
1077
1106
|
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Creates or updates an entity type by workspace-scoped slug.
|
|
1109
|
+
* Prefer the CLI (`npx @lunnoa/client entity-types deploy`) for happy-path deploy.
|
|
1110
|
+
*/
|
|
1111
|
+
upsertBySlug(definition) {
|
|
1112
|
+
const payload = "kind" in definition && definition.kind === "entityType" ? entityTypeDefinitionToUpsert(definition) : definition;
|
|
1113
|
+
return this.http.post("/api/object-types/upsert", {
|
|
1114
|
+
body: payload,
|
|
1115
|
+
query: {
|
|
1116
|
+
expansion: "attributeSchema,stateSchema,description"
|
|
1117
|
+
}
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1078
1120
|
};
|
|
1079
1121
|
|
|
1080
1122
|
// src/resources/approvals.ts
|
|
@@ -2158,7 +2200,9 @@ exports.defineAction = defineAction;
|
|
|
2158
2200
|
exports.defineAgent = defineAgent;
|
|
2159
2201
|
exports.defineAiConnection = defineAiConnection;
|
|
2160
2202
|
exports.defineConnection = defineConnection;
|
|
2203
|
+
exports.defineEntityType = defineEntityType;
|
|
2161
2204
|
exports.defineWorkflow = defineWorkflow;
|
|
2205
|
+
exports.entityTypeDefinitionToUpsert = entityTypeDefinitionToUpsert;
|
|
2162
2206
|
exports.isBrowserEnvironment = isBrowserEnvironment;
|
|
2163
2207
|
exports.isLoginRequires2FA = isLoginRequires2FA;
|
|
2164
2208
|
exports.iterateOffset = iterateOffset;
|