@undefineds.co/models 0.2.15 → 0.2.18
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/README.md +26 -28
- package/dist/agent.providers.js +11 -0
- package/dist/agent.repository.d.ts +1 -1
- package/dist/ai-config/index.d.ts +10 -2
- package/dist/ai-config/index.js +53 -15
- package/dist/ai-model.schema.js +4 -3
- package/dist/ai-provider.schema.js +1 -1
- package/dist/approval.schema.d.ts +7 -1
- package/dist/approval.schema.js +6 -8
- package/dist/audit.presentation.d.ts +23 -0
- package/dist/audit.presentation.js +275 -0
- package/dist/audit.schema.d.ts +1 -1
- package/dist/audit.schema.js +3 -8
- package/dist/chat.repository.d.ts +1 -1
- package/dist/chat.utils.d.ts +9 -0
- package/dist/chat.utils.js +33 -0
- package/dist/contact.repository.d.ts +1 -1
- package/dist/contact.schema.d.ts +8 -0
- package/dist/contact.schema.js +12 -0
- package/dist/credential.schema.js +1 -1
- package/dist/discovery/models.json +29 -0
- package/dist/discovery/providers.json +10 -0
- package/dist/grant.schema.d.ts +28 -1
- package/dist/grant.schema.js +21 -7
- package/dist/index.d.ts +10 -8
- package/dist/index.js +9 -7
- package/dist/message.repository.d.ts +1 -1
- package/dist/namespaces.js +11 -0
- package/dist/profile.repository.d.ts +7 -7
- package/dist/repository.d.ts +1 -99
- package/dist/repository.js +1 -189
- package/dist/schema.d.ts +34 -0
- package/dist/session/index.d.ts +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/session.schema.d.ts +2 -1
- package/dist/session/session.schema.js +11 -7
- package/dist/session.repository.d.ts +1 -1
- package/dist/sidecar/persistence-mapping.d.ts +2 -2
- package/dist/sidecar/sidecar-events.d.ts +192 -6
- package/dist/sidecar/sidecar-events.js +10 -0
- package/dist/thread.repository.d.ts +1 -1
- package/dist/vocab/sidecar.vocab.d.ts +17 -0
- package/dist/vocab/sidecar.vocab.js +17 -0
- package/dist/watch/index.d.ts +55 -0
- package/dist/watch/index.js +349 -12
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# LinX 数据模型
|
|
2
2
|
|
|
3
3
|
> 基于 Solid Pod 标准的 LinX 核心数据模型定义
|
|
4
|
-
>
|
|
4
|
+
>
|
|
5
5
|
> 使用 `drizzle-solid` ORM,兼容标准 RDF 词汇表(VCARD, FOAF, SIOC, DCTerms 等)
|
|
6
6
|
|
|
7
7
|
---
|
|
@@ -56,6 +56,12 @@ LinX 的所有数据存储在 Solid Pod 中,使用标准的 RDF 格式。本
|
|
|
56
56
|
- 新增 shared model 代码优先使用 `chatResource`、`threadResource`、`messageResource`、`sessionResource` 等 Solid resource 命名;`*Table` 只作为兼容 alias 逐步退出。
|
|
57
57
|
- 如果壳层需要新的查询、upsert、resolve-by-uri、审计或审批状态变更能力,优先在本包新增 repository/helper 和 tests;不要在 CLI/App 中复制 predicate、subject template、Turtle 读写或 shared 状态机。
|
|
58
58
|
- `approval` / `grant` / `audit` / `inboxNotification` / `session` 等跨端控制面也属于本包的 shared resource 语义。CLI/App 只负责把 Pi/Codex/Claude 等运行时事件映射成本包定义的 insert/update DTO,不能另建一套存储路径或审批策略。
|
|
59
|
+
- approval 的倒计时和可选决策也属于 shared resource 语义:使用 `approvalResource.expiresAt` 表示截止时间,使用 `approvalResource.approvalOptions` 存储上游原生协议给出的可选决策(例如 `allow_once` / `allow_always` / `reject_once`)。CLI/App 不得各自用私有 predicate 或本地状态推断这些字段。
|
|
60
|
+
- grant 是可维护的 LLM Wiki 文档资源,不是一次请求的 fingerprint。`grantResource` 使用 `/settings/autonomy/grants/{id}.ttl`,文档 URI 本身就是 RDF subject;通过 `title/summary/body/schema/pageKind/wikiStatus/tags/source/sourceHash/compiledAt/compiledFrom/related/context` 描述页面语义、来源和上下文。
|
|
61
|
+
- `grant.schema` 使用 `dcterms:conformsTo` 指向 Solid schema/shape URI,例如 `/settings/autonomy/schema/grant.ttl#GrantWikiPage`;它不是 `path`/`wikiPath` 字符串,TTL wiki page 也不需要 `.meta` subject。
|
|
62
|
+
- `grant.target`、`grant.action`、`grant.riskCeiling` 只用于候选筛选或排序,不得作为最终自动审批判定。最终是否覆盖必须看 wiki page 的 `body/summary/tags/source/provenance/context` 与当前请求的语义匹配结果。
|
|
63
|
+
- CLI/App 不得为 shared 控制面字段自定义业务 predicate。新增 approval/grant/audit 字段必须先在本包的 namespace、vocab、schema 和 tests 中定义。
|
|
64
|
+
- structured user-input 与 approval 一样属于 watch 共享协议:AI secretary 只能在答案能从请求上下文明确推出时代答,否则必须回到人工输入。
|
|
59
65
|
|
|
60
66
|
---
|
|
61
67
|
|
|
@@ -122,26 +128,26 @@ LinX 遵循 Solid 生态的最佳实践,优先使用标准 RDF 词汇表:
|
|
|
122
128
|
givenName: string; // vcard:givenName
|
|
123
129
|
familyName: string; // vcard:familyName
|
|
124
130
|
nickname: string; // foaf:nick
|
|
125
|
-
|
|
131
|
+
|
|
126
132
|
// 联系方式
|
|
127
133
|
email: string; // vcard:hasEmail
|
|
128
134
|
telephone: string; // vcard:hasTelephone
|
|
129
135
|
mobile: string;
|
|
130
|
-
|
|
136
|
+
|
|
131
137
|
// 地址
|
|
132
138
|
homeAddress: string; // vcard:hasAddress (JSON)
|
|
133
139
|
workAddress: string;
|
|
134
|
-
|
|
140
|
+
|
|
135
141
|
// 组织
|
|
136
142
|
organization: string; // vcard:organizationName
|
|
137
143
|
title: string; // vcard:title
|
|
138
|
-
|
|
144
|
+
|
|
139
145
|
// Solid 身份
|
|
140
146
|
webId: string; // foaf:weblog
|
|
141
|
-
|
|
147
|
+
|
|
142
148
|
// AI 联系人
|
|
143
149
|
aiAssistantId: string; // linx:aiAssistant
|
|
144
|
-
|
|
150
|
+
|
|
145
151
|
// 关系和标签
|
|
146
152
|
relationship: string; // vcard:hasRelated
|
|
147
153
|
tags: string; // dcterms:subject (JSON)
|
|
@@ -199,7 +205,7 @@ LinX 遵循 Solid 生态的最佳实践,优先使用标准 RDF 词汇表:
|
|
|
199
205
|
modifiedAt: timestamp; // dcterms:modified (编辑时间)
|
|
200
206
|
deletedAt: timestamp; // linx:deletedAt (软删除)
|
|
201
207
|
readBy: string; // linx:readBy (JSON)
|
|
202
|
-
|
|
208
|
+
|
|
203
209
|
// 附件(如果是文件/图片消息)
|
|
204
210
|
attachmentUri: string; // schema:about
|
|
205
211
|
attachmentName: string; // schema:name
|
|
@@ -254,12 +260,12 @@ LinX 遵循 Solid 生态的最佳实践,优先使用标准 RDF 词汇表:
|
|
|
254
260
|
description: string; // dcterms:description
|
|
255
261
|
favoriteType: string; // linx:favoriteType
|
|
256
262
|
targetUri: string; // linx:favoriteTarget ⭐ 必需
|
|
257
|
-
|
|
263
|
+
|
|
258
264
|
// 快照(避免查询原始资源)
|
|
259
265
|
snapshotContent: string; // schema:text
|
|
260
266
|
snapshotAuthor: string; // schema:author
|
|
261
267
|
snapshotCreatedAt: timestamp; // schema:dateCreated
|
|
262
|
-
|
|
268
|
+
|
|
263
269
|
owner: string; // dcterms:creator
|
|
264
270
|
folder: string; // linx:conversation
|
|
265
271
|
tags: string; // dcterms:subject (JSON)
|
|
@@ -344,37 +350,37 @@ POD_CACHE_SIZE: "pod.cacheSize"
|
|
|
344
350
|
description: string; // dcterms:description
|
|
345
351
|
avatarUrl: string; // foaf:depiction
|
|
346
352
|
assistantType: string; // dcterms:type (system, custom, shared)
|
|
347
|
-
|
|
353
|
+
|
|
348
354
|
// 模型配置
|
|
349
355
|
provider: string; // linx:aiProvider (openai, anthropic, ollama, custom)
|
|
350
356
|
modelId: string; // linx:aiModel (gpt-4, claude-3, llama2)
|
|
351
357
|
systemPrompt: string; // linx:systemPrompt
|
|
352
|
-
|
|
358
|
+
|
|
353
359
|
// 模型参数
|
|
354
360
|
temperature: float; // linx:temperature (0-2)
|
|
355
361
|
maxTokens: integer; // linx:maxTokens
|
|
356
362
|
topP: float;
|
|
357
363
|
frequencyPenalty: float;
|
|
358
364
|
presencePenalty: float;
|
|
359
|
-
|
|
365
|
+
|
|
360
366
|
// 功能配置
|
|
361
367
|
enableStreaming: boolean;
|
|
362
368
|
enableFunctionCalling: boolean;
|
|
363
369
|
allowedFunctions: string; // JSON 数组
|
|
364
|
-
|
|
370
|
+
|
|
365
371
|
// Pod 访问权限
|
|
366
372
|
podAccessLevel: string; // linx:status (read, write, full)
|
|
367
373
|
allowedContainers: string; // JSON 数组
|
|
368
|
-
|
|
374
|
+
|
|
369
375
|
// 共享
|
|
370
376
|
owner: string; // dcterms:creator
|
|
371
377
|
isPublic: boolean;
|
|
372
378
|
sharedWith: string; // JSON
|
|
373
|
-
|
|
379
|
+
|
|
374
380
|
// 统计
|
|
375
381
|
messageCount: integer;
|
|
376
382
|
lastUsedAt: timestamp;
|
|
377
|
-
|
|
383
|
+
|
|
378
384
|
status: string; // linx:status (active, disabled, archived)
|
|
379
385
|
createdAt: timestamp;
|
|
380
386
|
modifiedAt: timestamp;
|
|
@@ -401,7 +407,7 @@ yarn workspace @linq/models install
|
|
|
401
407
|
import {
|
|
402
408
|
// 词汇表
|
|
403
409
|
LINQ, SIOC, DCTerms, SCHEMA,
|
|
404
|
-
|
|
410
|
+
|
|
405
411
|
// 模型表
|
|
406
412
|
contactTable,
|
|
407
413
|
chatTable,
|
|
@@ -410,12 +416,12 @@ import {
|
|
|
410
416
|
favoriteTable,
|
|
411
417
|
settingsTable,
|
|
412
418
|
aiAssistantTable,
|
|
413
|
-
|
|
419
|
+
|
|
414
420
|
// 类型
|
|
415
421
|
type ContactRow,
|
|
416
422
|
type ChatRow,
|
|
417
423
|
type MessageRow,
|
|
418
|
-
|
|
424
|
+
|
|
419
425
|
// 常量
|
|
420
426
|
CONTACT_TYPES,
|
|
421
427
|
SETTING_KEYS,
|
|
@@ -585,11 +591,3 @@ yarn workspace @linq/models typecheck
|
|
|
585
591
|
## 许可证
|
|
586
592
|
|
|
587
593
|
MIT License
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
package/dist/agent.providers.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
export const DEFAULT_AGENT_PROVIDERS = [
|
|
2
|
+
{
|
|
3
|
+
slug: 'undefineds',
|
|
4
|
+
displayName: 'undefineds',
|
|
5
|
+
baseUrl: 'https://api.undefineds.co/v1',
|
|
6
|
+
homepage: 'https://undefineds.co/linx',
|
|
7
|
+
logoUrl: 'https://undefineds.co/favicon.ico',
|
|
8
|
+
models: [
|
|
9
|
+
{ id: 'linx-lite', displayName: 'LinX Lite' },
|
|
10
|
+
{ id: 'linx', displayName: 'LinX' },
|
|
11
|
+
],
|
|
12
|
+
},
|
|
2
13
|
{
|
|
3
14
|
slug: 'openai',
|
|
4
15
|
displayName: 'OpenAI',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const agentRepository: import("
|
|
1
|
+
export declare const agentRepository: import("@undefineds.co/drizzle-solid/dist/core/repository").PodRepositoryDescriptor<import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
|
|
2
2
|
id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
|
|
3
3
|
name: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
|
|
4
4
|
description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
@@ -43,16 +43,24 @@ export interface AIConfigMutationPlan {
|
|
|
43
43
|
modelUpserts: AIModelInsert[];
|
|
44
44
|
modelDeleteIds: string[];
|
|
45
45
|
}
|
|
46
|
+
export declare const UNDEFINEDS_AI_PROVIDER_ID = "undefineds";
|
|
47
|
+
export declare const UNDEFINEDS_AI_PROVIDER_DISPLAY_NAME = "undefineds";
|
|
48
|
+
export declare const UNDEFINEDS_AI_BASE_URL = "https://api.undefineds.co/v1";
|
|
49
|
+
export declare const LINX_LITE_MODEL_ID = "linx-lite";
|
|
50
|
+
export declare const LINX_MODEL_ID = "linx";
|
|
51
|
+
export declare const DEFAULT_LINX_MODEL_ID = "linx-lite";
|
|
52
|
+
export declare const UNDEFINEDS_AI_MODEL_IDS: readonly ["linx-lite", "linx"];
|
|
46
53
|
export declare function getAIConfigProviderCatalog(): readonly AIConfigProviderCatalogEntry[];
|
|
47
54
|
export declare function getAIConfigProviderMetadata(providerId: string): AIConfigProviderCatalogEntry;
|
|
48
55
|
export declare function normalizeAIConfigResourceId(raw?: string | null): string;
|
|
56
|
+
export declare function normalizeAIConfigModelId(raw?: string | null, providerId?: string | null): string;
|
|
49
57
|
export declare function normalizeAIConfigProviderId(raw?: string | null): string;
|
|
50
58
|
export declare function sameAIConfigProviderFamily(left?: string | null, right?: string | null): boolean;
|
|
51
59
|
export declare function getAIConfigProviderFamilyIds(providerId: string): string[];
|
|
52
60
|
export declare function getAIConfigDefaultBaseUrl(providerId: string): string | undefined;
|
|
53
61
|
export declare function getDefaultAIConfigCredentialId(providerId: string): string;
|
|
54
|
-
export declare function
|
|
55
|
-
export declare function
|
|
62
|
+
export declare function aiConfigProviderRef(providerId: string): string;
|
|
63
|
+
export declare function aiConfigModelRef(providerId: string, modelId?: string): string;
|
|
56
64
|
export declare function buildAIConfigProviderStateMap(options: BuildAIConfigProviderStateMapOptions): Record<string, AIConfigProviderState>;
|
|
57
65
|
export declare function buildAIConfigMutationPlan(input: {
|
|
58
66
|
providerId: string;
|
package/dist/ai-config/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export const UNDEFINEDS_AI_PROVIDER_ID = 'undefineds';
|
|
2
|
+
export const UNDEFINEDS_AI_PROVIDER_DISPLAY_NAME = 'undefineds';
|
|
3
|
+
export const UNDEFINEDS_AI_BASE_URL = 'https://api.undefineds.co/v1';
|
|
4
|
+
export const LINX_LITE_MODEL_ID = 'linx-lite';
|
|
5
|
+
export const LINX_MODEL_ID = 'linx';
|
|
6
|
+
export const DEFAULT_LINX_MODEL_ID = LINX_LITE_MODEL_ID;
|
|
7
|
+
export const UNDEFINEDS_AI_MODEL_IDS = [LINX_LITE_MODEL_ID, LINX_MODEL_ID];
|
|
1
8
|
const AI_CONFIG_PROVIDER_CATALOG = [
|
|
2
9
|
{
|
|
3
10
|
id: 'openai',
|
|
@@ -69,6 +76,7 @@ const AI_CONFIG_PROVIDER_CATALOG = [
|
|
|
69
76
|
},
|
|
70
77
|
];
|
|
71
78
|
const AI_CONFIG_PROVIDER_MAP = new Map(AI_CONFIG_PROVIDER_CATALOG.map((entry) => [entry.id, entry]));
|
|
79
|
+
const ABSOLUTE_IRI = /^[a-zA-Z][a-zA-Z\d+.-]*:/;
|
|
72
80
|
function normalizeText(value) {
|
|
73
81
|
return value.trim().toLowerCase();
|
|
74
82
|
}
|
|
@@ -111,12 +119,34 @@ export function getAIConfigProviderMetadata(providerId) {
|
|
|
111
119
|
export function normalizeAIConfigResourceId(raw) {
|
|
112
120
|
if (!raw)
|
|
113
121
|
return '';
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
const value = raw.trim();
|
|
123
|
+
if (!value)
|
|
124
|
+
return '';
|
|
125
|
+
if (value.includes('#'))
|
|
126
|
+
return value.split('#').pop() || value;
|
|
127
|
+
if (!ABSOLUTE_IRI.test(value) && !value.endsWith('.ttl')) {
|
|
128
|
+
return value;
|
|
129
|
+
}
|
|
130
|
+
const clean = value.replace(/\/$/, '');
|
|
131
|
+
if (!ABSOLUTE_IRI.test(value)) {
|
|
132
|
+
return clean.endsWith('.ttl') ? clean.slice(0, -4) : clean;
|
|
133
|
+
}
|
|
117
134
|
const tail = clean.split('/').pop() || clean;
|
|
118
135
|
return tail.endsWith('.ttl') ? tail.slice(0, -4) : tail;
|
|
119
136
|
}
|
|
137
|
+
export function normalizeAIConfigModelId(raw, providerId) {
|
|
138
|
+
const modelId = normalizeAIConfigResourceId(raw);
|
|
139
|
+
if (!modelId.includes('/'))
|
|
140
|
+
return modelId;
|
|
141
|
+
const [prefix, ...rest] = modelId.split('/');
|
|
142
|
+
if (rest.length === 0)
|
|
143
|
+
return modelId;
|
|
144
|
+
if (!providerId)
|
|
145
|
+
return modelId;
|
|
146
|
+
return normalizeAIConfigProviderId(prefix) === normalizeAIConfigProviderId(providerId)
|
|
147
|
+
? rest.join('/')
|
|
148
|
+
: modelId;
|
|
149
|
+
}
|
|
120
150
|
export function normalizeAIConfigProviderId(raw) {
|
|
121
151
|
const normalized = normalizeText(normalizeAIConfigResourceId(raw));
|
|
122
152
|
if (!normalized)
|
|
@@ -128,6 +158,9 @@ export function normalizeAIConfigProviderId(raw) {
|
|
|
128
158
|
}
|
|
129
159
|
return normalized;
|
|
130
160
|
}
|
|
161
|
+
function normalizeAIConfigModelStorageId(raw, providerId) {
|
|
162
|
+
return normalizeAIConfigModelId(raw, providerId);
|
|
163
|
+
}
|
|
131
164
|
export function sameAIConfigProviderFamily(left, right) {
|
|
132
165
|
const normalizedLeft = normalizeAIConfigProviderId(left);
|
|
133
166
|
const normalizedRight = normalizeAIConfigProviderId(right);
|
|
@@ -143,11 +176,16 @@ export function getAIConfigDefaultBaseUrl(providerId) {
|
|
|
143
176
|
export function getDefaultAIConfigCredentialId(providerId) {
|
|
144
177
|
return `${normalizeAIConfigProviderId(providerId)}-default`;
|
|
145
178
|
}
|
|
146
|
-
export function
|
|
147
|
-
return
|
|
179
|
+
export function aiConfigProviderRef(providerId) {
|
|
180
|
+
return normalizeAIConfigProviderId(providerId);
|
|
148
181
|
}
|
|
149
|
-
export function
|
|
150
|
-
|
|
182
|
+
export function aiConfigModelRef(providerId, modelId) {
|
|
183
|
+
if (modelId === undefined) {
|
|
184
|
+
return normalizeAIConfigResourceId(providerId);
|
|
185
|
+
}
|
|
186
|
+
const provider = normalizeAIConfigProviderId(providerId);
|
|
187
|
+
const model = normalizeAIConfigModelStorageId(modelId, provider);
|
|
188
|
+
return provider && model ? `/settings/ai/models/${provider}.ttl#${model}` : model;
|
|
151
189
|
}
|
|
152
190
|
export function buildAIConfigProviderStateMap(options) {
|
|
153
191
|
const catalog = options.catalog ?? AI_CONFIG_PROVIDER_CATALOG;
|
|
@@ -175,7 +213,7 @@ export function buildAIConfigProviderStateMap(options) {
|
|
|
175
213
|
const providerId = normalizeAIConfigProviderId(String(row.isProvidedBy ?? ''));
|
|
176
214
|
if (!providerId)
|
|
177
215
|
continue;
|
|
178
|
-
const modelId =
|
|
216
|
+
const modelId = normalizeAIConfigModelStorageId(String(row.id ?? row['@id'] ?? ''), providerId);
|
|
179
217
|
if (!modelId)
|
|
180
218
|
continue;
|
|
181
219
|
const list = modelMap.get(providerId) ?? [];
|
|
@@ -213,7 +251,7 @@ export function buildAIConfigProviderStateMap(options) {
|
|
|
213
251
|
enabled: true,
|
|
214
252
|
capabilities: [],
|
|
215
253
|
}));
|
|
216
|
-
const selectedModelId =
|
|
254
|
+
const selectedModelId = normalizeAIConfigModelStorageId(typeof providerRow?.hasModel === 'string' ? providerRow.hasModel : '', providerId) || preferredSelectedModelId(models);
|
|
217
255
|
states[providerId] = {
|
|
218
256
|
id: providerId,
|
|
219
257
|
enabled: (typeof credentialRow?.status === 'string' ? credentialRow.status : 'inactive') === 'active',
|
|
@@ -241,21 +279,21 @@ export function buildAIConfigMutationPlan(input) {
|
|
|
241
279
|
if (hasConfigUpdate || input.updates.models !== undefined) {
|
|
242
280
|
const selectedModelId = input.updates.models
|
|
243
281
|
? preferredSelectedModelId(input.updates.models)
|
|
244
|
-
:
|
|
282
|
+
: normalizeAIConfigModelStorageId(typeof existingProvider?.hasModel === 'string' ? existingProvider.hasModel : '', providerId);
|
|
245
283
|
providerPayload = {
|
|
246
284
|
id: providerId,
|
|
247
285
|
baseUrl: input.updates.baseUrl ??
|
|
248
286
|
(typeof existingProvider?.baseUrl === 'string' ? existingProvider.baseUrl : undefined) ??
|
|
249
287
|
metadata.defaultBaseUrl,
|
|
250
288
|
proxyUrl: typeof existingProvider?.proxyUrl === 'string' ? existingProvider.proxyUrl : undefined,
|
|
251
|
-
hasModel: selectedModelId ?
|
|
289
|
+
hasModel: selectedModelId ? aiConfigModelRef(providerId, selectedModelId) : undefined,
|
|
252
290
|
};
|
|
253
291
|
}
|
|
254
292
|
if (hasConfigUpdate) {
|
|
255
293
|
credentialPayload = {
|
|
256
294
|
id: normalizeAIConfigResourceId(typeof existingCredential?.id === 'string' ? existingCredential.id : '') ||
|
|
257
295
|
getDefaultAIConfigCredentialId(providerId),
|
|
258
|
-
provider:
|
|
296
|
+
provider: aiConfigProviderRef(providerId),
|
|
259
297
|
service: typeof existingCredential?.service === 'string' && existingCredential.service ? existingCredential.service : 'ai',
|
|
260
298
|
status: input.updates.enabled !== undefined
|
|
261
299
|
? input.updates.enabled
|
|
@@ -275,12 +313,12 @@ export function buildAIConfigMutationPlan(input) {
|
|
|
275
313
|
}
|
|
276
314
|
if (input.updates.models !== undefined) {
|
|
277
315
|
const existingById = new Map(existingModels.map((row) => [
|
|
278
|
-
|
|
316
|
+
normalizeAIConfigModelStorageId(String(row.id ?? row['@id'] ?? ''), providerId),
|
|
279
317
|
row,
|
|
280
318
|
]));
|
|
281
319
|
const nextIds = new Set();
|
|
282
320
|
for (const model of input.updates.models) {
|
|
283
|
-
const modelId =
|
|
321
|
+
const modelId = normalizeAIConfigModelStorageId(model.id, providerId);
|
|
284
322
|
if (!modelId)
|
|
285
323
|
continue;
|
|
286
324
|
nextIds.add(modelId);
|
|
@@ -290,7 +328,7 @@ export function buildAIConfigMutationPlan(input) {
|
|
|
290
328
|
id: modelId,
|
|
291
329
|
displayName: model.name || modelId,
|
|
292
330
|
modelType: 'chat',
|
|
293
|
-
isProvidedBy:
|
|
331
|
+
isProvidedBy: aiConfigProviderRef(providerId),
|
|
294
332
|
status: model.enabled ? 'active' : 'inactive',
|
|
295
333
|
createdAt: existingDate(existing?.createdAt) ?? now,
|
|
296
334
|
updatedAt: now,
|
package/dist/ai-model.schema.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { id, integer, podTable, string, timestamp, uri } from "@undefineds.co/drizzle-solid";
|
|
2
|
+
import { aiProviderTable } from "./ai-provider.schema.js";
|
|
2
3
|
import { XPOD_AI } from "./namespaces.js";
|
|
3
4
|
export const aiModelTable = podTable("aiModel", {
|
|
4
5
|
id: id("id"),
|
|
5
6
|
displayName: string("displayName").predicate(XPOD_AI.displayName),
|
|
6
7
|
modelType: string("modelType").predicate(XPOD_AI.modelType).default("chat"),
|
|
7
|
-
isProvidedBy: uri("isProvidedBy").predicate(XPOD_AI.isProvidedBy),
|
|
8
|
+
isProvidedBy: uri("isProvidedBy").predicate(XPOD_AI.isProvidedBy).link(aiProviderTable),
|
|
8
9
|
dimension: integer("dimension").predicate(XPOD_AI.dimension),
|
|
9
10
|
status: string("status").predicate(XPOD_AI.status).default("active"),
|
|
10
11
|
createdAt: timestamp("createdAt").predicate(XPOD_AI.createdAt).notNull().defaultNow(),
|
|
11
12
|
updatedAt: timestamp("updatedAt").predicate(XPOD_AI.updatedAt).notNull().defaultNow(),
|
|
12
13
|
}, {
|
|
13
|
-
base: "/settings/ai/models
|
|
14
|
+
base: "/settings/ai/models/",
|
|
14
15
|
type: XPOD_AI.Model,
|
|
15
16
|
namespace: XPOD_AI,
|
|
16
|
-
subjectTemplate: "#{id}",
|
|
17
|
+
subjectTemplate: "{isProvidedBy|id}.ttl#{id}",
|
|
17
18
|
});
|
|
@@ -4,7 +4,7 @@ export const aiProviderTable = podTable("aiProvider", {
|
|
|
4
4
|
id: id("id"),
|
|
5
5
|
baseUrl: string("baseUrl").predicate(XPOD_AI.baseUrl),
|
|
6
6
|
proxyUrl: string("proxyUrl").predicate(XPOD_AI.proxyUrl),
|
|
7
|
-
hasModel: uri("hasModel").predicate(XPOD_AI.hasModel),
|
|
7
|
+
hasModel: uri("hasModel").predicate(XPOD_AI.hasModel).link("aiModel"),
|
|
8
8
|
}, {
|
|
9
9
|
base: "/settings/ai/providers.ttl",
|
|
10
10
|
type: XPOD_AI.Provider,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function
|
|
1
|
+
export declare function extractApprovalIdFromApprovalRef(approvalRef: string | null | undefined): string | null;
|
|
2
2
|
export declare const approvalResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
|
|
3
3
|
id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
|
|
4
4
|
session: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
|
|
@@ -13,8 +13,11 @@ export declare const approvalResource: import("@undefineds.co/drizzle-solid/dist
|
|
|
13
13
|
decisionRole: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
14
14
|
onBehalfOf: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
|
|
15
15
|
reason: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
16
|
+
context: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
17
|
+
approvalOptions: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
16
18
|
policyVersion: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
17
19
|
createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
|
|
20
|
+
expiresAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
|
|
18
21
|
resolvedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
|
|
19
22
|
}>>;
|
|
20
23
|
export declare const approvalTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
|
|
@@ -31,8 +34,11 @@ export declare const approvalTable: import("@undefineds.co/drizzle-solid/dist/co
|
|
|
31
34
|
decisionRole: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
32
35
|
onBehalfOf: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
|
|
33
36
|
reason: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
37
|
+
context: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
38
|
+
approvalOptions: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
34
39
|
policyVersion: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
35
40
|
createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
|
|
41
|
+
expiresAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
|
|
36
42
|
resolvedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
|
|
37
43
|
}>>;
|
|
38
44
|
export type ApprovalRow = typeof approvalResource.$inferSelect;
|
package/dist/approval.schema.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import { podTable, uri, string, text, timestamp, id } from '@undefineds.co/drizzle-solid';
|
|
1
|
+
import { extractPodResourceTemplateValue, podTable, uri, string, text, timestamp, id } from '@undefineds.co/drizzle-solid';
|
|
2
2
|
import { ODRL, UDFS, DCTerms } from './namespaces.js';
|
|
3
|
-
export function
|
|
4
|
-
|
|
5
|
-
const safeDate = Number.isFinite(date.getTime()) ? date : new Date();
|
|
6
|
-
const yyyy = String(safeDate.getUTCFullYear());
|
|
7
|
-
const mm = String(safeDate.getUTCMonth() + 1).padStart(2, '0');
|
|
8
|
-
const dd = String(safeDate.getUTCDate()).padStart(2, '0');
|
|
9
|
-
return `/.data/approvals/${yyyy}/${mm}/${dd}.ttl#${encodeURIComponent(approvalId)}`;
|
|
3
|
+
export function extractApprovalIdFromApprovalRef(approvalRef) {
|
|
4
|
+
return extractPodResourceTemplateValue(approvalResource, approvalRef);
|
|
10
5
|
}
|
|
11
6
|
// Approval request resource (separate from Solid inbox notifications).
|
|
12
7
|
export const approvalResource = podTable('approval', {
|
|
@@ -28,9 +23,12 @@ export const approvalResource = podTable('approval', {
|
|
|
28
23
|
decisionRole: string('decisionRole').predicate(UDFS.decisionRole),
|
|
29
24
|
onBehalfOf: uri('onBehalfOf').predicate(UDFS.onBehalfOf),
|
|
30
25
|
reason: text('reason').predicate(UDFS.reason),
|
|
26
|
+
context: text('context').predicate(UDFS.context),
|
|
27
|
+
approvalOptions: text('approvalOptions').predicate(UDFS.approvalOptions),
|
|
31
28
|
policyVersion: string('policyVersion').predicate(UDFS.policyVersion),
|
|
32
29
|
// Timestamps
|
|
33
30
|
createdAt: timestamp('createdAt').predicate(DCTerms.created).notNull().defaultNow(),
|
|
31
|
+
expiresAt: timestamp('expiresAt').predicate(UDFS.expiresAt),
|
|
34
32
|
resolvedAt: timestamp('resolvedAt').predicate(UDFS.resolvedAt),
|
|
35
33
|
}, {
|
|
36
34
|
base: '/.data/approvals/',
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ApprovalRow } from './approval.schema';
|
|
2
|
+
import type { AuditRow } from './audit.schema';
|
|
3
|
+
export interface AuditPresentation {
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
category: 'auth_required' | 'audit';
|
|
7
|
+
status?: string;
|
|
8
|
+
chatId: string | null;
|
|
9
|
+
threadId: string | null;
|
|
10
|
+
thread: string | null;
|
|
11
|
+
about: string | null;
|
|
12
|
+
authUrl: string | null;
|
|
13
|
+
authMethod: string | null;
|
|
14
|
+
authMessage: string | null;
|
|
15
|
+
actorRoleLabel: string;
|
|
16
|
+
}
|
|
17
|
+
type RelatedApproval = Pick<ApprovalRow, 'target' | 'toolName' | 'risk' | 'reason' | 'status' | 'context'> | null | undefined;
|
|
18
|
+
export declare function buildAuditDetailRecord(audit: AuditRow, relatedApproval?: RelatedApproval): Record<string, unknown>;
|
|
19
|
+
export declare function formatInboxStatusLabel(status?: string | null): string | null;
|
|
20
|
+
export declare function formatAuditActorRole(role?: string | null): string;
|
|
21
|
+
export declare function createResolvedAuthTimestampsIndex(audits: AuditRow[]): Map<string, number[]>;
|
|
22
|
+
export declare function buildAuditPresentation(audit: AuditRow, resolvedAuthTimestampsByKey: Map<string, number[]>, relatedApproval?: RelatedApproval): AuditPresentation;
|
|
23
|
+
export {};
|