Skip to content

feat(ontologies): add Ontologies service for UiPath knowledge graph - #622

Draft
diwakar-jha3110 wants to merge 2 commits into
mainfrom
feat/ontology-onboarding
Draft

feat(ontologies): add Ontologies service for UiPath knowledge graph #622
diwakar-jha3110 wants to merge 2 commits into
mainfrom
feat/ontology-onboarding

Conversation

@diwakar-jha3110

Copy link
Copy Markdown
Contributor

Adds OntologyService to the SDK — CRUD for ontologies and full artifact management.

What changed

  • OntologyService with 11 methods: create, getAll, getById, update, deleteById, exportOntology, upsertArtifact, uploadArtifacts, getArtifact, listArtifacts, deleteArtifact, validateArtifact
  • ArtifactType enum: schema, constraints, mapping, business-rules, summary, context, functions, actions
  • Offset pagination on getAll via existing PaginationHelpers
  • Subpath export at @uipath/uipath-typescript/ontologies
  • api-client.ts: fixed empty-body guard ordering — TEXT responseType was returning "" instead of undefined for zero-byte responses
  • Unit tests (536 assertions)
  • Integration test suite wired but skipped — waiting on the Ontology service to be provisioned on the alpha tenant

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://UiPath.github.io/uipath-typescript/pr-preview/pr-622/

Built to branch gh-pages at 2026-07-23 06:28 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

…anagement

Implements the full OntologyService covering CRUD on ontologies and
component file operations (upsert, bulk-upsert, get, list, delete,
validate). Wires up the `@uipath/uipath-typescript/ontologies` subpath
export with ESM/CJS/UMD dist output. Integration tests are skipped
pending API deployment (target mid-July 2026).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

