@roostorg/types 1.1.0 → 2.0.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@roostorg/types",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "2.0.0",
5
5
  "description": "Shared types across Coop services",
6
6
  "module": "transpiled/index.js",
7
7
  "typings": "./transpiled/index.d.ts",
@@ -10,6 +10,11 @@
10
10
  "prepublishOnly": "npm run build",
11
11
  "test": "npm run build && node --test transpiled/test_scripts/"
12
12
  },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/roostorg/coop",
16
+ "directory": "types"
17
+ },
13
18
  "author": "Roostorg",
14
19
  "files": [
15
20
  "transpiled"
@@ -190,5 +190,5 @@ export declare const ItemTypeKind: {
190
190
  USER: "USER";
191
191
  };
192
192
  export type ItemTypeKind = keyof typeof ItemTypeKind;
193
- export type { CoopIntegrationConfigEntry, CoopIntegrationPlugin, CoopIntegrationsConfig, IntegrationCredentialField, IntegrationId, IntegrationManifest, ModelCard, ModelCardField, ModelCardSection, ModelCardSubsection, StoredIntegrationConfigPayload, } from './integration.js';
193
+ export type { CoopIntegrationConfigEntry, CoopIntegrationPlugin, CoopIntegrationsConfig, IntegrationConfigField, IntegrationId, IntegrationManifest, ModelCard, ModelCardField, ModelCardSection, ModelCardSubsection, PluginSignalContext, PluginSignalDescriptor, StoredIntegrationConfigPayload, } from './integration.js';
194
194
  export { assertModelCardHasRequiredSections, isCoopIntegrationPlugin, REQUIRED_MODEL_CARD_SECTION_IDS, } from './integration.js';
@@ -31,7 +31,7 @@ export type ModelCardSubsection = Readonly<{
31
31
  * Either subsections (with bold sub-headings) or top-level fields, or both.
32
32
  */
33
33
  export type ModelCardSection = Readonly<{
34
- /** Stable id for the section (e.g. "modelDetails", "trainingData"). */
34
+ /** Stable id for the section (e.g. "trainingData", "biasAndLimitations"). */
35
35
  id: string;
36
36
  /** Display title (e.g. "Model Details"). */
37
37
  title: string;
@@ -62,19 +62,19 @@ export type ModelCard = Readonly<{
62
62
  * Section ids that every integration's model card must include.
63
63
  * Use assertModelCardHasRequiredSections() to validate at runtime.
64
64
  */
65
- export declare const REQUIRED_MODEL_CARD_SECTION_IDS: readonly ["modelDetails", "technicalIntegration"];
65
+ export declare const REQUIRED_MODEL_CARD_SECTION_IDS: readonly ["trainingData", "policyAndTaxonomy", "annotationMethodology", "performanceBenchmarks", "biasAndLimitations", "implementationGuidance", "relevantLinks"];
66
66
  /**
67
- * Asserts that a model card has at least the required sections (basic information
68
- * and technical integration). Call when registering integration manifests.
67
+ * Asserts that a model card has at least the required sections.
68
+ * Call when registering integration manifests.
69
69
  * @throws Error if any required section id is missing
70
70
  */
71
71
  export declare function assertModelCardHasRequiredSections(card: ModelCard): void;
72
72
  /**
73
- * Describes a single credential field for integrations that require
74
- * API keys or other secrets. Used to generate or validate credential forms.
73
+ * Describes a single configuration field for integrations that require
74
+ * user-supplied config (e.g. API keys or other settings). Used to generate or validate config forms.
75
75
  */
76
- export type IntegrationCredentialField = Readonly<{
77
- /** Form field key (e.g. "apiKey", "labelerVersions"). */
76
+ export type IntegrationConfigField = Readonly<{
77
+ /** Form field key (e.g. "apiKey", "truePercentage"). */
78
78
  key: string;
79
79
  /** Human-readable label for the field. */
80
80
  label: string;
@@ -94,7 +94,7 @@ export type IntegrationCredentialField = Readonly<{
94
94
  export type IntegrationManifest = Readonly<{
95
95
  /** Unique integration id. Must be UPPER_SNAKE_CASE to align with GraphQL enums when used in COOP. */
96
96
  id: IntegrationId;
97
- /** Human-readable display name (e.g. "Google Content Safety API"). */
97
+ /** Human-readable display name shown in the UI (e.g. signal modal, integration cards). Exposed as Signal.integrationTitle. */
98
98
  name: string;
99
99
  /** Semantic version of the integration plugin (e.g. "1.0.0"). */
100
100
  version: string;
@@ -102,17 +102,13 @@ export type IntegrationManifest = Readonly<{
102
102
  description?: string;
103
103
  /** Link to documentation or product page. */
104
104
  docsUrl?: string;
105
- /** Optional URL to a logo image (or asset key if using a bundler). */
106
- logoUrl?: string;
107
- /** Optional URL to a logo variant (e.g. with background) for cards. */
108
- logoWithBackgroundUrl?: string;
109
- /** Whether this integration requires the user to supply credentials (e.g. API key). */
110
- requiresCredentials: boolean;
105
+ /** Whether this integration requires the user to supply config (e.g. API key). */
106
+ requiresConfig: boolean;
111
107
  /**
112
- * Schema for credential fields when requiresCredentials is true.
108
+ * Schema for configuration fields when requiresConfig is true.
113
109
  * Enables UI generation and validation without hardcoding per-integration forms.
114
110
  */
115
- credentialFields?: readonly IntegrationCredentialField[];
111
+ configurationFields?: readonly IntegrationConfigField[];
116
112
  /**
117
113
  * Optional list of signal type ids this integration provides (e.g. "ZENTROPI_LABELER").
118
114
  * Used by the platform to associate signals with this integration for display and gating.
@@ -120,12 +116,82 @@ export type IntegrationManifest = Readonly<{
120
116
  signalTypeIds?: readonly string[];
121
117
  /**
122
118
  * Model card: structured metadata (model name, version, sections) for the UI.
123
- * When present, the integration detail page renders it. Built-in integrations
124
- * should always provide a model card with at least sections "modelDetails" and
125
- * "technicalIntegration"; use assertModelCardHasRequiredSections() when
126
- * registering.
119
+ * When present, the integration detail page renders it. Integrations must
120
+ * include all sections listed in REQUIRED_MODEL_CARD_SECTION_IDS; use
121
+ * assertModelCardHasRequiredSections() when registering.
127
122
  */
128
123
  modelCard?: ModelCard;
124
+ /**
125
+ * ------------------------------------------------------------
126
+ * LOGO/IMAGE SECTION:
127
+ * ------------------------------------------------------------
128
+ * The following logo/image sections are optional. If none provided will use a fallback Coop logo.
129
+ *
130
+ * Provide either logoUrl and logoWithBackgroundUrl or logoPath and logoWithBackgroundPath.
131
+ *
132
+ * If you provide logoPath and logoWithBackgroundPath, the server will serve the files at
133
+ * GET /api/v1/integration-logos/:integrationId and GET /api/v1/integration-logos/:integrationId/with-background
134
+ * and set logoUrl and logoWithBackgroundUrl accordingly.
135
+ * Usage: logoUrl/logoPath = plain logo (no background), used on the integrations page;
136
+ * logoWithBackgroundUrl/logoWithBackgroundPath = logo with background, used in signal modals.
137
+ * If you provide logoUrl and logoWithBackgroundUrl, the server will use those URLs directly.
138
+ * Prefered size: ~180x180px for logoUrl and ~120x120px for logoWithBackgroundUrl.
139
+ * Prefer a square or horizontal logo that scales well.
140
+ */
141
+ logoUrl?: string;
142
+ logoWithBackgroundUrl?: string;
143
+ logoPath?: string;
144
+ logoWithBackgroundPath?: string;
145
+ }>;
146
+ /** Context passed to plugin.createSignals() so the plugin can build signal instances with credential access. */
147
+ export type PluginSignalContext = Readonly<{
148
+ /** Integration id (e.g. "ACME_API") from the plugin manifest. */
149
+ integrationId: string;
150
+ /** Get stored credential/config for an org. Resolves to the JSON stored for this integration. */
151
+ getCredential: (orgId: string) => Promise<Record<string, unknown>>;
152
+ }>;
153
+ /** Minimal signal descriptor returned by a plugin. The platform adapts this to its internal SignalBase. */
154
+ export type PluginSignalDescriptor = Readonly<{
155
+ /** Stable signal type id (e.g. "ACME_MODERATION_SIGNAL"). Must match one of manifest.signalTypeIds. */
156
+ id: Readonly<{
157
+ type: string;
158
+ }>;
159
+ displayName: string;
160
+ description: string;
161
+ docsUrl: string | null;
162
+ recommendedThresholds: Readonly<{
163
+ highPrecisionThreshold: string | number;
164
+ highRecallThreshold: string | number;
165
+ }> | null;
166
+ supportedLanguages: readonly string[] | 'ALL';
167
+ pricingStructure: Readonly<{
168
+ type: 'FREE' | 'SUBSCRIPTION';
169
+ }>;
170
+ eligibleInputs: readonly string[];
171
+ outputType: Readonly<{
172
+ scalarType: string;
173
+ }>;
174
+ getCost: () => number;
175
+ /** Run the signal. Input shape is platform-defined; result must have outputType and score. */
176
+ run: (input: unknown) => Promise<unknown>;
177
+ getDisabledInfo: (orgId: string) => Promise<{
178
+ disabled: false;
179
+ disabledMessage?: string;
180
+ } | {
181
+ disabled: true;
182
+ disabledMessage: string;
183
+ }>;
184
+ needsMatchingValues: boolean;
185
+ eligibleSubcategories: ReadonlyArray<{
186
+ id: string;
187
+ label: string;
188
+ description?: string;
189
+ childrenIds: readonly string[];
190
+ }>;
191
+ needsActionPenalties: boolean;
192
+ /** Integration id (same as context.integrationId). */
193
+ integration: string;
194
+ allowedInAutomatedRules: boolean;
129
195
  }>;
130
196
  /**
131
197
  * Plugin contract that third-party integration packages must implement.
@@ -136,6 +202,9 @@ export type IntegrationManifest = Readonly<{
136
202
  * const manifest: IntegrationManifest = { id: 'ACME_API', name: 'Acme API', ... };
137
203
  * const plugin: CoopIntegrationPlugin = { manifest };
138
204
  * export default plugin;
205
+ *
206
+ * To power routing/enforcement rules, also implement createSignals(context) and
207
+ * return one descriptor per manifest.signalTypeIds entry.
139
208
  */
140
209
  export type CoopIntegrationPlugin = Readonly<{
141
210
  manifest: IntegrationManifest;
@@ -144,6 +213,15 @@ export type CoopIntegrationPlugin = Readonly<{
144
213
  * If present, adopters can pass non-secret config in the integrations config file.
145
214
  */
146
215
  configSchema?: unknown;
216
+ /**
217
+ * Optional. If this integration provides signals for use in rules, implement this.
218
+ * Return one descriptor per signal type id listed in manifest.signalTypeIds.
219
+ * The platform will register these so they appear in the rule builder and can be used in conditions.
220
+ */
221
+ createSignals?: (context: PluginSignalContext) => ReadonlyArray<Readonly<{
222
+ signalTypeId: string;
223
+ signal: PluginSignalDescriptor;
224
+ }>>;
147
225
  }>;
148
226
  /**
149
227
  * Single entry in the adopters' integrations config file.
@@ -177,7 +255,7 @@ export type CoopIntegrationsConfig = Readonly<{
177
255
  * Shape of the config stored in the database for each integration (per org).
178
256
  * Stored in a generic table as JSON: one row per (org_id, integration_id) with
179
257
  * config as a JSON-serializable object. Each integration defines its own required
180
- * fields via IntegrationManifest.credentialFields; the app validates and
258
+ * fields via IntegrationManifest.configurationFields; the app validates and
181
259
  * serializes/deserializes to this type.
182
260
  *
183
261
  * Only JSON-serializable values (no functions, symbols, or BigInt) should be
@@ -13,20 +13,24 @@
13
13
  * Use assertModelCardHasRequiredSections() to validate at runtime.
14
14
  */
15
15
  export const REQUIRED_MODEL_CARD_SECTION_IDS = [
16
- 'modelDetails',
17
- 'technicalIntegration',
16
+ 'trainingData',
17
+ 'policyAndTaxonomy',
18
+ 'annotationMethodology',
19
+ 'performanceBenchmarks',
20
+ 'biasAndLimitations',
21
+ 'implementationGuidance',
22
+ 'relevantLinks',
18
23
  ];
19
24
  /**
20
- * Asserts that a model card has at least the required sections (basic information
21
- * and technical integration). Call when registering integration manifests.
25
+ * Asserts that a model card has at least the required sections.
26
+ * Call when registering integration manifests.
22
27
  * @throws Error if any required section id is missing
23
28
  */
24
29
  export function assertModelCardHasRequiredSections(card) {
25
30
  const sectionIds = new Set((card.sections ?? []).map((s) => s.id));
26
- for (const requiredId of REQUIRED_MODEL_CARD_SECTION_IDS) {
27
- if (!sectionIds.has(requiredId)) {
28
- throw new Error(`Model card must include a section with id "${requiredId}" (e.g. Basic Information / Model Details and Technical Integration).`);
29
- }
31
+ const missing = REQUIRED_MODEL_CARD_SECTION_IDS.filter((id) => !sectionIds.has(id));
32
+ if (missing.length > 0) {
33
+ throw new Error(`Model card is missing required section(s): ${missing.map((id) => `"${id}"`).join(', ')}.`);
30
34
  }
31
35
  }
32
36
  /**
@@ -44,5 +48,5 @@ export function isCoopIntegrationPlugin(value) {
44
48
  return (typeof m.id === 'string' &&
45
49
  typeof m.name === 'string' &&
46
50
  typeof m.version === 'string' &&
47
- typeof m.requiresCredentials === 'boolean');
51
+ typeof m.requiresConfig === 'boolean');
48
52
  }