@api-client/core 0.19.1 → 0.19.2
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/build/src/mocking/ModelingMock.d.ts +2 -0
- package/build/src/mocking/ModelingMock.d.ts.map +1 -1
- package/build/src/mocking/ModelingMock.js +2 -0
- package/build/src/mocking/ModelingMock.js.map +1 -1
- package/build/src/mocking/lib/Ai.d.ts +11 -0
- package/build/src/mocking/lib/Ai.d.ts.map +1 -0
- package/build/src/mocking/lib/Ai.js +53 -0
- package/build/src/mocking/lib/Ai.js.map +1 -0
- package/build/src/modeling/ai/DataDomainDelta.d.ts +146 -0
- package/build/src/modeling/ai/DataDomainDelta.d.ts.map +1 -0
- package/build/src/modeling/ai/DataDomainDelta.js +729 -0
- package/build/src/modeling/ai/DataDomainDelta.js.map +1 -0
- package/build/src/modeling/ai/DomainSerialization.d.ts +20 -0
- package/build/src/modeling/ai/DomainSerialization.d.ts.map +1 -0
- package/build/src/modeling/ai/DomainSerialization.js +185 -0
- package/build/src/modeling/ai/DomainSerialization.js.map +1 -0
- package/build/src/modeling/ai/domain_response_schema.d.ts +806 -0
- package/build/src/modeling/ai/domain_response_schema.d.ts.map +1 -0
- package/build/src/modeling/ai/domain_response_schema.js +289 -0
- package/build/src/modeling/ai/domain_response_schema.js.map +1 -0
- package/build/src/modeling/ai/domain_tools.d.ts +68 -0
- package/build/src/modeling/ai/domain_tools.d.ts.map +1 -0
- package/build/src/modeling/ai/domain_tools.js +71 -0
- package/build/src/modeling/ai/domain_tools.js.map +1 -0
- package/build/src/modeling/ai/index.d.ts +10 -0
- package/build/src/modeling/ai/index.d.ts.map +1 -0
- package/build/src/modeling/ai/index.js +9 -0
- package/build/src/modeling/ai/index.js.map +1 -0
- package/build/src/modeling/ai/message_parser.d.ts +23 -0
- package/build/src/modeling/ai/message_parser.d.ts.map +1 -0
- package/build/src/modeling/ai/message_parser.js +93 -0
- package/build/src/modeling/ai/message_parser.js.map +1 -0
- package/build/src/modeling/ai/prompts/domain_system.d.ts +6 -0
- package/build/src/modeling/ai/prompts/domain_system.d.ts.map +1 -0
- package/build/src/modeling/ai/prompts/domain_system.js +80 -0
- package/build/src/modeling/ai/prompts/domain_system.js.map +1 -0
- package/build/src/modeling/ai/tools/DataDomain.tools.d.ts +25 -0
- package/build/src/modeling/ai/tools/DataDomain.tools.d.ts.map +1 -0
- package/build/src/modeling/ai/tools/DataDomain.tools.js +334 -0
- package/build/src/modeling/ai/tools/DataDomain.tools.js.map +1 -0
- package/build/src/modeling/ai/tools/Semantic.tools.d.ts +48 -0
- package/build/src/modeling/ai/tools/Semantic.tools.d.ts.map +1 -0
- package/build/src/modeling/ai/tools/Semantic.tools.js +36 -0
- package/build/src/modeling/ai/tools/Semantic.tools.js.map +1 -0
- package/build/src/modeling/ai/tools/config.d.ts +13 -0
- package/build/src/modeling/ai/tools/config.d.ts.map +1 -0
- package/build/src/modeling/ai/tools/config.js +2 -0
- package/build/src/modeling/ai/tools/config.js.map +1 -0
- package/build/src/modeling/ai/types.d.ts +302 -0
- package/build/src/modeling/ai/types.d.ts.map +1 -0
- package/build/src/modeling/ai/types.js +40 -0
- package/build/src/modeling/ai/types.js.map +1 -0
- package/build/src/models/AiMessage.d.ts +185 -0
- package/build/src/models/AiMessage.d.ts.map +1 -0
- package/build/src/models/AiMessage.js +203 -0
- package/build/src/models/AiMessage.js.map +1 -0
- package/build/src/models/AiSession.d.ts +80 -0
- package/build/src/models/AiSession.d.ts.map +1 -0
- package/build/src/models/AiSession.js +102 -0
- package/build/src/models/AiSession.js.map +1 -0
- package/build/src/models/kinds.d.ts +2 -0
- package/build/src/models/kinds.d.ts.map +1 -1
- package/build/src/models/kinds.js +2 -0
- package/build/src/models/kinds.js.map +1 -1
- package/build/src/sdk/AiSdk.d.ts +93 -0
- package/build/src/sdk/AiSdk.d.ts.map +1 -0
- package/build/src/sdk/AiSdk.js +348 -0
- package/build/src/sdk/AiSdk.js.map +1 -0
- package/build/src/sdk/RouteBuilder.d.ts +7 -0
- package/build/src/sdk/RouteBuilder.d.ts.map +1 -1
- package/build/src/sdk/RouteBuilder.js +18 -0
- package/build/src/sdk/RouteBuilder.js.map +1 -1
- package/build/src/sdk/Sdk.d.ts +2 -0
- package/build/src/sdk/Sdk.d.ts.map +1 -1
- package/build/src/sdk/Sdk.js +2 -0
- package/build/src/sdk/Sdk.js.map +1 -1
- package/build/src/sdk/SdkBase.d.ts +4 -0
- package/build/src/sdk/SdkBase.d.ts.map +1 -1
- package/build/src/sdk/SdkBase.js.map +1 -1
- package/build/src/sdk/SdkMock.d.ts +15 -0
- package/build/src/sdk/SdkMock.d.ts.map +1 -1
- package/build/src/sdk/SdkMock.js +118 -0
- package/build/src/sdk/SdkMock.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +22 -22
- package/package.json +3 -3
- package/src/mocking/ModelingMock.ts +2 -0
- package/src/mocking/lib/Ai.ts +71 -0
- package/src/modeling/ai/DataDomainDelta.ts +798 -0
- package/src/modeling/ai/DomainSerialization.ts +199 -0
- package/src/modeling/ai/domain_response_schema.ts +301 -0
- package/src/modeling/ai/domain_tools.ts +76 -0
- package/src/modeling/ai/message_parser.ts +101 -0
- package/src/modeling/ai/prompts/domain_system.ts +79 -0
- package/src/modeling/ai/readme.md +8 -0
- package/src/modeling/ai/tools/DataDomain.tools.ts +365 -0
- package/src/modeling/ai/tools/Semantic.tools.ts +38 -0
- package/src/modeling/ai/tools/config.ts +13 -0
- package/src/modeling/ai/tools/readme.md +3 -0
- package/src/modeling/ai/types.ts +306 -0
- package/src/models/AiMessage.ts +335 -0
- package/src/models/AiSession.ts +160 -0
- package/src/models/kinds.ts +2 -0
- package/src/sdk/AiSdk.ts +395 -0
- package/src/sdk/RouteBuilder.ts +27 -0
- package/src/sdk/Sdk.ts +3 -0
- package/src/sdk/SdkBase.ts +4 -0
- package/src/sdk/SdkMock.ts +185 -0
- package/tests/unit/mocking/current/Ai.spec.ts +109 -0
- package/tests/unit/modeling/ai/DataDomainDelta.spec.ts +419 -0
- package/tests/unit/modeling/ai/DomainAiTools.spec.ts +29 -0
- package/tests/unit/modeling/ai/DomainSerialization.spec.ts +143 -0
- package/tests/unit/modeling/ai/message_parser.spec.ts +157 -0
- package/tests/unit/modeling/ai/tools/DataDomain.tools.spec.ts +64 -0
- package/tests/unit/modeling/ai/tools/Semantic.tools.spec.ts +55 -0
- package/tests/unit/models/AiMessage.spec.ts +216 -0
- package/tests/unit/models/AiSession.spec.ts +147 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { IDeletion } from './store/Deletion.js'
|
|
2
|
+
import { AiSessionKind } from './kinds.js'
|
|
3
|
+
import { nanoid } from '../nanoid.js'
|
|
4
|
+
import type { AiModelMessage } from './AiMessage.js'
|
|
5
|
+
|
|
6
|
+
export type AiSessionApp = 'domain' | 'api' | 'general'
|
|
7
|
+
|
|
8
|
+
export interface AiSessionSchema {
|
|
9
|
+
/**
|
|
10
|
+
* The kind of the schema
|
|
11
|
+
* This is set by the API and is used to identify the schema.
|
|
12
|
+
* @readonly
|
|
13
|
+
*/
|
|
14
|
+
readonly kind: typeof AiSessionKind
|
|
15
|
+
/**
|
|
16
|
+
* The key of the session
|
|
17
|
+
* This is set by the API and is used to identify the session.
|
|
18
|
+
*/
|
|
19
|
+
key: string
|
|
20
|
+
/**
|
|
21
|
+
* The application the session is for.
|
|
22
|
+
* Each app must query for its own sessions.
|
|
23
|
+
*/
|
|
24
|
+
app: AiSessionApp
|
|
25
|
+
/**
|
|
26
|
+
* The title of the session.
|
|
27
|
+
*/
|
|
28
|
+
title: string
|
|
29
|
+
/**
|
|
30
|
+
* Whether the session is pinned.
|
|
31
|
+
*/
|
|
32
|
+
pinned: boolean
|
|
33
|
+
/**
|
|
34
|
+
* Whether the user has renamed the session.
|
|
35
|
+
*/
|
|
36
|
+
userRenamed: boolean
|
|
37
|
+
/**
|
|
38
|
+
* The creation timestamp of the session.
|
|
39
|
+
*/
|
|
40
|
+
createdAt: number
|
|
41
|
+
/**
|
|
42
|
+
* The update timestamp of the session.
|
|
43
|
+
*/
|
|
44
|
+
updatedAt: number
|
|
45
|
+
/**
|
|
46
|
+
* Whether the file object is deleted.
|
|
47
|
+
*/
|
|
48
|
+
deleted?: boolean
|
|
49
|
+
/**
|
|
50
|
+
* The information about the delete information.
|
|
51
|
+
* Always set when the `delete` is true.
|
|
52
|
+
*/
|
|
53
|
+
deletedInfo?: IDeletion
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class AiSession implements AiSessionSchema {
|
|
57
|
+
static get Kind(): typeof AiSessionKind {
|
|
58
|
+
return AiSessionKind
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get kind(): typeof AiSessionKind {
|
|
62
|
+
return AiSessionKind
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
key: string
|
|
66
|
+
app: AiSessionApp
|
|
67
|
+
title: string
|
|
68
|
+
pinned: boolean
|
|
69
|
+
userRenamed: boolean
|
|
70
|
+
createdAt: number
|
|
71
|
+
updatedAt: number
|
|
72
|
+
deleted: boolean
|
|
73
|
+
deletedInfo?: IDeletion
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Checks if the given value is a valid AiSessionApp.
|
|
77
|
+
*/
|
|
78
|
+
static isSessionApp(app: unknown): app is AiSessionApp {
|
|
79
|
+
return ['domain', 'api', 'general'].includes(app as string)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static createSchema(input: Partial<AiSessionSchema>): AiSessionSchema {
|
|
83
|
+
const { key = nanoid(), app, title = '', createdAt = 0, updatedAt = 0, pinned = false, userRenamed = false } = input
|
|
84
|
+
if (!app) {
|
|
85
|
+
throw new Error('App is required to create an AiSession schema.')
|
|
86
|
+
}
|
|
87
|
+
if (!AiSession.isSessionApp(app)) {
|
|
88
|
+
throw new Error(`Invalid app: ${app}`)
|
|
89
|
+
}
|
|
90
|
+
const result: AiSessionSchema = {
|
|
91
|
+
key,
|
|
92
|
+
kind: AiSessionKind,
|
|
93
|
+
app,
|
|
94
|
+
title,
|
|
95
|
+
pinned,
|
|
96
|
+
userRenamed,
|
|
97
|
+
createdAt,
|
|
98
|
+
updatedAt,
|
|
99
|
+
}
|
|
100
|
+
if (input.deleted) {
|
|
101
|
+
result.deleted = input.deleted
|
|
102
|
+
result.deletedInfo = input.deletedInfo
|
|
103
|
+
}
|
|
104
|
+
return result
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
constructor(input: Partial<AiSessionSchema> = {}) {
|
|
108
|
+
const init = AiSession.createSchema(input)
|
|
109
|
+
this.key = init.key
|
|
110
|
+
this.app = init.app
|
|
111
|
+
this.title = init.title
|
|
112
|
+
this.pinned = init.pinned
|
|
113
|
+
this.userRenamed = init.userRenamed
|
|
114
|
+
this.createdAt = init.createdAt
|
|
115
|
+
this.updatedAt = init.updatedAt
|
|
116
|
+
this.deleted = init.deleted || false
|
|
117
|
+
this.deletedInfo = init.deletedInfo
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
toJSON(): AiSessionSchema {
|
|
121
|
+
const result: AiSessionSchema = {
|
|
122
|
+
kind: this.kind,
|
|
123
|
+
key: this.key,
|
|
124
|
+
app: this.app,
|
|
125
|
+
title: this.title,
|
|
126
|
+
pinned: this.pinned,
|
|
127
|
+
userRenamed: this.userRenamed,
|
|
128
|
+
createdAt: this.createdAt,
|
|
129
|
+
updatedAt: this.updatedAt,
|
|
130
|
+
}
|
|
131
|
+
if (this.deleted && this.deletedInfo) {
|
|
132
|
+
result.deleted = this.deleted
|
|
133
|
+
result.deletedInfo = { ...this.deletedInfo }
|
|
134
|
+
}
|
|
135
|
+
return result
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Processes the agent response and extracts the session title if available.
|
|
140
|
+
* It looks for a JSON object in the response text and extracts the `sessionTitle`.
|
|
141
|
+
*
|
|
142
|
+
* @param message The agent response.
|
|
143
|
+
* @returns {string | null} The session title if found, otherwise null.
|
|
144
|
+
*/
|
|
145
|
+
static extractSessionTitle(message: AiModelMessage): string | null {
|
|
146
|
+
const txt = message.text
|
|
147
|
+
if (!txt) {
|
|
148
|
+
return null
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const json = JSON.parse(txt)
|
|
152
|
+
if (json.sessionTitle) {
|
|
153
|
+
return String(json.sessionTitle)
|
|
154
|
+
}
|
|
155
|
+
} catch {
|
|
156
|
+
// ignore
|
|
157
|
+
}
|
|
158
|
+
return null
|
|
159
|
+
}
|
|
160
|
+
}
|
package/src/models/kinds.ts
CHANGED
|
@@ -24,3 +24,5 @@ export const ApiModelKind = 'Core#ApiModel'
|
|
|
24
24
|
export const ExposedEntityKind = 'Core#ExposedEntity'
|
|
25
25
|
export const ApiFileKind = 'Core#ApiFile'
|
|
26
26
|
export const GroupKind = 'Core#Group'
|
|
27
|
+
export const AiSessionKind = 'Core#AiSession'
|
|
28
|
+
export const AiMessageKind = 'Core#AiMessage'
|
package/src/sdk/AiSdk.ts
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import type { ContextListOptions, ContextListResult } from '../events/BaseEvents.js'
|
|
2
|
+
import { Exception } from '../exceptions/exception.js'
|
|
3
|
+
import type { AiStreamEvent } from '../modeling/ai/types.js'
|
|
4
|
+
import type { AiMessage, AiMessageSchema } from '../models/AiMessage.js'
|
|
5
|
+
import type { AiSessionApp, AiSessionSchema } from '../models/AiSession.js'
|
|
6
|
+
import { AiMessageKind, AiSessionKind } from '../models/kinds.js'
|
|
7
|
+
import { RouteBuilder } from './RouteBuilder.js'
|
|
8
|
+
import {
|
|
9
|
+
E_INVALID_JSON,
|
|
10
|
+
E_RESPONSE_NO_VALUE,
|
|
11
|
+
E_RESPONSE_STATUS,
|
|
12
|
+
E_RESPONSE_UNKNOWN,
|
|
13
|
+
SdkBase,
|
|
14
|
+
type SdkOptions,
|
|
15
|
+
} from './SdkBase.js'
|
|
16
|
+
|
|
17
|
+
export class AiSdk extends SdkBase {
|
|
18
|
+
/**
|
|
19
|
+
* Modifies the domain of a file.
|
|
20
|
+
* @param oid The organization id.
|
|
21
|
+
* @param fid The domain file id.
|
|
22
|
+
* @param goal The goal to modify the domain for.
|
|
23
|
+
* @param sid The conversation session id, if any. When provided it will be used to continue the conversation.
|
|
24
|
+
* @param request The request options.
|
|
25
|
+
*/
|
|
26
|
+
async *modifyDomain(
|
|
27
|
+
oid: string,
|
|
28
|
+
fid: string,
|
|
29
|
+
goal: string,
|
|
30
|
+
sid?: string,
|
|
31
|
+
request: SdkOptions = {}
|
|
32
|
+
): AsyncGenerator<AiStreamEvent> {
|
|
33
|
+
const { token = this.sdk.token, signal } = request
|
|
34
|
+
const url = this.sdk.getUrl(RouteBuilder.aiModifyDomain(oid, fid))
|
|
35
|
+
const body = JSON.stringify({ goal, sid })
|
|
36
|
+
const init: RequestInit = {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: {
|
|
39
|
+
'content-type': 'application/json',
|
|
40
|
+
'accept': 'text/event-stream',
|
|
41
|
+
'authorization': `Bearer ${token}`,
|
|
42
|
+
},
|
|
43
|
+
redirect: 'follow',
|
|
44
|
+
credentials: 'include',
|
|
45
|
+
body,
|
|
46
|
+
signal,
|
|
47
|
+
}
|
|
48
|
+
const result = await fetch(url, init)
|
|
49
|
+
if (!result.ok) {
|
|
50
|
+
const errText = await result.text()
|
|
51
|
+
throw new Exception(`Failed to modify domain: ${result.status} ${errText}`)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const reader = result.body?.getReader()
|
|
55
|
+
if (!reader) {
|
|
56
|
+
throw new Exception('Failed to get reader from response')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const decoder = new TextDecoder()
|
|
60
|
+
let buffer = ''
|
|
61
|
+
while (true) {
|
|
62
|
+
const { done, value } = await reader.read()
|
|
63
|
+
if (done) {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
buffer += decoder.decode(value, { stream: true })
|
|
67
|
+
let newlineIndex: number
|
|
68
|
+
while ((newlineIndex = buffer.indexOf('\n\n')) >= 0) {
|
|
69
|
+
const messageChunk = buffer.slice(0, newlineIndex)
|
|
70
|
+
buffer = buffer.slice(newlineIndex + 2)
|
|
71
|
+
if (!messageChunk.trim()) continue
|
|
72
|
+
|
|
73
|
+
const lines = messageChunk.split('\n')
|
|
74
|
+
let eventName = 'message'
|
|
75
|
+
let eventDataStr = ''
|
|
76
|
+
|
|
77
|
+
for (const line of lines) {
|
|
78
|
+
if (line.startsWith('event:')) {
|
|
79
|
+
eventName = line.substring(6).trim()
|
|
80
|
+
} else if (line.startsWith('data:')) {
|
|
81
|
+
eventDataStr += line.substring(5).trim()
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!eventDataStr) continue
|
|
86
|
+
|
|
87
|
+
let eventData
|
|
88
|
+
try {
|
|
89
|
+
eventData = JSON.parse(eventDataStr)
|
|
90
|
+
} catch {
|
|
91
|
+
// eslint-disable-next-line no-console
|
|
92
|
+
console.error('Failed to parse SSE JSON data:', eventDataStr)
|
|
93
|
+
continue
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
switch (eventName) {
|
|
97
|
+
case 'user-message':
|
|
98
|
+
case 'agent-message':
|
|
99
|
+
// Assume the data is a full AiMessage
|
|
100
|
+
yield { event: eventName, data: eventData as AiMessage }
|
|
101
|
+
break
|
|
102
|
+
case 'thought-chunk':
|
|
103
|
+
case 'text-chunk':
|
|
104
|
+
// Assume the data is string diff chunks
|
|
105
|
+
yield { event: eventName, data: eventData as string }
|
|
106
|
+
break
|
|
107
|
+
case 'done':
|
|
108
|
+
yield { event: eventName, data: eventData as AiMessage }
|
|
109
|
+
return
|
|
110
|
+
case 'error':
|
|
111
|
+
yield { event: eventName, data: Exception.fromRawException(eventData, 'Failed to generate results') }
|
|
112
|
+
break
|
|
113
|
+
case 'session-updated':
|
|
114
|
+
yield { event: eventName, data: eventData as AiSessionSchema }
|
|
115
|
+
break
|
|
116
|
+
default:
|
|
117
|
+
// eslint-disable-next-line no-console
|
|
118
|
+
console.warn(`Unknown SSE event: ${eventName}`)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
sessions = {
|
|
125
|
+
/**
|
|
126
|
+
* Lists the AI sessions for the given organization and application.
|
|
127
|
+
* @param oid The organization id.
|
|
128
|
+
* @param app The application id.
|
|
129
|
+
* @param options The list options.
|
|
130
|
+
* @param request The request options.
|
|
131
|
+
* @returns The list of AI sessions.
|
|
132
|
+
*/
|
|
133
|
+
list: async (
|
|
134
|
+
oid: string,
|
|
135
|
+
app: AiSessionApp,
|
|
136
|
+
options: ContextListOptions = {},
|
|
137
|
+
request: SdkOptions = {}
|
|
138
|
+
): Promise<ContextListResult<AiSessionSchema>> => {
|
|
139
|
+
const { token = this.sdk.token } = request
|
|
140
|
+
const url = this.sdk.getUrl(RouteBuilder.aiSessions(oid, app))
|
|
141
|
+
this.sdk.appendListOptions(url, options)
|
|
142
|
+
const result = await this.sdk.http.get(url.toString(), { token })
|
|
143
|
+
this.inspectCommonStatusCodes(result)
|
|
144
|
+
const E_PREFIX = 'Unable to list sessions. '
|
|
145
|
+
if (result.status !== 200) {
|
|
146
|
+
this.logInvalidResponse(result)
|
|
147
|
+
throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
|
|
148
|
+
}
|
|
149
|
+
if (!result.body) {
|
|
150
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
|
|
151
|
+
}
|
|
152
|
+
let data: ContextListResult<AiSessionSchema>
|
|
153
|
+
try {
|
|
154
|
+
data = JSON.parse(result.body)
|
|
155
|
+
} catch {
|
|
156
|
+
throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
|
|
157
|
+
}
|
|
158
|
+
if (!Array.isArray(data.items)) {
|
|
159
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
|
|
160
|
+
}
|
|
161
|
+
return data
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Reads the AI session for the given organization, application and session id.
|
|
166
|
+
* @param oid The organization id.
|
|
167
|
+
* @param app The application id.
|
|
168
|
+
* @param sid The session id.
|
|
169
|
+
* @param request The request options.
|
|
170
|
+
* @returns The AI session.
|
|
171
|
+
*/
|
|
172
|
+
read: async (oid: string, app: AiSessionApp, sid: string, request: SdkOptions = {}): Promise<AiSessionSchema> => {
|
|
173
|
+
const { token = this.sdk.token } = request
|
|
174
|
+
const url = this.sdk.getUrl(RouteBuilder.aiSession(oid, app, sid))
|
|
175
|
+
const result = await this.sdk.http.get(url.toString(), { token })
|
|
176
|
+
this.inspectCommonStatusCodes(result)
|
|
177
|
+
const E_PREFIX = 'Unable to read session. '
|
|
178
|
+
if (result.status !== 200) {
|
|
179
|
+
this.logInvalidResponse(result)
|
|
180
|
+
throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
|
|
181
|
+
}
|
|
182
|
+
if (!result.body) {
|
|
183
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
|
|
184
|
+
}
|
|
185
|
+
let data: AiSessionSchema
|
|
186
|
+
try {
|
|
187
|
+
data = JSON.parse(result.body)
|
|
188
|
+
} catch {
|
|
189
|
+
throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
|
|
190
|
+
}
|
|
191
|
+
if (data.kind !== AiSessionKind) {
|
|
192
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
|
|
193
|
+
}
|
|
194
|
+
return data
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Creates the AI session for the given organization, application and session id.
|
|
199
|
+
* @param oid The organization id.
|
|
200
|
+
* @param app The application id.
|
|
201
|
+
* @param session The AI session to create.
|
|
202
|
+
* @param request The request options.
|
|
203
|
+
* @returns The created AI session.
|
|
204
|
+
*/
|
|
205
|
+
create: async (
|
|
206
|
+
oid: string,
|
|
207
|
+
app: AiSessionApp,
|
|
208
|
+
session: Partial<AiSessionSchema>,
|
|
209
|
+
request: SdkOptions = {}
|
|
210
|
+
): Promise<AiSessionSchema> => {
|
|
211
|
+
const { token = this.sdk.token } = request
|
|
212
|
+
const url = this.sdk.getUrl(RouteBuilder.aiSessions(oid, app))
|
|
213
|
+
const body = JSON.stringify(session)
|
|
214
|
+
const result = await this.sdk.http.post(url.toString(), { token, body })
|
|
215
|
+
this.inspectCommonStatusCodes(result)
|
|
216
|
+
const E_PREFIX = 'Unable to create session. '
|
|
217
|
+
if (result.status !== 201) {
|
|
218
|
+
this.logInvalidResponse(result)
|
|
219
|
+
throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
|
|
220
|
+
}
|
|
221
|
+
if (!result.body) {
|
|
222
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
|
|
223
|
+
}
|
|
224
|
+
let data: AiSessionSchema
|
|
225
|
+
try {
|
|
226
|
+
data = JSON.parse(result.body)
|
|
227
|
+
} catch {
|
|
228
|
+
throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
|
|
229
|
+
}
|
|
230
|
+
if (data.kind !== AiSessionKind) {
|
|
231
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
|
|
232
|
+
}
|
|
233
|
+
return data
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Deletes the AI session for the given organization, application and session id.
|
|
238
|
+
* The API performs a soft delete of the session.
|
|
239
|
+
* @param oid The organization id.
|
|
240
|
+
* @param app The application id.
|
|
241
|
+
* @param sid The session id.
|
|
242
|
+
* @param request The request options.
|
|
243
|
+
*/
|
|
244
|
+
delete: async (oid: string, app: AiSessionApp, sid: string, request: SdkOptions = {}): Promise<void> => {
|
|
245
|
+
const { token = this.sdk.token } = request
|
|
246
|
+
const url = this.sdk.getUrl(RouteBuilder.aiSession(oid, app, sid))
|
|
247
|
+
const result = await this.sdk.http.delete(url.toString(), { token })
|
|
248
|
+
this.inspectCommonStatusCodes(result)
|
|
249
|
+
const E_PREFIX = 'Unable to delete session. '
|
|
250
|
+
if (result.status !== 204) {
|
|
251
|
+
this.logInvalidResponse(result)
|
|
252
|
+
throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Updates the AI session for the given organization, application and session id.
|
|
258
|
+
* @param oid The organization id.
|
|
259
|
+
* @param app The application id.
|
|
260
|
+
* @param session The AI session to update.
|
|
261
|
+
* @param request The request options.
|
|
262
|
+
* @returns The updated AI session.
|
|
263
|
+
*/
|
|
264
|
+
update: async (
|
|
265
|
+
oid: string,
|
|
266
|
+
app: AiSessionApp,
|
|
267
|
+
session: AiSessionSchema,
|
|
268
|
+
request: SdkOptions = {}
|
|
269
|
+
): Promise<AiSessionSchema> => {
|
|
270
|
+
const { token = this.sdk.token } = request
|
|
271
|
+
const url = this.sdk.getUrl(RouteBuilder.aiSession(oid, app, session.key))
|
|
272
|
+
const body = JSON.stringify(session)
|
|
273
|
+
const result = await this.sdk.http.put(url.toString(), { token, body })
|
|
274
|
+
this.inspectCommonStatusCodes(result)
|
|
275
|
+
const E_PREFIX = 'Unable to update session. '
|
|
276
|
+
if (result.status !== 200) {
|
|
277
|
+
this.logInvalidResponse(result)
|
|
278
|
+
throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
|
|
279
|
+
}
|
|
280
|
+
if (!result.body) {
|
|
281
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
|
|
282
|
+
}
|
|
283
|
+
let data: AiSessionSchema
|
|
284
|
+
try {
|
|
285
|
+
data = JSON.parse(result.body)
|
|
286
|
+
} catch {
|
|
287
|
+
throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
|
|
288
|
+
}
|
|
289
|
+
if (data.kind !== AiSessionKind) {
|
|
290
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
|
|
291
|
+
}
|
|
292
|
+
return data
|
|
293
|
+
},
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
messages = {
|
|
297
|
+
/**
|
|
298
|
+
* Lists the AI messages for the given organization and session id.
|
|
299
|
+
* @param oid The organization id.
|
|
300
|
+
* @param sid The session id.
|
|
301
|
+
* @param options The list options.
|
|
302
|
+
* @param request The request options.
|
|
303
|
+
* @returns The list of AI messages.
|
|
304
|
+
*/
|
|
305
|
+
list: async (
|
|
306
|
+
oid: string,
|
|
307
|
+
sid: string,
|
|
308
|
+
options: ContextListOptions = {},
|
|
309
|
+
request: SdkOptions = {}
|
|
310
|
+
): Promise<ContextListResult<AiMessageSchema>> => {
|
|
311
|
+
const { token = this.sdk.token } = request
|
|
312
|
+
const url = this.sdk.getUrl(RouteBuilder.aiMessages(oid, sid))
|
|
313
|
+
this.sdk.appendListOptions(url, options)
|
|
314
|
+
const result = await this.sdk.http.get(url.toString(), { token })
|
|
315
|
+
this.inspectCommonStatusCodes(result)
|
|
316
|
+
const E_PREFIX = 'Unable to list messages. '
|
|
317
|
+
if (result.status !== 200) {
|
|
318
|
+
this.logInvalidResponse(result)
|
|
319
|
+
throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
|
|
320
|
+
}
|
|
321
|
+
if (!result.body) {
|
|
322
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
|
|
323
|
+
}
|
|
324
|
+
let data: ContextListResult<AiMessageSchema>
|
|
325
|
+
try {
|
|
326
|
+
data = JSON.parse(result.body)
|
|
327
|
+
} catch {
|
|
328
|
+
throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
|
|
329
|
+
}
|
|
330
|
+
if (!Array.isArray(data.items)) {
|
|
331
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
|
|
332
|
+
}
|
|
333
|
+
return data
|
|
334
|
+
},
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Deletes the AI message for the given organization, session and message id.
|
|
338
|
+
* The API performs a soft delete of the message.
|
|
339
|
+
* @param oid The organization id.
|
|
340
|
+
* @param sid The session id.
|
|
341
|
+
* @param mid The message id.
|
|
342
|
+
* @param request The request options.
|
|
343
|
+
*/
|
|
344
|
+
delete: async (oid: string, sid: string, mid: string, request: SdkOptions = {}): Promise<void> => {
|
|
345
|
+
const { token = this.sdk.token } = request
|
|
346
|
+
const url = this.sdk.getUrl(RouteBuilder.aiMessage(oid, sid, mid))
|
|
347
|
+
const result = await this.sdk.http.delete(url.toString(), { token })
|
|
348
|
+
this.inspectCommonStatusCodes(result)
|
|
349
|
+
const E_PREFIX = 'Unable to delete message. '
|
|
350
|
+
if (result.status !== 204) {
|
|
351
|
+
this.logInvalidResponse(result)
|
|
352
|
+
throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Updates the AI message for the given organization, session and message id.
|
|
358
|
+
* @param oid The organization id.
|
|
359
|
+
* @param sid The session id.
|
|
360
|
+
* @param message The AI message to update.
|
|
361
|
+
* @param request The request options.
|
|
362
|
+
* @returns The updated AI message.
|
|
363
|
+
*/
|
|
364
|
+
update: async (
|
|
365
|
+
oid: string,
|
|
366
|
+
sid: string,
|
|
367
|
+
message: AiMessageSchema,
|
|
368
|
+
request: SdkOptions = {}
|
|
369
|
+
): Promise<AiMessageSchema> => {
|
|
370
|
+
const { token = this.sdk.token } = request
|
|
371
|
+
const url = this.sdk.getUrl(RouteBuilder.aiMessage(oid, sid, message.key))
|
|
372
|
+
const body = JSON.stringify(message)
|
|
373
|
+
const result = await this.sdk.http.put(url.toString(), { token, body })
|
|
374
|
+
this.inspectCommonStatusCodes(result)
|
|
375
|
+
const E_PREFIX = 'Unable to update message. '
|
|
376
|
+
if (result.status !== 200) {
|
|
377
|
+
this.logInvalidResponse(result)
|
|
378
|
+
throw this.createApiError(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`, result.body)
|
|
379
|
+
}
|
|
380
|
+
if (!result.body) {
|
|
381
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`, { code: 'E_RESPONSE_NO_VALUE', status: result.status })
|
|
382
|
+
}
|
|
383
|
+
let data: AiMessageSchema
|
|
384
|
+
try {
|
|
385
|
+
data = JSON.parse(result.body)
|
|
386
|
+
} catch {
|
|
387
|
+
throw new Exception(`${E_PREFIX}${E_INVALID_JSON}`, { code: 'E_INVALID_JSON', status: result.status })
|
|
388
|
+
}
|
|
389
|
+
if (data.kind !== AiMessageKind) {
|
|
390
|
+
throw new Exception(`${E_PREFIX}${E_RESPONSE_UNKNOWN}`, { code: 'E_RESPONSE_UNKNOWN', status: result.status })
|
|
391
|
+
}
|
|
392
|
+
return data
|
|
393
|
+
},
|
|
394
|
+
}
|
|
395
|
+
}
|
package/src/sdk/RouteBuilder.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-extraneous-class */
|
|
2
|
+
|
|
3
|
+
import type { AiSessionApp } from '../models/AiSession.js'
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
6
|
* A helper class to make sure routes user and reported by this service are consistent.
|
|
4
7
|
*/
|
|
@@ -299,4 +302,28 @@ export class RouteBuilder {
|
|
|
299
302
|
static groupUsers(oid: string, gid: string): string {
|
|
300
303
|
return `/v1/orgs/${oid}/groups/${gid}/users`
|
|
301
304
|
}
|
|
305
|
+
|
|
306
|
+
static aiModifyDomain(oid: string, fid: string): string | undefined {
|
|
307
|
+
return `${this.organization(oid)}/ai/domains/${fid}/modify/stream`
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
static aiModifyApi(oid: string, fid: string): string | undefined {
|
|
311
|
+
return `${this.organization(oid)}/ai/apis/${fid}/modify/stream`
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
static aiSessions(oid: string, app: AiSessionApp): string {
|
|
315
|
+
return `${this.organization(oid)}/ai/sessions/${app}`
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
static aiSession(oid: string, app: AiSessionApp, sid: string): string {
|
|
319
|
+
return `${RouteBuilder.aiSessions(oid, app)}/${sid}`
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
static aiMessages(oid: string, sid: string): string {
|
|
323
|
+
return `${this.organization(oid)}/ai/messages/${sid}`
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
static aiMessage(oid: string, sid: string, mid: string): string {
|
|
327
|
+
return `${RouteBuilder.aiMessages(oid, sid)}/${mid}`
|
|
328
|
+
}
|
|
302
329
|
}
|
package/src/sdk/Sdk.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { ProjectExecutionSdk } from './ProjectExecutionsSdk.js'
|
|
|
12
12
|
import { OrganizationsSdk } from './OrganizationsSdk.js'
|
|
13
13
|
import { DataCatalogSdk } from './DataCatalogSdk.js'
|
|
14
14
|
import { GroupsSdk } from './GroupsSdk.js'
|
|
15
|
+
import { AiSdk } from './AiSdk.js'
|
|
15
16
|
|
|
16
17
|
const baseUriSymbol = Symbol('baseUri')
|
|
17
18
|
|
|
@@ -81,6 +82,8 @@ export abstract class Sdk {
|
|
|
81
82
|
dataCatalog = new DataCatalogSdk(this)
|
|
82
83
|
|
|
83
84
|
groups = new GroupsSdk(this)
|
|
85
|
+
|
|
86
|
+
ai = new AiSdk(this)
|
|
84
87
|
/**
|
|
85
88
|
* When set it limits log output to minimum.
|
|
86
89
|
*/
|
package/src/sdk/SdkBase.ts
CHANGED