export const ONTOLOGY_ENDPOINTS = {
GET_ALL: `${ONTOLOGY_BASE}/api/ontology`,
CREATE: `${ONTOLOGY_BASE}/api/ontology`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Convention violation: duplicate endpoint constants without justifying comments.

CREATE (line 9), UPDATE (line 11), and DELETE (line 12) share identical URL patterns with GET_ALL and GET_BY_ID respectively. Likewise inside ARTIFACT, UPLOAD_BULK duplicates GET_ALL and UPSERT/DELETE duplicate GET.

Per conventions: "Avoid creating a duplicate endpoint constant whose URL pattern is identical to an existing one. HTTP method differences (GET vs PUT) are resolved at the call site (this.get() vs this.put()), not in the constant. Either reuse the existing constant directly, or — if a distinct name genuinely aids readability — add an explicit comment explaining the intentional duplication."

Options:

  1. Collapse the duplicates and reuse the constants at the call site (this.post(ONTOLOGY_ENDPOINTS.GET_ALL, ...), this.patch(ONTOLOGY_ENDPOINTS.GET_BY_ID(id), ...)), or
  2. Keep the named aliases but add a comment on each duplicate explaining the intentional duplication (e.g., // Same URL as GET_ALL; distinct name aids readability for write operations).

All four sets of duplicates need to be addressed:

  • GET_ALL / CREATE
  • GET_BY_ID / UPDATE / DELETE
  • ARTIFACT.GET_ALL / ARTIFACT.UPLOAD_BULK
  • ARTIFACT.GET / ARTIFACT.UPSERT / ARTIFACT.DELETE

@diwakar-jha3110
diwakar-jha3110 force-pushed the feat/ontology-onboarding branch from be399d3 to 73ca849 Compare July 23, 2026 06:27
createTime?: string;
updatedBy?: string;
updateTime?: string;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Timestamp field naming doesn't match SDK convention.

createTime and updateTime (line 90) will surface as-is in the public OntologySummary type because there is no transform pipeline applied in this service. The SDK convention requires past-tense *Time names throughout: createdTime, updatedTime (or lastModifiedTime).

Fix: add an OntologyMap field-rename table and apply transformData(data, OntologyMap) in the service's response pipeline:

// src/models/ontology/ontology.constants.ts
export const OntologyMap: Record<string, string> = {
  createTime: 'createdTime',
  updateTime: 'updatedTime',
};

Then in the service:

const transformed = transformData(response.data, OntologyMap);
return createOntologyWithMethods(transformed as RawOntologySummary, this);

And update RawOntologySummary accordingly:

createdTime?: string;
updatedTime?: string;

Same fix needed for ArtifactMetadata below.

createTime?: string;
updatedBy?: string;
updateTime?: string;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same timestamp naming issue as in RawOntologySummary above. ArtifactMetadata.createTime should be createdTime and updateTime (line 105) should be updatedTime. Apply the same OntologyMap transformation (or a separate ArtifactMap) to the listArtifacts, upsertArtifact, and uploadArtifacts response paths.

Comment thread docs/oauth-scopes.md Outdated
| `getGovernanceDecisions()` | `Traces.Api Insights.RealTimeData Insights OR.Folders.Read` |
| `getGovernanceSummary()` | `Traces.Api Insights.RealTimeData Insights OR.Folders.Read` |

## Ontologies

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OntologyServiceModel is tagged @internal — this docs section should be omitted.

Per conventions: "methods tagged @internal in their JSDoc do not get an OAuth scope entry — they are not part of the public API surface and do not appear in the OAuth integration guide. Similarly, mkdocs.yml nav entries and docs site pages are not needed for services where every public-facing method is tagged @internal."

Since OntologyServiceModel carries @internal, this entire section should be removed. The same applies to the mkdocs.yml nav entry (- Ontologies: api/interfaces/OntologyServiceModel.md) and the docs/pagination.md row — both should also be reverted. Re-add them all once the service graduates to public.

async upsertArtifact(idOrName: string, fileName: string, request: ArtifactUpsertRequest): Promise<ArtifactMetadata> {
if (!request.mediaType) {
throw new Error(`upsertArtifact: --media-type is required (e.g. 'text/owl-functional', 'text/turtle')`);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two issues here (and at the parallel check in validateArtifact line ~152):

  1. Wrong error type. Convention says "ValidationError — for user input validation only: missing required params, invalid option values, malformed user-provided data." Use ValidationError, not raw Error:

    throw new ValidationError({ message: 'upsertArtifact: mediaType is required' });
  2. Avoid SDK-side duplication of backend validation. Convention: "Do not duplicate backend validation SDK-side — when an API parameter has backend-enforced constraints, document the constraint in JSDoc rather than adding matching SDK-side validation." The backend will already return a 400 for a missing or empty Content-Type. This guard is redundant. Remove both if (!request.mediaType) blocks and instead document the constraint in the JSDoc @param for request.

  3. CLI-style flag syntax in an SDK error message. --media-type is a CLI flag; in a TypeScript SDK the error should reference the parameter name as it appears in code: mediaType, not --media-type.


// skip: Ontology service is not yet provisioned on the alpha tenant.
// Tests are wired and ready — remove describe.skip once the service is enabled on appsdev/appsdevDefault.
describe.skip('Ontology Service — Integration Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

describe.skip is not permitted here per conventions.

Convention: "describe.skip is permitted only when the service does not support PAT auth. In this case, write the full test body as if it will eventually run, add a comment explaining the limitation, and use describe.skip rather than omitting the test entirely."

"Not yet provisioned on the alpha tenant" is an infrastructure gap, not a PAT auth restriction. For infrastructure gaps, the convention says to use beforeAll + throw so the test suite fails visibly in CI (rather than silently being skipped):

describe('Ontology Service — Integration Tests', () => {
  let service: OntologyService;

  beforeAll(() => {
    const svc = getServices().ontologies;
    if (!svc) throw new Error('Ontology service not provisioned on this tenant — enable it before running these tests');
    service = svc;
  });
  // ...

This way the test is tracked as a real failure when the tenant lacks the service, rather than silently passing.

Comment thread src/services/index.ts
export * from './orchestrator';
export * from './action-center';
export * from './ontology';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

New services must not be added to the top-level services barrel.

Convention: "New services must be modularized only — export only via subpath (@uipath/uipath-typescript/ontologies), no top-level barrel export needed."

If src/index.ts re-exports src/services/index.ts (which is the typical pattern for the existing services listed here), adding export * from './ontology' here would expose OntologyService and all its types in the top-level @uipath/uipath-typescript bundle — contrary to the modular-only requirement for new services. Remove this line; the subpath export in package.json and rollup.config.js is sufficient.

@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review findings — 7 issues

Blocking

  1. Duplicate endpoint constantsCREATE, UPDATE, DELETE, ARTIFACT.UPLOAD_BULK, ARTIFACT.UPSERT, and ARTIFACT.DELETE all duplicate an existing constant's URL pattern with no justifying comment. Either reuse the existing constant at the call site or add an explicit duplication comment. (endpoints/ontology.ts:9)

  2. Timestamp namingcreateTime/updateTime surface directly in the public type without any transform. SDK convention requires createdTime/updatedTime. Needs an OntologyMap + transformData pass on both RawOntologySummary and ArtifactMetadata. (types:88, types:103)

  3. @internal service but docs are addedOntologyServiceModel is tagged @internal, so the OAuth scopes section, the mkdocs.yml nav entry, and the pagination.md row should all be omitted until the service goes public. (oauth-scopes.md:276)

  4. Top-level barrel for a new service — New services must be modular-only (subpath export). Adding to src/services/index.ts likely re-exposes the service in the top-level bundle. (services/index.ts:7)

Should fix

  1. Wrong error type + redundant validationnew Error should be ValidationError; SDK-side mediaType guard duplicates backend validation (remove it); error message uses CLI-style --media-type flag syntax. (ontology.ts:118)

  2. describe.skip for wrong reasondescribe.skip is reserved for PAT-auth-incompatible services. "Not provisioned on alpha tenant" should use beforeAll + throw so CI fails visibly. (integration.test.ts:9)

Comment on lines +21 to +22
ARTIFACT_TYPE_SCHEMA: 'schema',
ARTIFACT_TYPE_CONSTRAINTS: 'constraints',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Unused dead constants — remove per code hygiene convention.

ARTIFACT_TYPE_SCHEMA: 'schema' and ARTIFACT_TYPE_CONSTRAINTS: 'constraints' are never referenced in any test file. Every test that checks artifact types uses the enum directly (ArtifactType.Schema, ArtifactType.Constraints). These raw-string constants also violate the convention "Use enums for fixed value sets — NEVER leave raw strings/numbers".

Per conventions: "NEVER leave unused code — unused imports, variables, redundant constructors."

Suggested change
ARTIFACT_TYPE_SCHEMA: 'schema',
ARTIFACT_TYPE_CONSTRAINTS: 'constraints',

Simply delete both lines. Tests already use the ArtifactType enum values directly.

import { PaginationType } from '../../utils/pagination/internal-types';
import { BaseService } from '../base';

export class OntologyService extends BaseService implements OntologyServiceModel {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Missing @internal propagation on the service class.

OntologyServiceModel carries /** @internal */, but the OntologyService class itself has no JSDoc at all. Per conventions:

"Propagate @internal and @experimental to every public layer that exposes the same API — if an underlying service method is tagged @internal, the corresponding wrapper on the UiPath class (or any other public-facing class) must also carry the same tag. TypeDoc runs directly on public class methods; a missing tag on one layer surfaces the method in generated docs even if the service layer correctly marks it."

Add a JSDoc block to the class:

Suggested change
export class OntologyService extends BaseService implements OntologyServiceModel {
/** @internal */
export class OntologyService extends BaseService implements OntologyServiceModel {

The same tag should be propagated to the Ontologies export alias in src/services/ontology/index.ts once all three fixes (this, the docs cleanup in thread on docs/oauth-scopes.md, and the barrel removal in the thread on src/services/index.ts) are applied together.

@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Two new findings this run (in addition to the 7 open threads already on this PR):

  1. dead constantsARTIFACT_TYPE_SCHEMA and ARTIFACT_TYPE_CONSTRAINTS in tests/utils/constants/ontology.ts are never referenced anywhere. They duplicate enum values already used directly in tests. Delete both lines.

  2. missing @internal on classOntologyService in src/services/ontology/ontology.ts has no JSDoc at all. OntologyServiceModel is tagged @internal; the convention requires propagating that tag to every public layer. Add /** @internal */ above the class declaration.

@vnaren23

Copy link
Copy Markdown
Collaborator

@diwakar-jha3110 My understanding is Ontology is far from preview, why do we want to add it to SDK now itself? If this is meant to just be for testing, lets just for the have a branch and push a dev package into GitHub feed.

@diwakar-jha3110
diwakar-jha3110 marked this pull request as draft July 30, 2026 09:19
await expect(svc.getById(ontology.id)).rejects.toThrow();
});
});
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

exportOntology has no integration test.

Convention: "Every new method must also have an integration test in tests/integration/shared/{domain}/."

All 11 other service methods have an integration test block, but exportOntology is missing entirely. Add a describe('exportOntology', ...) block alongside the others — even while the suite is skipped, it should be written as if it will run:

describe('exportOntology', () => {
  it('should export the ontology as a zip archive', async () => {
    const svc = getService();
    const ontology = await svc.create('export-test', { displayName: 'Export Test' });
    createdIds.push(ontology.id);

    const zip = await svc.exportOntology(ontology.id);

    expect(zip).toBeInstanceOf(Uint8Array);
    expect(zip.length).toBeGreaterThan(0);
    // ZIP local file header magic: PK\x03\x04
    expect(zip[0]).toBe(0x50);
    expect(zip[1]).toBe(0x4b);
  });
});

@claude

claude Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

One new finding this run (in addition to the 9 open threads already on this PR):

Missing exportOntology integration test — All 11 other service methods have an integration test block; exportOntology is absent entirely. Convention requires every new method to have an integration test. (integration.test.ts:147)

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants