A worked example for Epic #11624: a non-Neo workspace whose .proto schema files are
indexed into the Knowledge Base. It demonstrates both ingestion paths with one custom
class each. See the cloud-deployment/ guide tree.
| Path | Role |
|---|---|
package.json |
Declares neo.mjs as a dependency — the external-workspace shape (npx neo app-style). |
proto/example.proto |
Sample content — a Protobuf schema with two messages and a service. |
src/ProtoParser.mjs |
Custom Parser — parseIngestionFile() turns a .proto file into parsed-chunk-v1 records (the push path). See Custom Parsers. |
src/ProtoSource.mjs |
Custom Source — extract() indexes the proto/ tree in the full-corpus build. See Custom Sources. |
A KB deployment registers them through its aiConfig (see Configuration) — in config.mjs:
import ProtoParser from './src/ProtoParser.mjs';
import ProtoSource from './src/ProtoSource.mjs';
customParsers : [{ParserClass: ProtoParser, parserId: 'proto'}],
customSources : [{SourceClass: ProtoSource, sourceName: 'ProtoSource'}],
sourcePaths : {ProtoSource: '<absolute path to this workspace>/proto'}…or programmatically — SourceRegistry.registerParser(ProtoParser, {parserId: 'proto'})
and SourceRegistry.registerSource(ProtoSource, {sourceName: 'ProtoSource'}).
Push proto/example.proto through the bulk facade. With no parserId on the record,
KnowledgeBaseIngestionService.resolveFileChunks applies its raw-text fallback — the
file ingests as a single whole-file chunk; no server-side registration is needed:
npm install
node -e 'const fs=require("fs");process.stdout.write(JSON.stringify({sourcePath:"proto/example.proto",content:fs.readFileSync("proto/example.proto","utf8")})+"\n")' \
| node node_modules/neo.mjs/buildScripts/ai/ingestTenant.mjs example-tenant --from-stdinA successful run prints a JSON summary — {ingested, embeddingsGenerated, deleted, ...},
and the chunk is scoped to the example-tenant tenant.
To chunk per protobuf message instead, register ProtoParser (see above) and add
parserId: "proto" to the record — resolveFileChunks then dispatches to it rather
than the raw-text fallback:
node -e 'const fs=require("fs");process.stdout.write(JSON.stringify({sourcePath:"proto/example.proto",content:fs.readFileSync("proto/example.proto","utf8"),parserId:"proto"})+"\n")' \
| node node_modules/neo.mjs/buildScripts/ai/ingestTenant.mjs example-tenant --from-stdin