C3 AI Documentation Home

Platform Types in the C3 AI Type System

The C3 AI Type System provides a structured means of defining and categorizing data models within the C3 Agentic AI Platform. This topic examines various Types in this system, some of which are in-built and referred to as Platform Types. These Platform Types offer a standardized model across different technologies and serve as a foundation to create high-level services. Developers have the flexibility to define their own Types.

Types

Each Type is declared in its own file. The file name is the same as the base name of the Type and includes the .c3typ file type extension. For the complete syntax, see Syntax of the type file.

Below are some categories of Platform Types that are essential to the C3 Agentic AI Platform.

Persistable Types

The C3 AI Type System enables you to automatically store and retrieve data. Persistable is the base Type for all Types that support data persistence in either a relational or key/value data store. Unless database annotations are provided, any Persistable Type is stored in a relational database. This base Type contains all the system fields and base functions relevant to persisting and retrieving data.

Using the keyword entity indicates that a Type is a Persistable Type. Doing so is the same as mixing-in a Persistable Type and is easier for other developers to read.

Type
entity type LightBulb

After a Type is defined as an entity Type, thus inheriting Persistable Type metadata, you can use data manipulation methods defined on Persistable.

Metadata Types

Metadata Types represent the structure of application logic.

The example below is the Type definition for SimpleMetric, which is a Metadata Type.

Type
entity type SimpleMetric mixes Metadata, Metric schema name 'METRIC_SMTRC' 

SeedData Types

SeedData Types represent information that you can update to customize your application. You can use SeedData Types to set up a default configuration that users can update.

Types that mix-in SeedData can be further configured using the @seed annotation and specifying a number of arguments:

  • userUpdatable: Users can update instances of the Type if true.
  • userRemovable: Users can remove instances of the Type if true.
  • userCreatable: Users can create new instances of the Type if true.
Type
@seed(userUpdatable=true)
entity type CronJob mixes SeedData<CronJob> schema name "CRON_JOB"

See the topic on Annotations for more information on using the @seed annotation.

FeatureEvaluatable Types

To create and evaluate metrics on a Type, that Type or its base Type needs to mix-in the FeatureEvaluatable Type.

In the example below, SmartBulb mixes in FeatureEvaluatable. It is possible to get the list of metrics for this Type using the .listMetrics() method, which lists metrics that have been defined on the SmartBulb Type.

Type
entity type SmartBulb extends LightBulb mixes FeatureEvaluatable type key "SMRT_BLB"{
    // ...
}
JavaScript
// List the metrics that have been defined on SmartBulb
SmartBulb.listMetrics() 
// Evaluate a single metric on SmartBulb 
SmartBulb.evalMetric({EvalMetricSpec}) 
// Evaluate metrics on SmartBulb 
SmartBulb.evalMetrics({EvalMetricsSpec}) 
// Evaluate metrics on SmartBulb, will need to provide additional information in the spec 
SmartBulb.evalMetricsWithMetaData({EvalMetricSpec})

Canonical Types

A canonical data model is a design pattern used to translate raw source data formats into target Types. Canonicals specify how raw data is loaded and organized into field values. The C3 Agentic AI Platform enables the definition of Canonical Types that are independent from any specific application, allowing applications to communicate with one other in a common format.

A Canonical Type must be mixed with the generic Type Canonical.

Note: Only primitive value Types are allowed on fields of Canonical Types. Each value must correctly correspond to the raw data Types being loaded on the C3 Agentic AI Platform.

Type
type CanonicalSmartBulb mixes Canonical<Canonical SmartBulb> {
    Manufacturer: string
    BulbType: string
    Wattage: decimal
    SN: string
    StartDate: datetime
    Latitude: double
    Longitude: double
}

Timeseries Types

Timeseries Types define time series data. Creating a Timeseries Type is a two-step process:

  1. Model time series data
  2. Evaluate modeled data with metrics to produce time series objects.

