@segmentstream-cloud/ontology 0.9.0 → 0.11.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.
Files changed (90) hide show
  1. package/dist/action.d.ts +19 -0
  2. package/dist/action.js +1 -0
  3. package/dist/analyze.d.ts +3 -1
  4. package/dist/analyze.js +97 -2
  5. package/dist/bin/migrate.js +3 -2
  6. package/dist/blob.d.ts +39 -0
  7. package/dist/blob.js +49 -0
  8. package/dist/diagnostics.d.ts +3 -3
  9. package/dist/diagnostics.js +1 -0
  10. package/dist/entity.d.ts +5 -3
  11. package/dist/index.d.ts +9 -4
  12. package/dist/index.js +6 -1
  13. package/dist/manifest.d.ts +71 -7
  14. package/dist/manifest.js +18 -1
  15. package/dist/migrate/apply.d.ts +7 -0
  16. package/dist/migrate/apply.js +18 -1
  17. package/dist/migrate/index.d.ts +1 -1
  18. package/dist/migrate/index.js +1 -1
  19. package/dist/migrate/model.d.ts +15 -2
  20. package/dist/migrate/plan.d.ts +6 -0
  21. package/dist/migrate/plan.js +35 -3
  22. package/dist/migrate/storage.d.ts +14 -0
  23. package/dist/migrate/storage.js +95 -0
  24. package/dist/names.d.ts +9 -1
  25. package/dist/names.js +11 -0
  26. package/dist/nitro.d.ts +13 -0
  27. package/dist/nitro.js +18 -0
  28. package/dist/property.d.ts +10 -1
  29. package/dist/property.js +12 -1
  30. package/dist/query.js +6 -1
  31. package/dist/runtime/generated-actions.d.ts +3 -0
  32. package/dist/runtime/generated-actions.js +10 -5
  33. package/dist/runtime/history.d.ts +3 -0
  34. package/dist/runtime/oauth.d.ts +9 -0
  35. package/dist/runtime/oauth.js +165 -0
  36. package/dist/runtime/pipeline.d.ts +5 -1
  37. package/dist/runtime/pipeline.js +87 -3
  38. package/dist/runtime/principals.d.ts +5 -0
  39. package/dist/runtime/principals.js +15 -0
  40. package/dist/runtime/records.js +9 -0
  41. package/dist/runtime/service-binding.d.ts +2 -1
  42. package/dist/runtime/service-binding.js +15 -2
  43. package/dist/runtime/writes.js +17 -3
  44. package/dist/service/api.js +19 -10
  45. package/dist/service/authentication.d.ts +27 -1
  46. package/dist/service/authentication.js +48 -26
  47. package/dist/service/config.d.ts +8 -0
  48. package/dist/service/config.js +18 -0
  49. package/dist/service/descriptions.d.ts +8 -0
  50. package/dist/service/descriptions.js +15 -0
  51. package/dist/service/errors.d.ts +5 -1
  52. package/dist/service/errors.js +6 -2
  53. package/dist/service/handlers.d.ts +1 -4
  54. package/dist/service/handlers.js +59 -203
  55. package/dist/service/mcp/server.d.ts +24 -0
  56. package/dist/service/mcp/server.js +370 -0
  57. package/dist/service/mcp/tools.d.ts +47 -0
  58. package/dist/service/mcp/tools.js +218 -0
  59. package/dist/service/oauth/protocol.d.ts +52 -0
  60. package/dist/service/oauth/protocol.js +110 -0
  61. package/dist/service/oauth/server.d.ts +27 -0
  62. package/dist/service/oauth/server.js +576 -0
  63. package/dist/service/operations.d.ts +114 -0
  64. package/dist/service/operations.js +218 -0
  65. package/dist/service/runtime-contract.d.ts +98 -0
  66. package/dist/service/schemas.d.ts +18 -2
  67. package/dist/service/schemas.js +18 -2
  68. package/dist/service/service.d.ts +3 -3
  69. package/dist/service/service.js +27 -7
  70. package/dist/storage/api.d.ts +4 -0
  71. package/dist/storage/api.js +39 -0
  72. package/dist/storage/authorization.d.ts +8 -0
  73. package/dist/storage/authorization.js +30 -0
  74. package/dist/storage/maintenance-auth.d.ts +20 -0
  75. package/dist/storage/maintenance-auth.js +24 -0
  76. package/dist/storage/maintenance.d.ts +7 -0
  77. package/dist/storage/maintenance.js +50 -0
  78. package/dist/storage/neon.d.ts +3 -0
  79. package/dist/storage/neon.js +212 -0
  80. package/dist/storage/operator.d.ts +10 -0
  81. package/dist/storage/operator.js +30 -0
  82. package/dist/storage/provider.d.ts +80 -0
  83. package/dist/storage/provider.js +20 -0
  84. package/dist/storage/sessions.d.ts +87 -0
  85. package/dist/storage/sessions.js +341 -0
  86. package/dist/storage/tables.d.ts +2 -0
  87. package/dist/storage/tables.js +55 -0
  88. package/dist/storage/writes.d.ts +7 -0
  89. package/dist/storage/writes.js +88 -0
  90. package/package.json +8 -1
package/dist/action.d.ts CHANGED
@@ -17,6 +17,17 @@ export interface ActionContext<Input, Prepared = undefined> extends PrepareConte
17
17
  }
18
18
  /** What `prepare` may fail with: the action errors, and connection calls that failed. */
19
19
  export type PrepareError = ActionError | ConnectionError;
20
+ /**
21
+ * How an action behaves, as MCP tool annotations tell agents. Clients such as Claude ask the user
22
+ * before they run a destructive tool. Without hints an action is taken as destructive and not
23
+ * idempotent.
24
+ */
25
+ export interface ActionHints {
26
+ /** Whether the action may overwrite or remove what someone decided. Default true. */
27
+ readonly destructive?: boolean;
28
+ /** Whether running it again with the same input changes nothing more. Default false. */
29
+ readonly idempotent?: boolean;
30
+ }
20
31
  /** A described, typed, permissioned Effect function: the only way to change records. */
21
32
  export interface Action<Input extends Schema.Top = Schema.Top, Result = unknown> {
22
33
  readonly [ActionTypeId]: typeof ActionTypeId;
@@ -27,6 +38,8 @@ export interface Action<Input extends Schema.Top = Schema.Top, Result = unknown>
27
38
  * is not set, the action requires `<entity>:<action name>`, for example `lead:changeStatus`.
28
39
  */
29
40
  readonly permission: string | undefined;
41
+ /** How the action behaves, as `action({ hints })` set it; see {@link ActionHints}. */
42
+ readonly hints: ActionHints | undefined;
30
43
  /** The connections `prepare` may call; empty for an action without `prepare`. */
31
44
  readonly connections: ReadonlyArray<AnyConnectionHandle>;
32
45
  /**
@@ -64,6 +77,12 @@ interface ActionOptions<Input extends Schema.Top> {
64
77
  * Roles grant it in their `permissions`.
65
78
  */
66
79
  readonly permission?: string;
80
+ /**
81
+ * How the action behaves, for the agents that run it over MCP. Set `destructive: false` for an
82
+ * action that only adds or that history makes easy to reverse, and `idempotent: true` for one
83
+ * that a repeated call leaves as it was.
84
+ */
85
+ readonly hints?: ActionHints;
67
86
  }
68
87
  export interface ActionConfig<Input extends Schema.Top, Result> extends ActionOptions<Input> {
69
88
  /**
package/dist/action.js CHANGED
@@ -11,6 +11,7 @@ export function action(config) {
11
11
  description: config.description,
12
12
  input: config.input,
13
13
  permission: config.permission,
14
+ hints: config.hints,
14
15
  connections: config.connections ?? [],
15
16
  ...(config.prepare === undefined ? {} : { prepare: config.prepare }),
16
17
  // A prepare-only action answers with what prepare returned; it writes nothing.
package/dist/analyze.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Schema } from "effect";
2
- import { type Action } from "./action.js";
2
+ import { type Action, type ActionHints } from "./action.js";
3
3
  import { type AnyConnectionHandle } from "./connection.js";
4
4
  import type { Diagnostic } from "./diagnostics.js";
5
5
  import { type AnyEntity } from "./entity.js";
@@ -67,6 +67,8 @@ export interface ResolvedAction {
67
67
  readonly input: JsonSchemaObject | undefined;
68
68
  /** The keys of the connections the action's `prepare` calls, in declaration order. */
69
69
  readonly connections: ReadonlyArray<string>;
70
+ /** The hints the action declares, or `undefined` when it declares none. */
71
+ readonly hints: ActionHints | undefined;
70
72
  }
71
73
  /** A connection the ontology declares. */
