@undefineds.co/models 0.2.26 → 0.2.27
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/dist/approval.schema.js +2 -1
- package/dist/audit.schema.js +2 -1
- package/dist/bin/udfs.d.ts +2 -0
- package/dist/bin/udfs.js +430 -0
- package/dist/chat.repository.d.ts +8 -0
- package/dist/chat.schema.d.ts +10 -0
- package/dist/chat.schema.js +9 -2
- package/dist/chat.utils.js +24 -9
- package/dist/index.d.ts +7 -3
- package/dist/index.js +7 -3
- package/dist/message.repository.d.ts +29 -9
- package/dist/message.schema.d.ts +29 -6
- package/dist/message.schema.js +26 -10
- package/dist/namespaces.js +23 -0
- package/dist/pod-storage-descriptor.d.ts +189 -0
- package/dist/pod-storage-descriptor.js +283 -0
- package/dist/repository.d.ts +2 -0
- package/dist/repository.js +3 -0
- package/dist/resource-id-defaults.d.ts +18 -0
- package/dist/resource-id-defaults.js +84 -0
- package/dist/run.schema.d.ts +112 -0
- package/dist/run.schema.js +89 -0
- package/dist/schema.d.ts +132 -8
- package/dist/schema.js +8 -0
- package/dist/session/session.schema.js +2 -1
- package/dist/sidecar/sidecar-events.d.ts +36 -36
- package/dist/task.schema.d.ts +62 -0
- package/dist/task.schema.js +49 -0
- package/dist/thread.repository.d.ts +15 -3
- package/dist/thread.schema.d.ts +14 -2
- package/dist/thread.schema.js +13 -5
- package/package.json +11 -3
package/dist/approval.schema.js
CHANGED
|
@@ -2,6 +2,7 @@ import { extractPodResourceTemplateValue, podTable, uri, string, text, timestamp
|
|
|
2
2
|
import { ODRL, UDFS, DCTerms } from './namespaces.js';
|
|
3
3
|
import { chatResource } from './chat.schema.js';
|
|
4
4
|
import { threadResource } from './thread.schema.js';
|
|
5
|
+
import { asPodResourceTemplateTarget } from './repository.js';
|
|
5
6
|
export function buildApprovalSubjectPath(approvalId, createdAt = new Date()) {
|
|
6
7
|
const date = createdAt instanceof Date ? createdAt : new Date(createdAt);
|
|
7
8
|
const safeDate = Number.isFinite(date.getTime()) ? date : new Date();
|
|
@@ -14,7 +15,7 @@ export function extractApprovalIdFromApprovalRef(approvalRef) {
|
|
|
14
15
|
if (approvalRef && !/[/:#]/.test(approvalRef)) {
|
|
15
16
|
return approvalRef;
|
|
16
17
|
}
|
|
17
|
-
return extractPodResourceTemplateValue(approvalResource, approvalRef);
|
|
18
|
+
return extractPodResourceTemplateValue(asPodResourceTemplateTarget(approvalResource), approvalRef);
|
|
18
19
|
}
|
|
19
20
|
// Approval request resource (separate from Solid inbox notifications).
|
|
20
21
|
export const approvalResource = podTable('approval', {
|
package/dist/audit.schema.js
CHANGED
|
@@ -2,6 +2,7 @@ import { extractPodResourceTemplateValue, podTable, uri, string, timestamp, id }
|
|
|
2
2
|
import { UDFS, DCTerms } from './namespaces.js';
|
|
3
3
|
import { chatResource } from './chat.schema.js';
|
|
4
4
|
import { threadResource } from './thread.schema.js';
|
|
5
|
+
import { asPodResourceTemplateTarget } from './repository.js';
|
|
5
6
|
export function buildAuditSubjectPath(auditId, createdAt = new Date()) {
|
|
6
7
|
const date = createdAt instanceof Date ? createdAt : new Date(createdAt);
|
|
7
8
|
const safeDate = Number.isFinite(date.getTime()) ? date : new Date();
|
|
@@ -45,7 +46,7 @@ export function extractAuditIdFromAuditRef(auditRef) {
|
|
|
45
46
|
if (auditRef && !/[/:#]/.test(auditRef)) {
|
|
46
47
|
return auditRef;
|
|
47
48
|
}
|
|
48
|
-
return extractPodResourceTemplateValue(auditResource, auditRef);
|
|
49
|
+
return extractPodResourceTemplateValue(asPodResourceTemplateTarget(auditResource), auditRef);
|
|
49
50
|
}
|
|
50
51
|
// Compatibility alias. New model code should prefer `auditResource`.
|
|
51
52
|
export const auditTable = auditResource;
|
package/dist/bin/udfs.js
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createPodStorage, podSchema, XPOD_CREDENTIAL, } from '../index.js';
|
|
3
|
+
async function main(argv) {
|
|
4
|
+
const [area, action, ...rest] = argv;
|
|
5
|
+
if (!area || area === 'help' || area === '--help' || area === '-h') {
|
|
6
|
+
printHelp();
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (area === 'schema') {
|
|
10
|
+
handleSchema(action, rest);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (area === 'storage') {
|
|
14
|
+
handleStorage(action, rest);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (area === 'consensus') {
|
|
18
|
+
await handleConsensus(action, rest);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
throw new Error(`Unknown udfs command: ${area}`);
|
|
22
|
+
}
|
|
23
|
+
function handleSchema(action, args) {
|
|
24
|
+
if (action === 'list') {
|
|
25
|
+
writeJson(podSchema.list());
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (action === 'describe') {
|
|
29
|
+
const uri = args[0];
|
|
30
|
+
if (!uri)
|
|
31
|
+
throw new Error('Usage: udfs schema describe <uri>');
|
|
32
|
+
const descriptor = podSchema.describe({ uri });
|
|
33
|
+
if (!descriptor)
|
|
34
|
+
throw new Error(`Descriptor not found: ${uri}`);
|
|
35
|
+
writeJson(descriptor);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (action === 'classes') {
|
|
39
|
+
writeJson(podSchema.classes({
|
|
40
|
+
uri: readOption(args, '--uri'),
|
|
41
|
+
}));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (action === 'search') {
|
|
45
|
+
const query = readOption(args, '--query') ?? args[0];
|
|
46
|
+
if (!query)
|
|
47
|
+
throw new Error('Usage: udfs schema search --query <text>');
|
|
48
|
+
writeJson(podSchema.search({
|
|
49
|
+
query,
|
|
50
|
+
source: readOption(args, '--source'),
|
|
51
|
+
resourceKind: readOption(args, '--resource-kind'),
|
|
52
|
+
limit: readNumberOption(args, '--limit'),
|
|
53
|
+
}));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (action === 'predicates') {
|
|
57
|
+
writeJson(podSchema.predicates({
|
|
58
|
+
uri: readOption(args, '--uri'),
|
|
59
|
+
field: readOption(args, '--field'),
|
|
60
|
+
}));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`Unknown schema command: ${action ?? '(missing)'}`);
|
|
64
|
+
}
|
|
65
|
+
function handleStorage(action, args) {
|
|
66
|
+
if (action === 'validate') {
|
|
67
|
+
const input = readInputPayload(args, 'udfs storage validate --input \'<mutation-json>\'');
|
|
68
|
+
writeJson(createPodStorage().validate(input));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Unknown storage command: ${action ?? '(missing)'}`);
|
|
72
|
+
}
|
|
73
|
+
async function handleConsensus(action, args) {
|
|
74
|
+
if (!action || action === '--help' || action === '-h') {
|
|
75
|
+
printConsensusHelp();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const allArgs = [action, ...args];
|
|
79
|
+
const input = readConsensusInput(allArgs);
|
|
80
|
+
const result = await resolveConsensusRequest({
|
|
81
|
+
sessionId: input.session_id,
|
|
82
|
+
request: input.request,
|
|
83
|
+
tokenType: input.answers?.token_type ?? 'tunnel-token',
|
|
84
|
+
conversation: input.conversation_id ?? process.env.UDFS_CONSENSUS_CONVERSATION_ID,
|
|
85
|
+
});
|
|
86
|
+
if (allArgs.includes('--json')) {
|
|
87
|
+
writeJson(result);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
process.stdout.write(`Consensus: ${input.request}\n`);
|
|
91
|
+
if (result.session_id) {
|
|
92
|
+
process.stdout.write(`Session: ${result.session_id}\n`);
|
|
93
|
+
}
|
|
94
|
+
process.stdout.write(`Consensus runtime: ${result.consensusRuntime.mode}${result.consensusRuntime.mode === 'remote' ? ` (${result.consensusRuntime.baseUrl})` : ''}\n`);
|
|
95
|
+
if (result.consensusResponse?.conversationId) {
|
|
96
|
+
process.stdout.write(`Conversation: ${result.consensusResponse.conversationId}\n`);
|
|
97
|
+
}
|
|
98
|
+
process.stdout.write(`Clarification: ${result.first.questions[0].question}\n`);
|
|
99
|
+
process.stdout.write(`Answer: ${input.answers?.token_type ?? 'tunnel-token'}\n`);
|
|
100
|
+
process.stdout.write(`Schema: ${result.resolved.schemaUri}\n`);
|
|
101
|
+
process.stdout.write(`Descriptor storage: ${result.descriptor.storage.base}${result.descriptor.storage.resourceIdPattern}\n`);
|
|
102
|
+
}
|
|
103
|
+
function resolveConsensusRuntime() {
|
|
104
|
+
const baseUrl = process.env.UDFS_CONSENSUS_BASE_URL;
|
|
105
|
+
const token = process.env.UDFS_CONSENSUS_TOKEN;
|
|
106
|
+
if (baseUrl && token) {
|
|
107
|
+
return {
|
|
108
|
+
mode: 'remote',
|
|
109
|
+
baseUrl,
|
|
110
|
+
auth: 'runtime-token',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
mode: 'local-fallback',
|
|
115
|
+
auth: 'none',
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function resolveConsensusRequest(input) {
|
|
119
|
+
const runtime = resolveConsensusRuntime();
|
|
120
|
+
if (runtime.mode === 'remote') {
|
|
121
|
+
const remote = await callRemoteConsensus({
|
|
122
|
+
runtime,
|
|
123
|
+
sessionId: input.sessionId,
|
|
124
|
+
request: input.request,
|
|
125
|
+
conversation: input.conversation,
|
|
126
|
+
});
|
|
127
|
+
const parsed = parseRemoteConsensusPayload(remote.body);
|
|
128
|
+
const resolved = coerceResolvedConsensusPayload(parsed);
|
|
129
|
+
if (!resolved) {
|
|
130
|
+
throw new Error('Remote Consensus response did not contain a resolved schema payload');
|
|
131
|
+
}
|
|
132
|
+
return buildConsensusResult({
|
|
133
|
+
runtime,
|
|
134
|
+
sessionId: input.sessionId,
|
|
135
|
+
tokenType: input.tokenType,
|
|
136
|
+
fieldMapping: resolved.fieldMapping,
|
|
137
|
+
confidence: resolved.confidence,
|
|
138
|
+
response: {
|
|
139
|
+
id: remote.id,
|
|
140
|
+
conversationId: remote.conversationId,
|
|
141
|
+
parsed,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return buildConsensusResult({
|
|
146
|
+
runtime,
|
|
147
|
+
sessionId: input.sessionId,
|
|
148
|
+
tokenType: input.tokenType,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async function callRemoteConsensus(input) {
|
|
152
|
+
const token = process.env.UDFS_CONSENSUS_TOKEN;
|
|
153
|
+
if (!token) {
|
|
154
|
+
throw new Error('Remote Consensus requires injected UDFS_CONSENSUS_TOKEN');
|
|
155
|
+
}
|
|
156
|
+
const body = {
|
|
157
|
+
model: process.env.UDFS_CONSENSUS_MODEL ?? 'consensus-modeling',
|
|
158
|
+
input: [
|
|
159
|
+
{
|
|
160
|
+
role: 'user',
|
|
161
|
+
content: [
|
|
162
|
+
{
|
|
163
|
+
type: 'input_text',
|
|
164
|
+
text: input.request,
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
metadata: {
|
|
170
|
+
product: 'linx',
|
|
171
|
+
purpose: 'pod-storage',
|
|
172
|
+
...(input.sessionId ? { session_id: input.sessionId } : {}),
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
if (input.conversation) {
|
|
176
|
+
body.conversation = input.conversation;
|
|
177
|
+
}
|
|
178
|
+
const response = await fetch(`${input.runtime.baseUrl.replace(/\/+$/u, '')}/responses`, {
|
|
179
|
+
method: 'POST',
|
|
180
|
+
headers: {
|
|
181
|
+
authorization: `Bearer ${token}`,
|
|
182
|
+
'content-type': 'application/json',
|
|
183
|
+
},
|
|
184
|
+
body: JSON.stringify(body),
|
|
185
|
+
});
|
|
186
|
+
const text = await response.text();
|
|
187
|
+
const parsedBody = text ? JSON.parse(text) : {};
|
|
188
|
+
if (!response.ok) {
|
|
189
|
+
throw new Error(`Remote Consensus request failed: ${response.status} ${text}`);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
id: typeof parsedBody.id === 'string' ? parsedBody.id : undefined,
|
|
193
|
+
conversationId: extractConversationId(parsedBody),
|
|
194
|
+
body: parsedBody,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function extractConversationId(body) {
|
|
198
|
+
if (typeof body.conversation === 'string')
|
|
199
|
+
return body.conversation;
|
|
200
|
+
if (body.conversation
|
|
201
|
+
&& typeof body.conversation === 'object'
|
|
202
|
+
&& 'id' in body.conversation
|
|
203
|
+
&& typeof body.conversation.id === 'string') {
|
|
204
|
+
return body.conversation.id;
|
|
205
|
+
}
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
function parseRemoteConsensusPayload(body) {
|
|
209
|
+
if (isRecord(body) && typeof body.status === 'string') {
|
|
210
|
+
return body;
|
|
211
|
+
}
|
|
212
|
+
if (isRecord(body) && typeof body.output_text === 'string') {
|
|
213
|
+
return parseJsonMaybe(body.output_text);
|
|
214
|
+
}
|
|
215
|
+
if (isRecord(body) && Array.isArray(body.output)) {
|
|
216
|
+
for (const item of body.output) {
|
|
217
|
+
if (!isRecord(item) || !Array.isArray(item.content))
|
|
218
|
+
continue;
|
|
219
|
+
for (const content of item.content) {
|
|
220
|
+
if (!isRecord(content))
|
|
221
|
+
continue;
|
|
222
|
+
const text = typeof content.text === 'string'
|
|
223
|
+
? content.text
|
|
224
|
+
: typeof content.output_text === 'string'
|
|
225
|
+
? content.output_text
|
|
226
|
+
: undefined;
|
|
227
|
+
if (!text)
|
|
228
|
+
continue;
|
|
229
|
+
const parsed = parseJsonMaybe(text);
|
|
230
|
+
if (parsed)
|
|
231
|
+
return parsed;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (isRecord(body) && Array.isArray(body.choices)) {
|
|
236
|
+
for (const choice of body.choices) {
|
|
237
|
+
if (!isRecord(choice) || !isRecord(choice.message))
|
|
238
|
+
continue;
|
|
239
|
+
if (typeof choice.message.content !== 'string')
|
|
240
|
+
continue;
|
|
241
|
+
const parsed = parseJsonMaybe(choice.message.content);
|
|
242
|
+
if (parsed)
|
|
243
|
+
return parsed;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
function coerceResolvedConsensusPayload(payload) {
|
|
249
|
+
if (!isRecord(payload) || payload.status !== 'resolved')
|
|
250
|
+
return null;
|
|
251
|
+
const schemaUri = stringField(payload, 'schemaUri') ?? stringField(payload, 'uri');
|
|
252
|
+
if (schemaUri !== XPOD_CREDENTIAL.Credential)
|
|
253
|
+
return null;
|
|
254
|
+
if (!isRecord(payload.fieldMapping))
|
|
255
|
+
return null;
|
|
256
|
+
const service = stringField(payload.fieldMapping, 'service');
|
|
257
|
+
const providerId = stringField(payload.fieldMapping, 'providerId');
|
|
258
|
+
const secretType = stringField(payload.fieldMapping, 'secretType');
|
|
259
|
+
if (!service || !providerId || !secretType)
|
|
260
|
+
return null;
|
|
261
|
+
return {
|
|
262
|
+
fieldMapping: {
|
|
263
|
+
service,
|
|
264
|
+
providerId,
|
|
265
|
+
secretType,
|
|
266
|
+
label: stringField(payload.fieldMapping, 'label'),
|
|
267
|
+
status: stringField(payload.fieldMapping, 'status'),
|
|
268
|
+
},
|
|
269
|
+
confidence: typeof payload.confidence === 'number' ? payload.confidence : undefined,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function parseJsonMaybe(text) {
|
|
273
|
+
try {
|
|
274
|
+
return JSON.parse(text);
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function isRecord(value) {
|
|
281
|
+
return typeof value === 'object' && value !== null;
|
|
282
|
+
}
|
|
283
|
+
function stringField(record, field) {
|
|
284
|
+
const value = record[field];
|
|
285
|
+
return typeof value === 'string' && value.trim() ? value : undefined;
|
|
286
|
+
}
|
|
287
|
+
function buildConsensusResult(input) {
|
|
288
|
+
const first = {
|
|
289
|
+
status: 'needs_clarification',
|
|
290
|
+
questions: [
|
|
291
|
+
{
|
|
292
|
+
id: 'token_type',
|
|
293
|
+
question: '这是 Cloudflare API Token 还是 Tunnel Token?',
|
|
294
|
+
options: ['tunnel-token', 'api-token'],
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
};
|
|
298
|
+
const resolved = {
|
|
299
|
+
status: 'resolved',
|
|
300
|
+
schemaUri: XPOD_CREDENTIAL.Credential,
|
|
301
|
+
fieldMapping: {
|
|
302
|
+
service: input.fieldMapping?.service ?? 'infra',
|
|
303
|
+
providerId: input.fieldMapping?.providerId ?? 'cloudflare',
|
|
304
|
+
secretType: input.fieldMapping?.secretType ?? input.tokenType,
|
|
305
|
+
label: input.fieldMapping?.label
|
|
306
|
+
?? defaultCredentialLabel(input.fieldMapping?.providerId ?? 'cloudflare', input.fieldMapping?.secretType ?? input.tokenType),
|
|
307
|
+
status: input.fieldMapping?.status ?? 'active',
|
|
308
|
+
},
|
|
309
|
+
confidence: input.confidence ?? (input.tokenType === 'tunnel-token' ? 0.96 : 0.94),
|
|
310
|
+
};
|
|
311
|
+
const descriptor = podSchema.describe({ uri: resolved.schemaUri });
|
|
312
|
+
if (!descriptor) {
|
|
313
|
+
throw new Error(`Descriptor not found: ${resolved.schemaUri}`);
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
session_id: input.sessionId,
|
|
317
|
+
consensusRuntime: input.runtime,
|
|
318
|
+
consensusResponse: input.response,
|
|
319
|
+
first,
|
|
320
|
+
resolved,
|
|
321
|
+
descriptor: {
|
|
322
|
+
uri: descriptor.uri,
|
|
323
|
+
storage: descriptor.storage,
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function readOption(args, name) {
|
|
328
|
+
const index = args.indexOf(name);
|
|
329
|
+
if (index === -1)
|
|
330
|
+
return undefined;
|
|
331
|
+
const value = args[index + 1];
|
|
332
|
+
return value && !value.startsWith('--') ? value : undefined;
|
|
333
|
+
}
|
|
334
|
+
function readNumberOption(args, name) {
|
|
335
|
+
const value = readOption(args, name);
|
|
336
|
+
if (!value)
|
|
337
|
+
return undefined;
|
|
338
|
+
const parsed = Number(value);
|
|
339
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
340
|
+
throw new Error(`${name} must be a positive number`);
|
|
341
|
+
}
|
|
342
|
+
return Math.floor(parsed);
|
|
343
|
+
}
|
|
344
|
+
function readConsensusInput(args) {
|
|
345
|
+
if (args[0] === 'model') {
|
|
346
|
+
throw new Error('Use: udfs consensus --input \'<json>\'');
|
|
347
|
+
}
|
|
348
|
+
const parsed = readInputPayload(args, 'udfs consensus --input \'<json>\' --json');
|
|
349
|
+
if (!isRecord(parsed)) {
|
|
350
|
+
throw new Error('Consensus input must be a JSON object');
|
|
351
|
+
}
|
|
352
|
+
const request = stringField(parsed, 'request')
|
|
353
|
+
?? stringField(parsed, 'message')
|
|
354
|
+
?? stringField(parsed, 'text');
|
|
355
|
+
if (!request) {
|
|
356
|
+
throw new Error('Consensus input requires a non-empty request field');
|
|
357
|
+
}
|
|
358
|
+
const answers = isRecord(parsed.answers) ? parsed.answers : {};
|
|
359
|
+
const tokenTypeText = stringField(answers, 'token_type') ?? stringField(parsed, 'token_type');
|
|
360
|
+
const tokenType = coerceTokenType(tokenTypeText);
|
|
361
|
+
if (tokenTypeText && !tokenType) {
|
|
362
|
+
throw new Error(`Unsupported token type: ${tokenTypeText}`);
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
session_id: stringField(parsed, 'session_id'),
|
|
366
|
+
request,
|
|
367
|
+
answers: tokenType ? { token_type: tokenType } : undefined,
|
|
368
|
+
conversation_id: stringField(parsed, 'conversation_id') ?? stringField(parsed, 'conversation'),
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function coerceTokenType(value) {
|
|
372
|
+
if (value === 'tunnel-token' || value === 'api-token') {
|
|
373
|
+
return value;
|
|
374
|
+
}
|
|
375
|
+
return undefined;
|
|
376
|
+
}
|
|
377
|
+
function defaultCredentialLabel(providerId, secretType) {
|
|
378
|
+
const providerLabel = providerId
|
|
379
|
+
.split(/[-_.]/g)
|
|
380
|
+
.filter(Boolean)
|
|
381
|
+
.map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
|
|
382
|
+
.join(' ');
|
|
383
|
+
const secretLabel = secretType
|
|
384
|
+
.split(/[-_.]/g)
|
|
385
|
+
.filter(Boolean)
|
|
386
|
+
.map((part) => part.toLowerCase() === 'api' ? 'API' : `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
|
|
387
|
+
.join(' ');
|
|
388
|
+
return `${providerLabel} ${secretLabel}`;
|
|
389
|
+
}
|
|
390
|
+
function readInputPayload(args, usage) {
|
|
391
|
+
const raw = readOption(args, '--input');
|
|
392
|
+
if (!raw) {
|
|
393
|
+
throw new Error(`Usage: ${usage}`);
|
|
394
|
+
}
|
|
395
|
+
return JSON.parse(raw);
|
|
396
|
+
}
|
|
397
|
+
function writeJson(value) {
|
|
398
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
399
|
+
}
|
|
400
|
+
function printHelp() {
|
|
401
|
+
process.stdout.write(`udfs - Undefineds Pod data semantics tool
|
|
402
|
+
|
|
403
|
+
Usage:
|
|
404
|
+
udfs schema list
|
|
405
|
+
udfs schema search --query <text>
|
|
406
|
+
udfs schema describe <uri>
|
|
407
|
+
udfs schema classes [--uri <uri>]
|
|
408
|
+
udfs schema predicates [--uri <uri>] [--field <field>]
|
|
409
|
+
udfs consensus --input '{"session_id":"sess_123","request":"我要保存这个 Cloudflare token","answers":{"token_type":"tunnel-token"}}' --json
|
|
410
|
+
udfs storage validate --input '<mutation-json>'
|
|
411
|
+
|
|
412
|
+
Runtime:
|
|
413
|
+
Remote Consensus uses UDFS_CONSENSUS_BASE_URL plus UDFS_CONSENSUS_TOKEN when injected by LinX/linx-lite.
|
|
414
|
+
Do not pass user API keys on the command line.
|
|
415
|
+
`);
|
|
416
|
+
}
|
|
417
|
+
function printConsensusHelp() {
|
|
418
|
+
process.stdout.write(`udfs consensus - Ask Consensus how a storage request should be represented
|
|
419
|
+
|
|
420
|
+
Usage:
|
|
421
|
+
udfs consensus --input '{"session_id":"sess_123","request":"我要保存这个 Cloudflare token","answers":{"token_type":"tunnel-token"}}' --json
|
|
422
|
+
|
|
423
|
+
Runtime:
|
|
424
|
+
Remote Consensus uses UDFS_CONSENSUS_BASE_URL plus UDFS_CONSENSUS_TOKEN when injected by LinX/linx-lite.
|
|
425
|
+
`);
|
|
426
|
+
}
|
|
427
|
+
main(process.argv.slice(2)).catch((error) => {
|
|
428
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
429
|
+
process.exitCode = 1;
|
|
430
|
+
});
|
|
@@ -3,6 +3,8 @@ export declare const chatRepository: import("@undefineds.co/drizzle-solid/dist/c
|
|
|
3
3
|
title: 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>;
|
|
5
5
|
avatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
|
|
6
|
+
author: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
|
|
7
|
+
status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
|
|
6
8
|
starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
|
|
7
9
|
muted: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
|
|
8
10
|
unreadCount: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"integer", null, false, true>;
|
|
@@ -19,6 +21,8 @@ export declare const chatRepository: import("@undefineds.co/drizzle-solid/dist/c
|
|
|
19
21
|
title: string;
|
|
20
22
|
description: string;
|
|
21
23
|
avatarUrl: string;
|
|
24
|
+
author: string;
|
|
25
|
+
status: string;
|
|
22
26
|
starred: boolean;
|
|
23
27
|
muted: boolean;
|
|
24
28
|
unreadCount: number;
|
|
@@ -35,6 +39,8 @@ export declare const chatRepository: import("@undefineds.co/drizzle-solid/dist/c
|
|
|
35
39
|
id?: string | undefined;
|
|
36
40
|
description?: string | undefined;
|
|
37
41
|
avatarUrl?: string | undefined;
|
|
42
|
+
author?: string | undefined;
|
|
43
|
+
status?: string | undefined;
|
|
38
44
|
starred?: boolean | undefined;
|
|
39
45
|
muted?: boolean | undefined;
|
|
40
46
|
unreadCount?: number | undefined;
|
|
@@ -51,6 +57,8 @@ export declare const chatRepository: import("@undefineds.co/drizzle-solid/dist/c
|
|
|
51
57
|
title?: string | undefined;
|
|
52
58
|
description?: string | null | undefined;
|
|
53
59
|
avatarUrl?: string | null | undefined;
|
|
60
|
+
author?: string | null | undefined;
|
|
61
|
+
status?: string | undefined;
|
|
54
62
|
starred?: boolean | null | undefined;
|
|
55
63
|
muted?: boolean | null | undefined;
|
|
56
64
|
unreadCount?: number | null | undefined;
|
package/dist/chat.schema.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export type ChatMemberRole = 'owner' | 'admin' | 'member';
|
|
2
|
+
export type ChatStatusType = 'active' | 'archived' | 'deleted';
|
|
3
|
+
export declare const ChatStatus: {
|
|
4
|
+
readonly ACTIVE: "active";
|
|
5
|
+
readonly ARCHIVED: "archived";
|
|
6
|
+
readonly DELETED: "deleted";
|
|
7
|
+
};
|
|
2
8
|
export interface ChatMetadata {
|
|
3
9
|
memberRoles?: Record<string, ChatMemberRole>;
|
|
4
10
|
}
|
|
@@ -24,6 +30,8 @@ export declare const chatResource: import("@undefineds.co/drizzle-solid/dist/cor
|
|
|
24
30
|
title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
|
|
25
31
|
description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
26
32
|
avatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
|
|
33
|
+
author: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
|
|
34
|
+
status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
|
|
27
35
|
starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
|
|
28
36
|
muted: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
|
|
29
37
|
unreadCount: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"integer", null, false, true>;
|
|
@@ -41,6 +49,8 @@ export declare const chatTable: import("@undefineds.co/drizzle-solid/dist/core/s
|
|
|
41
49
|
title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
|
|
42
50
|
description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
|
|
43
51
|
avatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
|
|
52
|
+
author: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
|
|
53
|
+
status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
|
|
44
54
|
starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
|
|
45
55
|
muted: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
|
|
46
56
|
unreadCount: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"integer", null, false, true>;
|
package/dist/chat.schema.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { boolean, object, podTable, string, text, timestamp, uri, id, integer } from '@undefineds.co/drizzle-solid';
|
|
2
2
|
import { UDFS, DCTerms, SCHEMA, MEETING, WF } from './namespaces.js';
|
|
3
|
+
import { chatResourceId } from './resource-id-defaults.js';
|
|
4
|
+
export const ChatStatus = {
|
|
5
|
+
ACTIVE: 'active',
|
|
6
|
+
ARCHIVED: 'archived',
|
|
7
|
+
DELETED: 'deleted',
|
|
8
|
+
};
|
|
3
9
|
/**
|
|
4
10
|
* Chat resource.
|
|
5
11
|
*
|
|
@@ -18,12 +24,14 @@ import { UDFS, DCTerms, SCHEMA, MEETING, WF } from './namespaces.js';
|
|
|
18
24
|
* - Threads stored as fragments in same file: /.data/chat/{id}/index.ttl#{threadId}
|
|
19
25
|
*/
|
|
20
26
|
export const chatResource = podTable('chats', {
|
|
21
|
-
id: id('id'),
|
|
27
|
+
id: id('id').default(chatResourceId),
|
|
22
28
|
// Display
|
|
23
29
|
title: string('title').predicate(DCTerms.title).notNull(),
|
|
24
30
|
description: string('description').predicate(DCTerms.description),
|
|
25
31
|
avatarUrl: uri('avatarUrl').predicate(SCHEMA.image),
|
|
26
32
|
// Chat state
|
|
33
|
+
author: uri('author').predicate(DCTerms.creator),
|
|
34
|
+
status: string('status').predicate(UDFS.status).notNull().default(ChatStatus.ACTIVE),
|
|
27
35
|
starred: boolean('starred').predicate(UDFS.favorite).default(false),
|
|
28
36
|
muted: boolean('muted').predicate(UDFS.muted).default(false),
|
|
29
37
|
unreadCount: integer('unreadCount').predicate(UDFS.unreadCount).default(0),
|
|
@@ -49,7 +57,6 @@ export const chatResource = podTable('chats', {
|
|
|
49
57
|
sparqlEndpoint: '/.data/chat/-/sparql',
|
|
50
58
|
type: MEETING.LongChat,
|
|
51
59
|
namespace: UDFS,
|
|
52
|
-
subjectTemplate: '{id}/index.ttl#this',
|
|
53
60
|
});
|
|
54
61
|
// Compatibility alias. New model code should prefer `chatResource`.
|
|
55
62
|
export const chatTable = chatResource;
|
package/dist/chat.utils.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { threadResource } from './thread.schema.js';
|
|
1
|
+
import { parsePodResourceRef } from '@undefineds.co/drizzle-solid';
|
|
2
|
+
import { commandKindFromResourceId, surfaceIdFromCommandResourceId, } from './resource-id-defaults.js';
|
|
4
3
|
export const toTimestamp = (value, fallback = 0) => {
|
|
5
4
|
if (value instanceof Date)
|
|
6
5
|
return value.getTime();
|
|
@@ -13,19 +12,35 @@ export const toTimestamp = (value, fallback = 0) => {
|
|
|
13
12
|
return fallback;
|
|
14
13
|
};
|
|
15
14
|
export function extractChatIdFromChatRef(chatRef) {
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
if (!chatRef)
|
|
16
|
+
return null;
|
|
17
|
+
const parsed = parsePodResourceRef({ config: { base: '/.data/chat/' } }, chatRef);
|
|
18
|
+
const resourceId = parsed?.resourceId ?? chatRef;
|
|
19
|
+
const direct = resourceId.match(/^([^/]+)\/index\.ttl#this$/);
|
|
20
|
+
if (direct)
|
|
21
|
+
return decodeURIComponent(direct[1]);
|
|
22
|
+
return surfaceIdFromCommandResourceId(resourceId);
|
|
18
23
|
}
|
|
19
24
|
export function extractThreadIdFromThreadRef(threadRef) {
|
|
20
|
-
|
|
25
|
+
if (!threadRef)
|
|
26
|
+
return null;
|
|
27
|
+
const parsed = parsePodResourceRef({ config: { base: '/.data/' } }, threadRef);
|
|
28
|
+
const resourceId = parsed?.resourceId ?? threadRef;
|
|
29
|
+
const hashIndex = resourceId.lastIndexOf('#');
|
|
30
|
+
return hashIndex >= 0 && hashIndex < resourceId.length - 1
|
|
31
|
+
? resourceId.slice(hashIndex + 1)
|
|
32
|
+
: resourceId;
|
|
21
33
|
}
|
|
22
34
|
export function extractChatThreadRef(uri) {
|
|
23
35
|
if (!uri)
|
|
24
36
|
return { chatId: null, threadId: null };
|
|
25
|
-
const parsed = parsePodResourceRef(
|
|
37
|
+
const parsed = parsePodResourceRef({ config: { base: '/.data/' } }, uri);
|
|
38
|
+
const resourceId = parsed?.resourceId ?? uri;
|
|
26
39
|
return {
|
|
27
|
-
chatId:
|
|
28
|
-
|
|
40
|
+
chatId: commandKindFromResourceId(resourceId) === 'chat'
|
|
41
|
+
? surfaceIdFromCommandResourceId(resourceId)
|
|
42
|
+
: null,
|
|
43
|
+
threadId: extractThreadIdFromThreadRef(resourceId),
|
|
29
44
|
};
|
|
30
45
|
}
|
|
31
46
|
export function resolveThreadChatId(thread) {
|
package/dist/index.d.ts
CHANGED
|
@@ -5,13 +5,16 @@ export * from './profile.repository';
|
|
|
5
5
|
export * from './profile.schema';
|
|
6
6
|
export { ContactGender, contactResource, contactTable, ContactClass, ContactType, isAgentContact, isGroupContact, normalizeContactGender, type ContactRow, type ContactInsert, type ContactUpdate, type ContactClassValue, type ContactGenderValue, type ContactTypeValue, } from './contact.schema';
|
|
7
7
|
export { contactRepository } from './contact.repository';
|
|
8
|
-
export { chatResource, chatTable, type ChatMetadata, type ChatMemberRole, type ChatRow, type ChatInsert, type ChatUpdate, } from './chat.schema';
|
|
8
|
+
export { ChatStatus, chatResource, chatTable, type ChatMetadata, type ChatMemberRole, type ChatStatusType, type ChatRow, type ChatInsert, type ChatUpdate, } from './chat.schema';
|
|
9
9
|
export { chatRepository } from './chat.repository';
|
|
10
10
|
export { extractChatIdFromChatRef, extractChatThreadRef, extractThreadIdFromThreadRef, resolveThreadChatId, toTimestamp, type ChatThreadRef, } from './chat.utils';
|
|
11
|
-
export { threadResource, threadTable, type ThreadRow, type ThreadInsert, type ThreadUpdate, } from './thread.schema';
|
|
11
|
+
export { ThreadStatus, threadResource, threadTable, type ThreadStatusType, type ThreadRow, type ThreadInsert, type ThreadUpdate, } from './thread.schema';
|
|
12
12
|
export { threadRepository } from './thread.repository';
|
|
13
|
-
export { messageResource, messageTable, type MessageRow, type MessageInsert, type MessageUpdate, } from './message.schema';
|
|
13
|
+
export { MessageRole, MessageStatus, messageResource, messageTable, type MessageRoleType, type MessageStatusType, type MessageRow, type MessageInsert, type MessageUpdate, } from './message.schema';
|
|
14
14
|
export { messageRepository } from './message.repository';
|
|
15
|
+
export { TaskStatus, TaskTriggerKind, taskResource, taskTable, type TaskStatusType, type TaskTriggerKindType, type TaskRow, type TaskInsert, type TaskUpdate, } from './task.schema';
|
|
16
|
+
export { RunStatus, RunStepType, runResource, runStepResource, runTable, runStepTable, type RunStatusType, type RunStepTypeValue, type RunRow, type RunInsert, type RunUpdate, type RunStepRow, type RunStepInsert, type RunStepUpdate, } from './run.schema';
|
|
17
|
+
export { chatResourceId, commandKindFromResourceId, dateParts, messageResourceId, parentDir, resourceKey, runResourceId, runStepResourceId, surfaceIdFromCommandResourceId, taskResourceId, threadResourceId, type CommandKind, type DateInput, type DateParts, } from './resource-id-defaults';
|
|
15
18
|
export { issueResource, issueTable, type IssueStatus, type IssuePriority, type IssueRow, type IssueInsert, type IssueUpdate, } from './issue.schema';
|
|
16
19
|
export { issueRepository } from './issue.repository';
|
|
17
20
|
export { MessageBlockType, MessageBlockStatus, type BaseMessageBlock, type PlaceholderMessageBlock, type MainTextMessageBlock, type ThinkingMessageBlock, type ImageMessageBlock, type CodeMessageBlock, type ToolMessageBlock, type FileMessageBlock, type ErrorMessageBlock, type CitationMessageBlock, type MessageBlock, type MessageRichContent, createMessageBlock, isBlockType, parseMessageBlocks, serializeMessageBlocks, } from './types/message-block';
|
|
@@ -41,6 +44,7 @@ export { aiModelResource, aiModelTable, type AIModelRow, type AIModelInsert, typ
|
|
|
41
44
|
export { agentStatusResource, agentStatusTable, aiConfigResource, aiConfigTable, indexedFileResource, indexedFileTable, vectorStoreResource, vectorStoreTable, type AgentStatusRow, type AgentStatusInsert, type AgentStatusUpdate, type AIConfigRow, type AIConfigInsert, type AIConfigUpdate as AIConfigResourceUpdate, type IndexedFileRow, type IndexedFileInsert, type IndexedFileUpdate, type VectorStoreRow, type VectorStoreInsert, type VectorStoreUpdate, } from './ai-runtime.schema';
|
|
42
45
|
export { aiConfigModelRef, aiConfigModelUri, aiConfigProviderRef, aiConfigProviderUri, buildAIConfigDisconnectPlan, buildAIConfigMutationPlan, buildAIConfigProviderStateMap, getAIConfigDefaultBaseUrl, getAIConfigProviderCatalog, getAIConfigProviderFamilyIds, getAIConfigProviderMetadata, getDefaultAIConfigCredentialId, normalizeAIConfigProviderId, normalizeAIConfigModelId, normalizeAIConfigResourceId, sameAIConfigProviderFamily, selectAIConfigCredential, type AIConfigModel, type AIConfigCredentialSelection, type AIConfigDisconnectPlan, type AIConfigMutationPlan, type AIConfigProviderCatalogEntry, type AIConfigProviderState, type AIConfigUpdate, type BuildAIConfigProviderStateMapOptions, } from './ai-config';
|
|
43
46
|
export { applySolidComunicaPatches, } from './comunica-patches';
|
|
47
|
+
export { credentialDescriptor, createPodModelDescriptorRegistry, createPodSchema, createPodStorage, officialPodModelDescriptors, podSchema, type PodModelDescriptor, type PodModelDescriptorSource, type PodModelDescriptorTrustLevel, type PodModelFieldDescriptor, type PodModelFieldType, type PodModelMergePolicy, type PodSchemaClassEntry, type PodSchemaPredicateEntry, type PodSchemaSearchEntry, type PodStorageCommitResult, type PodStorageMutationPlan, type PodStorageValidationResult, } from './pod-storage-descriptor';
|
|
44
48
|
export { createRepositoryDescriptor, definePodRepository, initSolidResources, initSolidTables, type AnyPodResource, type AnyPodTable, type PodRepositoryDescriptor, type RepositoryCacheOptions, type RepositoryInvalidations, type RepositoryScope, type SolidDatabase, } from './repository';
|
|
45
49
|
export { importJobSchema } from './import';
|
|
46
50
|
export { eq, ne, and, or, drizzle } from '@undefineds.co/drizzle-solid';
|