It is also possible to evaluate data that isn't modeled as time series (for example, static data) with metrics to produce a Timeseries Type.

External Types

External Types are used to represent data that is stored outside the C3 Agentic AI Platform. External Types do not go through the data loading process for C3 AI Type actions. Instead, data access actions like fetch() and get() are performed on data stores outside the platform. External Types can be created on remote relational databases, such as PostgreSQL, Microsoft SQL Server, or Oracle.

To create an External Type, you need to mix-in External and NoSystemCols, and define the remote table name and the remote column names. Each field is mapped to one remote column.

After you have defined an External Type, you can access data from this data store as if it were any other Persistable Type.

For more detailed information about connecting to an external data source refer to the topic on Virtualization.

Define an External Type

An External Type Actor is defined below by mixing in External and NoSystemCols, and specifying a schema name, which is the name of the remote table. In this case, the name of the remote table is ACTOR.

Type
/*
 * Actor.c3typ
 */
entity type Actor mixes External, NoSystemCols schema name "ACTOR" {
    id: ~ schema name 'ACTOR_ID' 
    firstName: string schema name 'FIRST_NAME'
    lastName: string schema name 'LAST_NAME'
    fullName: string calc "concat(firstName, ' ', lastName)"
    lastUpdate: datetime no tz schema name 'LAST_UPDATE'
}

Fields such as id and firstName are associated with a column in the ACTOR table. For example, firstName is a string field and is mapped to the FIRST_NAME column.

When defining External Types, the id field must be mapped to a column in the table, or define a composite key. A composite key is when two or more columns are used to uniquely identify each row a table.

Parametric Types

Parametric Types, sometimes referred to as generic Types, are Types that allow you to define Types parameterized by other Types. Parametric Types cannot be instantiated or persisted, and are required to be mixed-in to concrete (non-generic) Types.

Parametric Types are a way of making the C3 AI system more expressive, while still maintaining full static Type safety. The arguments of Parametric Types are written generically so that Parametric Types are able to populate fields without depending on the Type of the arguments. This allows the Parametric Type to be abstract and populated with a known Type when mixed-in by the developer.

Parametric Type example

In this example, Point is a Parametric Type, as it has the unbound variable V.

Type
type Point<V> {
    x: V 
    y: V
}

The value of V must be specified in the Type definition that mixes in Point:

Type
entity type UsesParametric mixes Point<Another Type> {
    // FOR ILLUSTRATION: These two fields are inherited from Point 
    x: Another Type 
    y: Another Type

    aFieldOnUsesParametric: string
}

In the example below, RealPoint and IntPoint mix-in the generic Type Point and bind the variable in different ways.

  • RealPoint - fields are bound to double values
  • IntPoint – fields are bound to integer values

Either Type can be passed to a method that declares an argument of Type Point.

Type
type RealPoint mixes Point<double>

type IntPoint mixes Point<int>

Parametric Type advanced example

MapReduce is a generic Type that takes four parametric values — the target Type the job is defined on, the map output key, the map output value Type (also referred to as the intermediate value Type), and the reduce output value Type.

To define a map-reduce job that is used for word count on Text, you can define a WordCount Type, which extends MapReduce. When extending MapReduce,

  1. Set target Type parametric variable TargetType to OutputType.
  2. Set the map output key Type OutputKeyType as a string.
  3. Set the map output value Type InterValType as a double.
  4. Set the reduce output value Type OutValType to a double.
Type
extendable entity type MapReduce<TargetType, OutKeyType, InterValType, OutValType> mixes...

For more information on implementing WordCount and using MapReduce, see Run MapReduce Jobs.

Alerts can be created by mixing in the Analytic Type, which is a generic Type, with an input and output.

In the example below, the SmartBulbFailureAlert takes as input SmartBulbFailureInput, and returns a void.

Type
type SmartBulbFailureAlert mixes Analytic<SmartBulbFailureInput, void>
Was this page helpful?