72
74
  export interface ResolvedConnection {
package/dist/analyze.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import { checkWarehouseSource } from "./warehouse-backed.js";
2
2
  import { Schema } from "effect";
3
+ import { BLOB_UPLOAD_ANNOTATION } from "./blob.js";
4
+ import { BLOB_CONTENT_TYPES, MAX_BLOB_BYTES } from "./blob.js";
3
5
  import { isAction } from "./action.js";
4
6
  import { CONNECTION_KEY, isConnection } from "./connection.js";
5
7
  import { isEntity } from "./entity.js";
6
- import { LEGACY_MEMBER_NAME, ENTITY_ID, GENERATED_ACTIONS, GENERATED_UPSERT_PREFIX, HISTORY_SUFFIX, MEMBER_ROLE, RESERVED_ENTITY_NAMES, RESERVED_MEMBER_NAMES, RESERVED_RELATIONSHIP_NAMES, SNAKE_CASE_NAME, SYSTEM_PROPERTIES, isSystemProperty, } from "./names.js";
8
+ import { LEGACY_MEMBER_NAME, ENTITY_ID, GENERATED_ACTIONS, GENERATED_UPSERT_PREFIX, HISTORY_SUFFIX, MCP_READ_TOOLS, MCP_TOOL_NAME_MAX_LENGTH, MEMBER_ROLE, mcpToolName, RESERVED_ENTITY_NAMES, RESERVED_MEMBER_NAMES, RESERVED_RELATIONSHIP_NAMES, SNAKE_CASE_NAME, SYSTEM_PROPERTIES, isSystemProperty, } from "./names.js";
7
9
  import { REFERENCE_ANNOTATION, propertyDefinition, referenceTarget, } from "./property.js";
8
10
  import { generatedActionPermissions, parsePermission, permissionOf, READ_VERB, rolesGranting, WILDCARD, } from "./permissions.js";
9
11
  import { ON_DELETE, isRelationship } from "./relationship.js";
@@ -56,6 +58,7 @@ export function analyze(config, options = {}) {
56
58
  const resolved = entities.map((candidate) => resolveEntity(candidate, scope));
57
59
  checkEntityIdentities(resolved, report);
58
60
  checkMemberNames(resolved, report);
61
+ checkToolNames(resolved, report);
59
62
  checkWarehouseSource(resolved, report);
60
63
  checkConnectionsUsed(resolved, connections, config.connections ?? [], report);
61
64
  if (options.checkPermissions !== false) {
@@ -63,6 +66,58 @@ export function analyze(config, options = {}) {
63
66
  }
64
67
  return { entities: resolved, roles, signIn, connections, diagnostics };
65
68
  }
69
+ /**
70
+ * The operations of a stored entity that become MCP tools, each with the path a problem is reported
71
+ * at: the reads, the generated actions and the authored actions.
72
+ */
73
+ function toolOperations(candidate) {
74
+ const { permissions } = candidate;
75
+ const generated = [
76
+ ...(permissions.create !== undefined ? ["create", "update", "delete"] : []),
77
+ ...(permissions.create !== undefined
78
+ ? candidate.properties
79
+ .filter(({ definition }) => definition.unique)
80
+ .map(({ name }) => `${GENERATED_UPSERT_PREFIX}${name}`)
81
+ : []),
82
+ ...(permissions.link !== undefined ? ["link", "unlink"] : []),
83
+ ];
84
+ return [
85
+ ...[...MCP_READ_TOOLS, ...generated].map((operation) => ({ operation, path: candidate.name })),
86
+ // An authored action with a generated action's name is already refused as a reserved name.
87
+ ...candidate.actions
88
+ .filter(({ name }) => !GENERATED_ACTIONS.includes(name) && !GENERATED_UPSERT.test(name))
89
+ .map(({ name }) => ({ operation: name, path: `${candidate.name}.actions.${name}` })),
90
+ ];
91
+ }
92
+ /**
93
+ * Every MCP tool needs a name of its own, at most 64 characters long. A tool's name joins the
94
+ * entity's and the operation's with an underscore, so entity `pilot` with an action `request_find`
95
+ * would take the name of entity `pilot_request`'s `find`.
96
+ */
97
+ function checkToolNames(entities, report) {
98
+ const owners = new Map();
99
+ const seen = new Set();
100
+ for (const candidate of entities) {
101
+ // A second entity with the same name is already refused as a duplicate.
102
+ if (candidate.entity.definition.source !== undefined || seen.has(candidate.name)) {
103
+ continue;
104
+ }
105
+ seen.add(candidate.name);
106
+ for (const { operation, path } of toolOperations(candidate)) {
107
+ const name = mcpToolName(candidate.name, operation);
108
+ const owner = owners.get(name);
109
+ if (owner !== undefined) {
110
+ report("invalid-tool-name", path, `its MCP tool ${name} is already the tool of ${owner}; rename one of them.`);
111
+ continue;
112
+ }
113
+ owners.set(name, `${candidate.name}'s ${operation}`);
114
+ if (name.length > MCP_TOOL_NAME_MAX_LENGTH) {
115
+ report("invalid-tool-name", path, `its MCP tool ${name} is ${name.length} characters long; agents accept at most ` +
116
+ `${MCP_TOOL_NAME_MAX_LENGTH}. Shorten the entity or the action name.`);
117
+ }
118
+ }
119
+ }
120
+ }
66
121
  /** The handles `defineOntology({ connections })` lists, each with a valid key and a description. */
67
122
  function collectConnections(config, report) {
68
123
  const declared = config.connections;
@@ -340,6 +395,19 @@ function resolveProperties(candidate, scope) {
340
395
  return properties;
341
396
  }
342
397
  function checkProperty(path, schema, definition, report) {
398
+ if (definition.type === "blob") {
399
+ if (definition.unique || "default" in definition) {
400
+ report("invalid-property", path, "Blob properties cannot be unique or have a default.");
401
+ }
402
+ if (!definition.accept?.length ||
403
+ definition.accept.some((type) => !BLOB_CONTENT_TYPES.includes(type)) ||
404
+ new Set(definition.accept).size !== definition.accept.length ||
405
+ !Number.isInteger(definition.maxBytes) ||
406
+ definition.maxBytes < 1 ||
407
+ definition.maxBytes > MAX_BLOB_BYTES) {
408
+ report("invalid-constraint", path, "Use supported content types and a limit from 1 byte to 25 MiB.");
409
+ }
410
+ }
343
411
  if (definition.type === "select") {
344
412
  checkSelectOptions(path, definition, report);
345
413
  }
@@ -531,10 +599,37 @@ function resolveActions(candidate, scope) {
531
599
  permission: resolvePermission(path, permissionOf(candidate.name, name), action, scope),
532
600
  input: resolveInput(path, action.input, scope),
533
601
  connections: resolveActionConnections(path, action, scope),
602
+ hints: resolveHints(path, action, report),
534
603
  });
535
604
  }
536
605
  return actions;
537
606
  }
607
+ const HINT_NAMES = ["destructive", "idempotent"];
608
+ /** The action's `hints`: an object of booleans, `destructive` and `idempotent`. */
609
+ function resolveHints(path, action, report) {
610
+ const declared = action.hints;
611
+ if (declared === undefined) {
612
+ return undefined;
613
+ }
614
+ const at = `${path}.hints`;
615
+ if (!isPlainObject(declared)) {
616
+ report("invalid-action", at, "hints is an object such as { destructive: false }.");
617
+ return undefined;
618
+ }
619
+ const hints = {};
620
+ for (const [key, value] of Object.entries(declared)) {
621
+ if (!HINT_NAMES.includes(key)) {
622
+ report("invalid-action", `${at}.${key}`, `is not a hint; use ${HINT_NAMES.join(" or ")}.`);
623
+ }
624
+ else if (typeof value !== "boolean") {
625
+ report("invalid-action", `${at}.${key}`, "is true or false.");
626
+ }
627
+ else {
628
+ hints[key] = value;
629
+ }
630
+ }
631
+ return hints;
632
+ }
538
633
  /** The action's own `permission`, which names an entity and a verb without wildcards. */
539
634
  function resolvePermission(path, fallback, action, scope) {
540
635
  const declared = action.permission;
@@ -563,7 +658,7 @@ function resolveInput(path, input, scope) {
563
658
  }
564
659
  try {
565
660
  const document = Schema.toJsonSchemaDocument(input, {
566
- includeAnnotationKey: (key) => key === REFERENCE_ANNOTATION,
661
+ includeAnnotationKey: (key) => key === REFERENCE_ANNOTATION || key === BLOB_UPLOAD_ANNOTATION,
567
662
  onExcessProperty: "error",
568
663
  });
569
664
  const schema = document.schema;
@@ -2,7 +2,7 @@ import * as PgClient from "@effect/sql-pg/PgClient";
2
2
  import { Cause, Effect, Redacted } from "effect";
3
3
  import { SqlClient } from "effect/unstable/sql";
4
4
  import { isSqlError } from "effect/unstable/sql/SqlError";
5
- import { applyMigration, readCatalog } from "../migrate/apply.js";
5
+ import { applyMigration, readCatalog, readRuntimeTables, } from "../migrate/apply.js";
6
6
  import { MigrationRefused } from "../migrate/errors.js";
7
7
  import { isNoopMigration } from "../migrate/model.js";
8
8
  import { planMigration } from "../migrate/plan.js";
@@ -88,7 +88,8 @@ function migrateDatabase(input) {
88
88
  return Effect.gen(function* () {
89
89
  const sql = yield* SqlClient.SqlClient;
90
90
  const current = yield* readCatalog({ sql });
91
- const plan = planMigration({ current, target });
91
+ const existingTables = yield* readRuntimeTables({ sql });
92
+ const plan = planMigration({ current, target, existingTables });
92
93
  output.stdout(formatPlan(plan, { sql: input.planOnly }));
93
94
  if (plan.refusals.length > 0) {
94
95
  output.stderr(formatRefusals(plan.refusals));
package/dist/blob.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ import { Schema } from "effect";
2
+ /** Metadata of an immutable file revision. Provider keys and grants never appear in records. */
3
+ export declare const BlobValue: Schema.Struct<{
4
+ readonly id: Schema.String;
5
+ readonly filename: Schema.String;
6
+ readonly contentType: Schema.String;
7
+ readonly size: Schema.Int;
8
+ readonly createdAt: Schema.String;
9
+ }>;
10
+ export type BlobValue = typeof BlobValue.Type;
11
+ /** An opaque completed-upload ticket. Only the action runtime may resolve and consume it. */
12
+ declare function uploadCodec(entity?: string, property?: string): Schema.decodeTo<Schema.Struct<{
13
+ readonly uploadId: Schema.String;
14
+ }>, Schema.Struct<{
15
+ readonly upload_id: Schema.String;
16
+ }>, never, never>;
17
+ export declare const BlobUpload: Schema.Struct<{
18
+ readonly uploadId: Schema.String;
19
+ }>;
20
+ export type BlobUpload = typeof BlobUpload.Type;
21
+ export declare const BLOB_UPLOAD_ANNOTATION = "x-ontology-upload";
22
+ export declare const MAX_BLOB_BYTES: number;
23
+ export declare const BLOB_CONTENT_TYPES: readonly ["application/pdf", "image/jpeg", "image/png", "text/plain"];
24
+ type SchemaValue<S> = S extends {
25
+ readonly Type: infer T;
26
+ } ? T : S extends Schema.optionalKey<infer Inner> ? Inner["Type"] : never;
27
+ type BlobPropertyKey<P> = {
28
+ [K in keyof P]: NonNullable<SchemaValue<P[K]>> extends BlobValue ? K : never;
29
+ }[keyof P] & string;
30
+ /** Internal wire codec for session tickets and generated action inputs. */
31
+ export declare function uploadInput(entity?: string, property?: string): ReturnType<typeof uploadCodec>;
32
+ /** Declares which blob field an authored action's upload input may write. */
33
+ export declare const uploads: {
34
+ for<const P extends Readonly<Record<string, unknown>>>(entity: {
35
+ readonly name: string;
36
+ readonly properties: P;
37
+ }, property: BlobPropertyKey<P>): typeof BlobUpload;
38
+ };
39
+ export {};
package/dist/blob.js ADDED
@@ -0,0 +1,49 @@
1
+ import { Schema, SchemaTransformation } from "effect";
2
+ import { nameToWire } from "./authoring-names.js";
3
+ /** Metadata of an immutable file revision. Provider keys and grants never appear in records. */
4
+ export const BlobValue = Schema.Struct({
5
+ id: Schema.String.check(Schema.isUUID()),
6
+ filename: Schema.String,
7
+ contentType: Schema.String,
8
+ size: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
9
+ createdAt: Schema.String,
10
+ });
11
+ /** An opaque completed-upload ticket. Only the action runtime may resolve and consume it. */
12
+ function uploadCodec(entity, property) {
13
+ const id = Schema.String.check(Schema.isUUID());
14
+ return Schema.Struct({ upload_id: id })
15
+ .annotate({
16
+ ...(entity && property
17
+ ? {
18
+ description: `A completed upload for ${entity}.${property}.`,
19
+ "x-ontology-upload": { entity, property },
20
+ }
21
+ : {}),
22
+ })
23
+ .pipe(Schema.decodeTo(Schema.Struct({ uploadId: id }), SchemaTransformation.transform({
24
+ decode: (value) => ({ uploadId: value.upload_id }),
25
+ encode: (value) => ({ upload_id: value.uploadId }),
26
+ })));
27
+ }
28
+ export const BlobUpload = Schema.Struct({ uploadId: Schema.String.check(Schema.isUUID()) });
29
+ export const BLOB_UPLOAD_ANNOTATION = "x-ontology-upload";
30
+ export const MAX_BLOB_BYTES = 25 * 1024 * 1024;
31
+ export const BLOB_CONTENT_TYPES = [
32
+ "application/pdf",
33
+ "image/jpeg",
34
+ "image/png",
35
+ "text/plain",
36
+ ];
37
+ /** Internal wire codec for session tickets and generated action inputs. */
38
+ export function uploadInput(entity, property) {
39
+ return uploadCodec(entity, property);
40
+ }
41
+ /** Declares which blob field an authored action's upload input may write. */
42
+ export const uploads = {
43
+ for(entity, property) {
44
+ return BlobUpload.annotate({
45
+ description: `A completed upload for ${entity.name}.${property}.`,
46
+ "x-ontology-upload": { entity: nameToWire(entity.name), property: nameToWire(property) },
47
+ });
48
+ },
49
+ };
@@ -1,10 +1,10 @@
1
1
  import { Schema } from "effect";
2
- export declare const DIAGNOSTIC_CODES: readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare"];
2
+ export declare const DIAGNOSTIC_CODES: readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare", "invalid-tool-name"];
3
3
  export type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[number];
4
4
  /** A problem `check` found in an ontology definition. */
5
5
  export declare const Diagnostic: Schema.Struct<{
6
6
  readonly severity: Schema.Literals<readonly ["error", "warning"]>;
7
- readonly code: Schema.Literals<readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare"]>;
7
+ readonly code: Schema.Literals<readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare", "invalid-tool-name"]>;
8
8
  /** Where the problem is, for example `lead.properties.status.options[1]`. */
9
9
  readonly path: Schema.String;
10
10
  readonly message: Schema.String;
@@ -14,7 +14,7 @@ declare const InvalidOntology_base: Schema.Class<InvalidOntology, Schema.TaggedS
14
14
  readonly message: Schema.String;
15
15
  readonly diagnostics: Schema.$Array<Schema.Struct<{
16
16
  readonly severity: Schema.Literals<readonly ["error", "warning"]>;
17
- readonly code: Schema.Literals<readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare"]>;
17
+ readonly code: Schema.Literals<readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare", "invalid-tool-name"]>;
18
18
  /** Where the problem is, for example `lead.properties.status.options[1]`. */
19
19
  readonly path: Schema.String;
20
20
  readonly message: Schema.String;
@@ -49,6 +49,7 @@ export const DIAGNOSTIC_CODES = [
49
49
  "unknown-connection",
50
50
  "unused-connection",
51
51
  "invalid-prepare",
52
+ "invalid-tool-name",
52
53
  ];
53
54
  /** A problem `check` found in an ontology definition. */
54
55
  export const Diagnostic = Schema.Struct({
package/dist/entity.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { BlobUpload, BlobValue } from "./blob.js";
1
2
  import { Effect, type Schema } from "effect";
2
3
  import type { Measures } from "./measure.js";
3
4
  import type { WarehouseSource } from "./source.js";
@@ -39,6 +40,7 @@ type IsOptional<S> = S extends {
39
40
  type ValueOf<S> = S extends {
40
41
  readonly Type: infer T;
41
42
  } ? IsOptional<S> extends true ? T | null : T : never;
43
+ type WriteValueOf<S> = NonNullable<ValueOf<S>> extends BlobValue ? BlobUpload | (null extends ValueOf<S> ? null : never) : ValueOf<S>;
42
44
  type RequiredOnCreate<S> = IsOptional<S> extends true ? false : S extends {
43
45
  readonly "~ontology.defaulted": true;
44
46
  } ? false : true;
@@ -68,9 +70,9 @@ export type EntityRecord<P, R> = Simplify<SystemFields & {
68
70
  * relationships take ids by relationship name (`{ lead: lead.id }`), `rel.many` a list of ids.
69
71
  */
70
72
  export type CreateValues<P, R> = Simplify<{
71
- readonly [K in RequiredPropertyKeys<P>]: ValueOf<P[K]>;
73
+ readonly [K in RequiredPropertyKeys<P>]: WriteValueOf<P[K]>;
72
74
  } & {
73
- readonly [K in Exclude<keyof P, RequiredPropertyKeys<P>>]?: ValueOf<P[K]>;
75
+ readonly [K in Exclude<keyof P, RequiredPropertyKeys<P>>]?: WriteValueOf<P[K]>;
74
76
  } & {
75
77
  readonly [K in RequiredOneKeys<R>]: string;
76
78
  } & {
@@ -80,7 +82,7 @@ export type CreateValues<P, R> = Simplify<{
80
82
  }>;
81
83
  /** Values for `update`. Handlers may write `managed` properties; the generated `update` may not. */
82
84
  export type UpdateValues<P, R> = Simplify<{
83
- readonly [K in keyof P]?: ValueOf<P[K]>;
85
+ readonly [K in keyof P]?: WriteValueOf<P[K]>;
84
86
  } & {
85
87
  readonly [K in OneKeys<R>]?: R[K] extends OneRelationship<true> ? string | null : string;
86
88
  } & {
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
+ export { BlobValue, BlobUpload, uploads, BLOB_CONTENT_TYPES, MAX_BLOB_BYTES } from "./blob.js";
1
2
  export { warehouse, compatibleWarehouseColumn, warehouseColumnType, validateWarehouseSource, } from "./source.js";
2
3
  export type { WarehouseSource } from "./source.js";
3
4
  export { m } from "./measure.js";
4
5
  export type { Measure, Measures, MeasureExpression, MeasureOptions } from "./measure.js";
5
6
  export { action, isAction } from "./action.js";
6
- export type { Action, ActionConfig, ActionConfigWithConnections, ActionContext, ActionEncodedInput, ActionInput, ActionResult, Actions, AnyAction, PrepareContext, PrepareError, } from "./action.js";
7
+ export type { Action, ActionConfig, ActionConfigWithConnections, ActionContext, ActionEncodedInput, ActionHints, ActionInput, ActionResult, Actions, AnyAction, PrepareContext, PrepareError, } from "./action.js";
7
8
  export { CONNECTION_ERROR_REASONS, CONNECTION_KEY, CONNECTION_METHODS, connection, ConnectionError, Connections, ConnectionTransport, isConnection, MAXIMUM_CONNECTION_BODY_BYTES, } from "./connection.js";
8
9
  export type { AnyConnectionHandle, Connection, ConnectionCall, ConnectionClient, ConnectionErrorReason, ConnectionHandle, ConnectionHeaders, ConnectionMethod, ConnectionOptions, ConnectionReply, ConnectionRequest, ConnectionRequestOptions, ConnectionResponse, ConnectionsOf, ConnectionStub, StubRequest, StubResponse, } from "./connection.js";
9
10
  export type { EntityPermissions, JsonSchemaObject, MemberOptions, OntologyConfig, ResolvedAction, ResolvedConnection, ResolvedEntity, ResolvedIndex, ResolvedProperty, ResolvedRelationship, } from "./analyze.js";
@@ -21,7 +22,7 @@ export type { Ontology } from "./ontology.js";
21
22
  export { DEFAULT_MEMBER_PERMISSIONS, generatedActionPermissions, grants, isAllowed, parsePermission, permissionsOf, READ_VERB, rolesGranting, WILDCARD, } from "./permissions.js";
22
23
  export type { ParsedPermission, PermissionHolder, RolePermissions } from "./permissions.js";
23
24
  export { p, PROPERTY_TYPES, propertyDefinition } from "./property.js";
24
- export type { AnyProperty, NumberOptions, Property, PropertyDefinition, PropertyOf, PropertyOptions, PropertyType, ReferenceOptions, SelectOption, SelectOptionInput, TextOptions, } from "./property.js";
25
+ export type { AnyProperty, NumberOptions, Property, PropertyDefinition, PropertyOf, PropertyOptions, BlobOptions, PropertyType, ReferenceOptions, SelectOption, SelectOptionInput, TextOptions, } from "./property.js";
25
26
  export { ON_DELETE, rel } from "./relationship.js";
26
27
  export type { AnyRelationship, EntityTarget, LazyEntity, ManyOptions, ManyRelationship, OnDelete, OneOptions, OneRelationship, Phrase, } from "./relationship.js";
27
28
  export { renderCatalog } from "./render.js";
@@ -54,8 +55,12 @@ export type { ConnectionAudit, ConnectionTransportFactory, LocalConnection, Loca
54
55
  export { configFromEnv, ENVIRONMENT_VARIABLES, NEON_AUTH_ENVIRONMENT_VARIABLES, OntologyServiceConfigError, } from "./service/config.js";
55
56
  export type { ActionCommitted, AfterCommitHook, NeonAuthEnvironment, OntologyEnvironment, OntologyServiceConfig, } from "./service/config.js";
56
57
  export { NotInvited, OntologyBackend } from "./service/runtime-contract.js";
57
- export type { GeneratedActionsProvider, IdentityProvider, OntologyServiceRuntime, RunActionInput, SignInIdentity, } from "./service/runtime-contract.js";
58
+ export type { GeneratedActionsProvider, IdentityProvider, OAuthClient, OAuthClientAuthMethod, OAuthGrant, OAuthRequest, OAuthStore, OAuthToken, OAuthTokenKind, OntologyServiceRuntime, RunActionInput, SignInIdentity, UsedOAuthToken, } from "./service/runtime-contract.js";
58
59
  export { createOntologyService, ONTOLOGY_HASH_HEADER, REQUEST_ID_HEADER, } from "./service/service.js";
60
+ export { MCP_PATH, MCP_PROTOCOL_VERSIONS } from "./service/mcp/server.js";
61
+ export { MCP_TOOL_NAME_MAX_LENGTH, mcpToolName } from "./names.js";
59
62
  export type { OntologyService } from "./service/service.js";
60
- export { applyMigration, CatalogInvalid, CatalogMismatch, isNoopMigration, migrate, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationFailed, MigrationPlan, MigrationRefusal, MigrationRefused, MigrationStep, OntologyStorage, planMigration, readCatalog, } from "./migrate/index.js";
63
+ export { applyMigration, CatalogInvalid, CatalogMismatch, isNoopMigration, migrate, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationFailed, MigrationPlan, MigrationRefusal, MigrationRefused, MigrationStep, OntologyStorage, planMigration, readCatalog, readRuntimeTables, } from "./migrate/index.js";
61
64
  export type { ApplyMigrationError, ApplyMigrationOptions, CatalogInput, MigrateInput, MigrationOptions, MigrationRefusalCode, MigrationResult, MigrationStepClassification, MigrationStepKind, PlanMigrationInput, } from "./migrate/index.js";
65
+ export type { BlobStorageBinding } from "./storage/provider.js";
66
+ export { runBlobStorageMaintenance } from "./storage/operator.js";
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { BlobValue, BlobUpload, uploads, BLOB_CONTENT_TYPES, MAX_BLOB_BYTES } from "./blob.js";
1
2
  export { warehouse, compatibleWarehouseColumn, warehouseColumnType, validateWarehouseSource, } from "./source.js";
2
3
  export { m } from "./measure.js";
3
4
  export { action, isAction } from "./action.js";
@@ -33,5 +34,9 @@ export { deployedConnections, LocalConnectionContextError, localConnections, OID
33
34
  export { configFromEnv, ENVIRONMENT_VARIABLES, NEON_AUTH_ENVIRONMENT_VARIABLES, OntologyServiceConfigError, } from "./service/config.js";
34
35
  export { NotInvited, OntologyBackend } from "./service/runtime-contract.js";
35
36
  export { createOntologyService, ONTOLOGY_HASH_HEADER, REQUEST_ID_HEADER, } from "./service/service.js";
37
+ // The MCP server the service serves beside the HTTP API.
38
+ export { MCP_PATH, MCP_PROTOCOL_VERSIONS } from "./service/mcp/server.js";
39
+ export { MCP_TOOL_NAME_MAX_LENGTH, mcpToolName } from "./names.js";
36
40
  // Migrations: the planner, the applier and the physical mapping they share with the runtime.
37
- export { applyMigration, CatalogInvalid, CatalogMismatch, isNoopMigration, migrate, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationFailed, MigrationPlan, MigrationRefusal, MigrationRefused, MigrationStep, OntologyStorage, planMigration, readCatalog, } from "./migrate/index.js";
41
+ export { applyMigration, CatalogInvalid, CatalogMismatch, isNoopMigration, migrate, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationFailed, MigrationPlan, MigrationRefusal, MigrationRefused, MigrationStep, OntologyStorage, planMigration, readCatalog, readRuntimeTables, } from "./migrate/index.js";
42
+ export { runBlobStorageMaintenance } from "./storage/operator.js";