Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# CODEOWNERS file for managing repository permissions
# Format: path-pattern @username @org/team-name

# Maintainers: Default owners for all files
* @roostorg/roosters

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Restart the COOP server so it loads the plugin.
This package implements the COOP plugin contract from `@roostorg/types`:

- **Default export:** `CoopIntegrationPlugin` with `manifest` and `createSignals(context)`.
- **Manifest:** `id`, `name`, `version`, `requiresConfig`, `configurationFields`, `signalTypeIds`, `modelCard` (with required sections `modelDetails` and `technicalIntegration`).
- **Manifest:** `id`, `name`, `version`, `requiresConfig`, `configurationFields`, `signalTypeIds`, `modelCard` (must include every section id in `REQUIRED_MODEL_CARD_SECTION_IDS` from `@roostorg/types`; call `assertModelCardHasRequiredSections(modelCard)` when registering).
- **createSignals:** Returns two descriptors:
- `RANDOM_SIGNAL_SELECTION`: `run(input)` uses `context.getCredential(orgId)` for true percentage; returns `{ outputType: { scalarType: 'BOOLEAN' }, score: boolean }`.
- `RANDOM_SCORE`: `run()` returns `{ outputType: { scalarType: 'NUMBER' }, score: number }` in [0, 1]; no config. Threshold is set in the rule (above/below).
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@roostorg/coop-integration-example",
"version": "1.0.0",
"version": "2.0.0",
"description": "Example package to show how a custom integration and signal can be used in COOP this is meant to be a reference repository and provide basic determination",
"type": "module",
"main": "dist/index.js",
Expand Down Expand Up @@ -33,10 +33,10 @@
},
"homepage": "https://github.com/roostorg/coop-integration-example#readme",
"peerDependencies": {
"@roostorg/types": ">=1.0.0"
"@roostorg/types": ">=2.0.0"
},
"devDependencies": {
"@roostorg/types": "^1.1.1",
"@roostorg/types": "^2.0.0",
"typescript": "^5.0.0"
},
"engines": {
Expand Down
97 changes: 77 additions & 20 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
* 2. Random Score – numeric [0, 1], threshold set in the rule (tests score vs threshold).
*/

import type {
CoopIntegrationPlugin,
IntegrationManifest,
ModelCard,
PluginSignalContext,
PluginSignalDescriptor,
import {
assertModelCardHasRequiredSections,
type CoopIntegrationPlugin,
type IntegrationManifest,
type ModelCard,
type PluginSignalContext,
type PluginSignalDescriptor,
} from '@roostorg/types';

const SIGNAL_TYPE_RANDOM_SELECTION = 'RANDOM_SIGNAL_SELECTION';
Expand All @@ -20,48 +21,104 @@ const DEFAULT_TRUE_PERCENTAGE = 50;
const modelCard: ModelCard = {
modelName: 'COOP Integration Example',
version: '1.0.0',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a lot of versions here - making sure this is the version of the model card for this integration.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And that it is OK to be 1.0.0 even though the types package has moved to 2.0.0. I think this is fine, would like your eyes on that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually updated all to 2.0 as this package was upgraded to 2.0 given types also changed,

releaseDate: '2026',
releaseDate: 'March 2026',
sections: [
{
id: 'modelDetails',
title: 'Model Details',
id: 'trainingData',
title: 'Training Data',
fields: [
{ label: 'Model Name', value: 'COOP Integration Example' },
{
label: 'Purpose',
label: 'Overview',
value:
'Example plugin with two signals: one uses org config (boolean), one returns a numeric score so you can set a threshold in the rule (over/under).',
'This reference integration does not use a trained model. Outputs are randomly generated for demonstration and testing of COOP rules, configuration, and UI only.',
},
],
},
{
id: 'policyAndTaxonomy',
title: 'Policy and Taxonomy',
fields: [
{
label: 'Scope',
value:
'Not a content policy engine. Signals are placeholders: boolean “coin flip” with configurable probability and a numeric random score for threshold exercises in rules.',
},
],
},
{
id: 'annotationMethodology',
title: 'Annotation Methodology',
fields: [
{
label: 'Method',
value:
'No human or automated labeling pipeline. Values are produced with Math.random() (or equivalent logic) at evaluation time.',
},
],
},
{
id: 'performanceBenchmarks',
title: 'Performance and Benchmarks',
fields: [
{
label: 'Benchmarks',
value:
'No precision, recall, or latency benchmarks apply. Do not use performance claims from this package in production decisions.',
},
],
},
{
id: 'biasAndLimitations',
title: 'Bias and Limitations',
fields: [
{
label: 'Limitations',
value:
'Outputs are uncorrelated with input content. Unsuitable for safety, compliance, or moderation decisions. For integration testing and developer learning only.',
},
],
},
{
id: 'implementationGuidance',
title: 'Implementation Guidance',
fields: [
{
label: 'Signals',
value: `${SIGNAL_TYPE_RANDOM_SELECTION} (boolean, config-driven) and ${SIGNAL_TYPE_RANDOM_SCORE} (number 0–1, threshold in rule).`,
value: `${SIGNAL_TYPE_RANDOM_SELECTION} (boolean; org config truePercentage 0–100). ${SIGNAL_TYPE_RANDOM_SCORE} (number; set threshold and above/below in the rule).`,
},
{
label: 'Configuration',
value:
'Random Signal Selection requires org integration config (true percentage). Random Score requires no integration config.',
},
],
},
{
id: 'technicalIntegration',
title: 'Technical Integration',
id: 'relevantLinks',
title: 'Relevant Links',
fields: [
{
label: 'Signal types',
value: `${SIGNAL_TYPE_RANDOM_SELECTION}, ${SIGNAL_TYPE_RANDOM_SCORE}`,
label: 'Repository',
value: 'https://github.com/roostorg/coop-integration-example',
},
{
label: 'Config',
value: 'truePercentage (0–100) for Random Signal Selection only; Random Score needs no config.',
label: 'Documentation',
value: 'https://roostorg.github.io/coop/INTEGRATIONS_PLUGIN.html',
},
],
},
],
};

assertModelCardHasRequiredSections(modelCard);

const manifest: IntegrationManifest = {
id: INTEGRATION_ID,
name: 'COOP Integration Example',
version: '1.0.0',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, re version numbers

description:
'Example plugin with two signals: config-driven boolean and a numeric score you compare with a threshold in the rule.',
docsUrl: 'https://github.com/roostorg/coop/tree/main/coop-integration-example',
docsUrl: 'https://roostorg.github.io/coop/INTEGRATIONS_PLUGIN.html',
requiresConfig: true,
configurationFields: [
{
Expand Down
Loading