@undefineds.co/models 0.2.37 → 0.2.39

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.
@@ -1,73 +1,12 @@
1
- export declare const chatRepository: 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
- id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
3
- title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
4
- description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
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>;
8
- starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
9
- muted: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
10
- unreadCount: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"integer", null, false, true>;
11
- contact: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
12
- participants: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", false, false>;
13
- metadata: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"object", null, false, false>;
14
- lastActiveAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
15
- lastMessage: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
16
- lastMessagePreview: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
17
- createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
18
- updatedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
19
- }>>, {
1
+ import { definePodRepository } from './repository';
2
+ import { chatResource, type ChatRow, type ChatInsert, type ChatUpdate } from './chat.schema';
3
+ export declare function buildChatRepositoryTarget(chatIdOrRef: string): {
20
4
  id: string;
21
- title: string;
22
- description: string;
23
- avatarUrl: string;
24
- author: string;
25
- status: string;
26
- starred: boolean;
27
- muted: boolean;
28
- unreadCount: number;
29
- contact: string;
30
- participants: string[];
31
- metadata: Record<string, unknown>;
32
- lastActiveAt: Date;
33
- lastMessage: string;
34
- lastMessagePreview: string;
35
- createdAt: Date;
36
- updatedAt: Date;
37
- }, {
38
- title: string;
39
- id?: string | undefined;
40
- description?: string | undefined;
41
- avatarUrl?: string | undefined;
42
- author?: string | undefined;
43
- status?: string | undefined;
44
- starred?: boolean | undefined;
45
- muted?: boolean | undefined;
46
- unreadCount?: number | undefined;
47
- contact?: string | undefined;
48
- participants?: string[] | undefined;
49
- metadata?: Record<string, unknown> | undefined;
50
- lastActiveAt?: Date | undefined;
51
- lastMessage?: string | undefined;
52
- lastMessagePreview?: string | undefined;
53
- createdAt?: Date | undefined;
54
- updatedAt?: Date | undefined;
55
- }, {
56
- id?: string | null | undefined;
57
- title?: string | undefined;
58
- description?: string | null | undefined;
59
- avatarUrl?: string | null | undefined;
60
- author?: string | null | undefined;
61
- status?: string | undefined;
62
- starred?: boolean | null | undefined;
63
- muted?: boolean | null | undefined;
64
- unreadCount?: number | null | undefined;
65
- contact?: string | null | undefined;
66
- participants?: string[] | null | undefined;
67
- metadata?: Record<string, unknown> | null | undefined;
68
- lastActiveAt?: Date | null | undefined;
69
- lastMessage?: string | null | undefined;
70
- lastMessagePreview?: string | null | undefined;
71
- createdAt?: Date | undefined;
72
- updatedAt?: Date | undefined;
73
- }, Record<string, unknown>>;
5
+ };
6
+ export declare function buildChatRepositoryIri(webIdOrPodUrl: string, chatIdOrRef: string): string;
7
+ export declare function readChatRepositoryId(chatRef: string | null | undefined): string | null;
8
+ export declare const chatRepository: ReturnType<typeof definePodRepository<typeof chatResource, ChatRow, ChatInsert, ChatUpdate>> & {
9
+ target: typeof buildChatRepositoryTarget;
10
+ iri: typeof buildChatRepositoryIri;
11
+ idFromRef: typeof readChatRepositoryId;
12
+ };
@@ -1,8 +1,23 @@
1
1
  import { definePodRepository } from './repository.js';
2
2
  import { chatResource } from './chat.schema.js';
3
+ import { extractChatIdFromChatRef } from './chat.utils.js';
4
+ export function buildChatRepositoryTarget(chatIdOrRef) {
5
+ return {
6
+ id: extractChatIdFromChatRef(chatIdOrRef) ?? chatIdOrRef,
7
+ };
8
+ }
9
+ export function buildChatRepositoryIri(webIdOrPodUrl, chatIdOrRef) {
10
+ return chatResource.buildIri(webIdOrPodUrl, buildChatRepositoryTarget(chatIdOrRef));
11
+ }
12
+ export function readChatRepositoryId(chatRef) {
13
+ return extractChatIdFromChatRef(chatRef);
14
+ }
3
15
  export const chatRepository = definePodRepository({
4
16
  namespace: 'chat',
5
17
  resource: chatResource,
6
18
  searchableFields: ['title', 'description'],
7
19
  defaultSort: { field: 'lastActiveAt', direction: 'desc' },
8
20
  });
21
+ chatRepository.target = buildChatRepositoryTarget;
22
+ chatRepository.iri = buildChatRepositoryIri;
23
+ chatRepository.idFromRef = readChatRepositoryId;
@@ -27,6 +27,7 @@ export interface ChatMetadata {
27
27
  */
28
28
  export declare const chatResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
29
29
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
30
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
30
31
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
31
32
  description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
32
33
  avatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
@@ -46,6 +47,7 @@ export declare const chatResource: import("@undefineds.co/drizzle-solid/dist/cor
46
47
  }>>;
47
48
  export declare const chatTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
48
49
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
50
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
49
51
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
50
52
  description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
51
53
  avatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
@@ -1,5 +1,5 @@
1
1
  import { boolean, object, podTable, string, text, timestamp, uri, id, integer } from '@undefineds.co/drizzle-solid';
2
- import { UDFS, DCTerms, SCHEMA, MEETING, WF } from './namespaces.js';
2
+ import { UDFS, DCTerms, SCHEMA, MEETING, WF, RDF, SIOC } from './namespaces.js';
3
3
  export const ChatStatus = {
4
4
  ACTIVE: 'active',
5
5
  ARCHIVED: 'archived',
@@ -24,6 +24,9 @@ export const ChatStatus = {
24
24
  */
25
25
  export const chatResource = podTable('chats', {
26
26
  id: id('id').default('{key}/index.ttl#this'),
27
+ // Resource config writes mee:LongChat; keep sioc:Container explicit so
28
+ // thread.parent can use sioc:has_parent for Chat and Task containers.
29
+ rdfType: uri('rdfType').array().predicate(RDF.type).notNull().default([SIOC.Container]),
27
30
  // Display
28
31
  title: string('title').predicate(DCTerms.title).notNull(),
29
32
  description: string('description').predicate(DCTerms.description),
@@ -13,4 +13,3 @@ export declare function buildChatTargetRef(chatIdOrRef: string): string;
13
13
  export declare function extractThreadIdFromThreadRef(threadRef: string | null | undefined): string | null;
14
14
  export declare function extractChatThreadRef(uri: string | null | undefined): ChatThreadRef;
15
15
  export declare function extractChatTargetRef(uri: string | null | undefined): ChatTargetRef;
16
- export declare function resolveThreadChatId(thread: Pick<Record<string, unknown>, 'chat'> | null | undefined): string | null;
@@ -72,6 +72,3 @@ export function extractChatTargetRef(uri) {
72
72
  }
73
73
  return { chatId: null, threadId: null, messageId: null };
74
74
  }
75
- export function resolveThreadChatId(thread) {
76
- return extractChatIdFromChatRef(typeof thread?.chat === 'string' ? thread.chat : null);
77
- }
@@ -28,7 +28,7 @@ export const fixtureChatDirectAI = {
28
28
  };
29
29
  export const fixtureThreadDirectAI = {
30
30
  id: 'thread-001',
31
- chat: 'https://pod.example/.data/chat/chat-direct-ai-1/index.ttl#this',
31
+ parent: 'https://pod.example/.data/chat/chat-direct-ai-1/index.ttl#this',
32
32
  title: 'Main thread',
33
33
  starred: false,
34
34
  workspace: 'https://pod.example/.data/agent-workspaces/secretary/ws-main/',
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export { ContactGender, contactResource, contactTable, ContactClass, ContactType
7
7
  export { contactRepository } from './contact.repository';
8
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
- export { buildChatTargetRef, extractChatIdFromChatRef, extractChatTargetRef, extractChatThreadRef, extractThreadIdFromThreadRef, resolveThreadChatId, toTimestamp, type ChatTargetRef, type ChatThreadRef, } from './chat.utils';
10
+ export { buildChatTargetRef, extractChatIdFromChatRef, extractChatTargetRef, extractChatThreadRef, extractThreadIdFromThreadRef, toTimestamp, type ChatTargetRef, type ChatThreadRef, } from './chat.utils';
11
11
  export { buildModelResourceId, buildModelResourceIri, buildModelResourceIriForDatabase, resolveModelResourceIri, resolveModelResourceIriForDatabase, type ModelResourceTarget, } from './resource-refs';
12
12
  export { ThreadStatus, threadResource, threadTable, type ThreadStatusType, type ThreadRow, type ThreadInsert, type ThreadUpdate, } from './thread.schema';
13
13
  export { threadRepository } from './thread.repository';
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ export { contactRepository } from './contact.repository.js';
19
19
  // Chat & Message - 聊天和消息
20
20
  export { ChatStatus, chatResource, chatTable, } from './chat.schema.js';
21
21
  export { chatRepository } from './chat.repository.js';
22
- export { buildChatTargetRef, extractChatIdFromChatRef, extractChatTargetRef, extractChatThreadRef, extractThreadIdFromThreadRef, resolveThreadChatId, toTimestamp, } from './chat.utils.js';
22
+ export { buildChatTargetRef, extractChatIdFromChatRef, extractChatTargetRef, extractChatThreadRef, extractThreadIdFromThreadRef, toTimestamp, } from './chat.utils.js';
23
23
  export { buildModelResourceId, buildModelResourceIri, buildModelResourceIriForDatabase, resolveModelResourceIri, resolveModelResourceIriForDatabase, } from './resource-refs.js';
24
24
  export { ThreadStatus, threadResource, threadTable, } from './thread.schema.js';
25
25
  export { threadRepository } from './thread.repository.js';
@@ -1,8 +1,7 @@
1
1
  export declare const messageRepository: 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
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
4
3
  chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
5
- thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
4
+ thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
6
5
  maker: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
7
6
  role: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
8
7
  content: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
@@ -24,7 +23,6 @@ export declare const messageRepository: import("@undefineds.co/drizzle-solid/dis
24
23
  updatedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
25
24
  }>>, {
26
25
  id: string;
27
- scope: string;
28
26
  chat: string;
29
27
  thread: string;
30
28
  maker: string;
@@ -47,11 +45,10 @@ export declare const messageRepository: import("@undefineds.co/drizzle-solid/dis
47
45
  createdAt: Date;
48
46
  updatedAt: Date;
49
47
  }, {
48
+ thread: string;
50
49
  content: string;
51
50
  id?: string | undefined;
52
- scope?: string | undefined;
53
51
  chat?: string | undefined;
54
- thread?: string | undefined;
55
52
  maker?: string | undefined;
56
53
  role?: string | undefined;
57
54
  richContent?: string | undefined;
@@ -72,9 +69,8 @@ export declare const messageRepository: import("@undefineds.co/drizzle-solid/dis
72
69
  updatedAt?: Date | undefined;
73
70
  }, {
74
71
  id?: string | null | undefined;
75
- scope?: string | null | undefined;
76
72
  chat?: string | null | undefined;
77
- thread?: string | null | undefined;
73
+ thread?: string | undefined;
78
74
  maker?: string | null | undefined;
79
75
  role?: string | undefined;
80
76
  content?: string | undefined;
@@ -15,13 +15,13 @@ export declare const MessageStatus: {
15
15
  * Message resource (aligned with xpod).
16
16
  *
17
17
  * Product semantics:
18
- * - Message belongs to a neutral product scope: usually a Chat, sometimes a
19
- * Task/thread execution timeline.
18
+ * - Message belongs to a Thread timeline. Chat messages also keep the Chat
19
+ * relation for Solid Chat compatibility and chat-bucketed storage.
20
20
  * - Chat remains the Solid Chat compatibility relation. When present, the
21
21
  * message is written under the Chat message bucket and projected through
22
22
  * wf:message.
23
- * - Thread is optional and appears when a message participates in an explicit
24
- * AI/task/branch timeline.
23
+ * - Task ownership is derived through message.thread -> thread.parent. Do not
24
+ * duplicate it as a custom Message scope relation.
25
25
  *
26
26
  * Storage structure:
27
27
  * - Location: /.data/chat/{chat|id}/{yyyy}/{MM}/{dd}/messages.ttl#{id}
@@ -30,9 +30,8 @@ export declare const MessageStatus: {
30
30
  */
31
31
  export declare const messageResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
32
32
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
33
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
34
33
  chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
35
- thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
34
+ thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
36
35
  maker: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
37
36
  role: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
38
37
  content: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
@@ -55,9 +54,8 @@ export declare const messageResource: import("@undefineds.co/drizzle-solid/dist/
55
54
  }>>;
56
55
  export declare const messageTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
57
56
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
58
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
59
57
  chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
60
- thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
58
+ thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
61
59
  maker: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
62
60
  role: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
63
61
  content: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
@@ -18,13 +18,13 @@ export const MessageStatus = {
18
18
  * Message resource (aligned with xpod).
19
19
  *
20
20
  * Product semantics:
21
- * - Message belongs to a neutral product scope: usually a Chat, sometimes a
22
- * Task/thread execution timeline.
21
+ * - Message belongs to a Thread timeline. Chat messages also keep the Chat
22
+ * relation for Solid Chat compatibility and chat-bucketed storage.
23
23
  * - Chat remains the Solid Chat compatibility relation. When present, the
24
24
  * message is written under the Chat message bucket and projected through
25
25
  * wf:message.
26
- * - Thread is optional and appears when a message participates in an explicit
27
- * AI/task/branch timeline.
26
+ * - Task ownership is derived through message.thread -> thread.parent. Do not
27
+ * duplicate it as a custom Message scope relation.
28
28
  *
29
29
  * Storage structure:
30
30
  * - Location: /.data/chat/{chat|id}/{yyyy}/{MM}/{dd}/messages.ttl#{id}
@@ -34,9 +34,7 @@ export const MessageStatus = {
34
34
  export const messageResource = podTable('chat_message', {
35
35
  id: id('id').default((key, row) => (renderDefaultIdTemplate(row?.chat
36
36
  ? 'chat/{chat.key}/{yyyy}/{MM}/{dd}/messages.ttl#{key}'
37
- : row?.thread
38
- ? '{thread.dir}/{yyyy}/{MM}/{dd}/messages.ttl#{key}'
39
- : '{scope.dir}/{yyyy}/{MM}/{dd}/messages.ttl#{key}', {
37
+ : '{thread.dir}/{yyyy}/{MM}/{dd}/messages.ttl#{key}', {
40
38
  key: resourceKey(key, 'msg'),
41
39
  row,
42
40
  links: {
@@ -44,12 +42,10 @@ export const messageResource = podTable('chat_message', {
44
42
  thread: threadResource,
45
43
  },
46
44
  }))),
47
- // Canonical product owner scope. The object can be a Chat, Task, Thread, or future command surface.
48
- scope: uri('scope').predicate(UDFS.inScope),
49
45
  // Solid Chat compatibility relation. In RDF this is an inverse link: <chat> wf:message <message>.
50
46
  chat: uri('chat').predicate(WF.message).inverse().link(chatResource),
51
- // Optional Thread relation. In RDF this is an inverse Solid Chat/SIOC link: <thread> sioc:has_member <message>.
52
- thread: uri('thread').predicate(SIOC.has_member).inverse().link(threadResource),
47
+ // Timeline relation. In RDF this is an inverse Solid Chat/SIOC link: <thread> sioc:has_member <message>.
48
+ thread: uri('thread').predicate(SIOC.has_member).inverse().notNull().link(threadResource),
53
49
  // maker is the entity URI of the message author:
54
50
  // - User: their WebID (https://user.pod/profile/card#me)
55
51
  // - AI: Agent URI (/agents/{id}/)
@@ -58,6 +58,7 @@ export const SCHEMA = createNamespace('schema', 'http://schema.org/', {
58
58
  url: 'url',
59
59
  });
60
60
  export const SIOC = createNamespace('sioc', 'http://rdfs.org/sioc/ns#', {
61
+ Container: 'Container',
61
62
  Post: 'Post',
62
63
  Thread: 'Thread',
63
64
  Forum: 'Forum',
@@ -132,7 +133,6 @@ export const UDFS = createNamespace('udfs', 'https://undefineds.co/ns#', {
132
133
  sortKey: 'sortKey',
133
134
  hasThread: 'hasThread',
134
135
  inThread: 'inThread',
135
- inScope: 'inScope',
136
136
  participants: 'participants',
137
137
  message: 'message',
138
138
  messageContent: 'messageContent',
package/dist/schema.d.ts CHANGED
@@ -80,6 +80,7 @@ export declare const solidResources: {
80
80
  }>>;
81
81
  chatResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
82
82
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
83
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
83
84
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
84
85
  description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
85
86
  avatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
@@ -116,9 +117,7 @@ export declare const solidResources: {
116
117
  }>>;
117
118
  threadResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
118
119
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
119
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
120
- chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
121
- task: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
120
+ parent: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
122
121
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
123
122
  status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
124
123
  starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
@@ -129,9 +128,8 @@ export declare const solidResources: {
129
128
  }>>;
130
129
  messageResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
131
130
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
132
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
133
131
  chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
134
- thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
132
+ thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
135
133
  maker: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
136
134
  role: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
137
135
  content: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
@@ -154,6 +152,7 @@ export declare const solidResources: {
154
152
  }>>;
155
153
  taskResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
156
154
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
155
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
157
156
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
158
157
  instruction: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
159
158
  prompt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
@@ -592,6 +591,7 @@ export declare const solidSchema: {
592
591
  }>>;
593
592
  chatTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
594
593
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
594
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
595
595
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
596
596
  description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
597
597
  avatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
@@ -628,9 +628,7 @@ export declare const solidSchema: {
628
628
  }>>;
629
629
  threadTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
630
630
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
631
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
632
- chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
633
- task: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
631
+ parent: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
634
632
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
635
633
  status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
636
634
  starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
@@ -641,9 +639,8 @@ export declare const solidSchema: {
641
639
  }>>;
642
640
  messageTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
643
641
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
644
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
645
642
  chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
646
- thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
643
+ thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
647
644
  maker: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
648
645
  role: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
649
646
  content: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
@@ -666,6 +663,7 @@ export declare const solidSchema: {
666
663
  }>>;
667
664
  taskTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
668
665
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
666
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
669
667
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
670
668
  instruction: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
671
669
  prompt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
@@ -17,6 +17,7 @@ export declare const TaskStatus: {
17
17
  */
18
18
  export declare const taskResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
19
19
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
20
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
20
21
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
21
22
  instruction: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
22
23
  prompt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
@@ -33,6 +34,7 @@ export declare const taskResource: import("@undefineds.co/drizzle-solid/dist/cor
33
34
  }>>;
34
35
  export declare const taskTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
35
36
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
37
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
36
38
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
37
39
  instruction: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
38
40
  prompt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
@@ -1,5 +1,5 @@
1
1
  import { id, object, podTable, string, text, timestamp, uri } from '@undefineds.co/drizzle-solid';
2
- import { DCTerms, UDFS } from './namespaces.js';
2
+ import { DCTerms, RDF, SIOC, UDFS } from './namespaces.js';
3
3
  export const TaskStatus = {
4
4
  OPEN: 'open',
5
5
  READY: 'ready',
@@ -18,6 +18,9 @@ export const TaskStatus = {
18
18
  */
19
19
  export const taskResource = podTable('task', {
20
20
  id: id('id').default('index.ttl#{key}'),
21
+ // Resource config writes udfs:Task; keep sioc:Container explicit so
22
+ // task-owned threads can use the same sioc:has_parent relation as chats.
23
+ rdfType: uri('rdfType').array().predicate(RDF.type).notNull().default([SIOC.Container]),
21
24
  title: string('title').predicate(DCTerms.title),
22
25
  instruction: text('instruction').predicate(UDFS.instruction).notNull(),
23
26
  prompt: text('prompt').predicate(UDFS.prompt),
@@ -1,49 +1,20 @@
1
- export declare const threadRepository: 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
- id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
3
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
4
- chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
5
- task: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
6
- title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
7
- status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
8
- starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
9
- workspace: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
10
- metadata: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"object", null, false, false>;
11
- createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
12
- updatedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
13
- }>>, {
14
- id: string;
15
- scope: string;
16
- chat: string;
17
- task: string;
18
- title: string;
19
- status: string;
20
- starred: boolean;
21
- workspace: string;
22
- metadata: Record<string, unknown>;
23
- createdAt: Date;
24
- updatedAt: Date;
25
- }, {
26
- id?: string | undefined;
27
- scope?: string | undefined;
28
- chat?: string | undefined;
29
- task?: string | undefined;
30
- title?: string | undefined;
31
- status?: string | undefined;
32
- starred?: boolean | undefined;
33
- workspace?: string | undefined;
34
- metadata?: Record<string, unknown> | undefined;
35
- createdAt?: Date | undefined;
36
- updatedAt?: Date | undefined;
37
- }, {
38
- id?: string | null | undefined;
39
- scope?: string | null | undefined;
40
- chat?: string | null | undefined;
41
- task?: string | null | undefined;
42
- title?: string | null | undefined;
43
- status?: string | undefined;
44
- starred?: boolean | null | undefined;
45
- workspace?: string | null | undefined;
46
- metadata?: Record<string, unknown> | null | undefined;
47
- createdAt?: Date | undefined;
48
- updatedAt?: Date | undefined;
49
- }, Record<string, unknown>>;
1
+ import { definePodRepository } from './repository';
2
+ import { threadResource, type ThreadRow, type ThreadInsert, type ThreadUpdate } from './thread.schema';
3
+ export interface ChatThreadTarget extends Record<string, unknown> {
4
+ parent: string;
5
+ id?: string;
6
+ }
7
+ export declare function buildChatThreadTarget(chatIdOrRef: string, threadIdOrRef?: string): ChatThreadTarget;
8
+ export declare function extractChatIdFromThread(row: Pick<ThreadRow, 'parent'> | null | undefined): string | null;
9
+ export declare function readThreadRepositoryChatId(threadRef: string | null | undefined): string | null;
10
+ export declare function readThreadRepositoryId(threadRef: string | null | undefined): string | null;
11
+ export declare function buildChatThreadIri(webIdOrPodUrl: string, chatIdOrRef: string, threadId: string): string;
12
+ export declare function buildChatThreadResourceId(chatIdOrRef: string, threadIdOrRef: string): string;
13
+ export declare const threadRepository: ReturnType<typeof definePodRepository<typeof threadResource, ThreadRow, ThreadInsert, ThreadUpdate>> & {
14
+ targetForChat: typeof buildChatThreadTarget;
15
+ iriForChat: typeof buildChatThreadIri;
16
+ idForChat: typeof buildChatThreadResourceId;
17
+ chatId: typeof extractChatIdFromThread;
18
+ chatIdFromRef: typeof readThreadRepositoryChatId;
19
+ idFromRef: typeof readThreadRepositoryId;
20
+ };
@@ -1,8 +1,39 @@
1
1
  import { definePodRepository } from './repository.js';
2
2
  import { threadResource } from './thread.schema.js';
3
+ import { buildChatTargetRef, extractChatIdFromChatRef, extractChatThreadRef, extractThreadIdFromThreadRef, } from './chat.utils.js';
4
+ export function buildChatThreadTarget(chatIdOrRef, threadIdOrRef) {
5
+ const parsedThread = extractChatThreadRef(threadIdOrRef);
6
+ const chatRef = parsedThread.chatId ?? chatIdOrRef;
7
+ const threadId = parsedThread.threadId ?? extractThreadIdFromThreadRef(threadIdOrRef) ?? threadIdOrRef;
8
+ return {
9
+ ...(threadId ? { id: threadId } : {}),
10
+ parent: buildChatTargetRef(chatRef),
11
+ };
12
+ }
13
+ export function extractChatIdFromThread(row) {
14
+ return extractChatIdFromChatRef(row?.parent);
15
+ }
16
+ export function readThreadRepositoryChatId(threadRef) {
17
+ return extractChatThreadRef(threadRef).chatId;
18
+ }
19
+ export function readThreadRepositoryId(threadRef) {
20
+ return extractThreadIdFromThreadRef(threadRef);
21
+ }
22
+ export function buildChatThreadIri(webIdOrPodUrl, chatIdOrRef, threadId) {
23
+ return threadResource.buildIri(webIdOrPodUrl, buildChatThreadTarget(chatIdOrRef, threadId));
24
+ }
25
+ export function buildChatThreadResourceId(chatIdOrRef, threadIdOrRef) {
26
+ return threadResource.buildId(buildChatThreadTarget(chatIdOrRef, threadIdOrRef));
27
+ }
3
28
  export const threadRepository = definePodRepository({
4
29
  namespace: 'thread',
5
30
  resource: threadResource,
6
31
  searchableFields: ['title'],
7
32
  defaultSort: { field: 'updatedAt', direction: 'desc' },
8
33
  });
34
+ threadRepository.targetForChat = buildChatThreadTarget;
35
+ threadRepository.iriForChat = buildChatThreadIri;
36
+ threadRepository.idForChat = buildChatThreadResourceId;
37
+ threadRepository.chatId = extractChatIdFromThread;
38
+ threadRepository.chatIdFromRef = readThreadRepositoryChatId;
39
+ threadRepository.idFromRef = readThreadRepositoryId;
@@ -8,16 +8,16 @@ export declare const ThreadStatus: {
8
8
  * Thread resource.
9
9
  *
10
10
  * Product semantics:
11
- * - Thread is the implicit concrete timeline/place under exactly one surface:
12
- * Chat for conversation timelines, or Task for task execution timelines.
13
- * - `scope` is the neutral LinX ownership relation for that surface. When the
14
- * scope is a Chat, also write `chat` so Solid Chat clients can keep using
15
- * sioc:has_parent. When the scope is a Task, also write `task` for workflow
16
- * indexes.
11
+ * - Thread is the implicit concrete timeline/place under exactly one parent
12
+ * container: Chat for conversation timelines, or Task for task execution
13
+ * timelines.
14
+ * - `parent` uses sioc:has_parent for both Chat and Task. Chat and Task are
15
+ * both modeled as sioc:Container, so Thread does not need parallel chat/task
16
+ * ownership fields.
17
17
  * - AI product runtime sessions map to Thread when they represent a concrete
18
18
  * conversation timeline/place/run.
19
- * - Thread carries workspace/place relations and runtime metadata. Chat only
20
- * identifies the counterpart/conversation object.
19
+ * - Thread carries workspace/place relations and runtime metadata. The parent
20
+ * container identifies the command surface/counterpart.
21
21
  * - Product/runtime-specific ids should stay in metadata as `runtimeSessionId`,
22
22
  * `runtime`, etc. Do not name the generic thread id `piSessionId`.
23
23
  *
@@ -33,9 +33,7 @@ export declare const ThreadStatus: {
33
33
  */
34
34
  export declare const threadResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
35
35
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
36
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
37
- chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
38
- task: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
36
+ parent: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
39
37
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
40
38
  status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
41
39
  starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
@@ -46,9 +44,7 @@ export declare const threadResource: import("@undefineds.co/drizzle-solid/dist/c
46
44
  }>>;
47
45
  export declare const threadTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
48
46
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
49
- scope: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
50
- chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
51
- task: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
47
+ parent: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
52
48
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
53
49
  status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
54
50
  starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
@@ -1,7 +1,5 @@
1
1
  import { uri, boolean, object, podTable, string, timestamp, id, renderDefaultIdTemplate } from '@undefineds.co/drizzle-solid';
2
2
  import { UDFS, DCTerms, SIOC } from './namespaces.js';
3
- import { chatResource } from './chat.schema.js';
4
- import { taskResource } from './task.schema.js';
5
3
  import { resourceKey } from './resource-id-defaults.js';
6
4
  export const ThreadStatus = {
7
5
  ACTIVE: 'active',
@@ -12,16 +10,16 @@ export const ThreadStatus = {
12
10
  * Thread resource.
13
11
  *
14
12
  * Product semantics:
15
- * - Thread is the implicit concrete timeline/place under exactly one surface:
16
- * Chat for conversation timelines, or Task for task execution timelines.
17
- * - `scope` is the neutral LinX ownership relation for that surface. When the
18
- * scope is a Chat, also write `chat` so Solid Chat clients can keep using
19
- * sioc:has_parent. When the scope is a Task, also write `task` for workflow
20
- * indexes.
13
+ * - Thread is the implicit concrete timeline/place under exactly one parent
14
+ * container: Chat for conversation timelines, or Task for task execution
15
+ * timelines.
16
+ * - `parent` uses sioc:has_parent for both Chat and Task. Chat and Task are
17
+ * both modeled as sioc:Container, so Thread does not need parallel chat/task
18
+ * ownership fields.
21
19
  * - AI product runtime sessions map to Thread when they represent a concrete
22
20
  * conversation timeline/place/run.
23
- * - Thread carries workspace/place relations and runtime metadata. Chat only
24
- * identifies the counterpart/conversation object.
21
+ * - Thread carries workspace/place relations and runtime metadata. The parent
22
+ * container identifies the command surface/counterpart.
25
23
  * - Product/runtime-specific ids should stay in metadata as `runtimeSessionId`,
26
24
  * `runtime`, etc. Do not name the generic thread id `piSessionId`.
27
25
  *
@@ -36,24 +34,14 @@ export const ThreadStatus = {
36
34
  * container URI here and store portable metadata with that container/resource.
37
35
  */
38
36
  export const threadResource = podTable('thread', {
39
- id: id('id').default((key, row) => (renderDefaultIdTemplate(row?.chat
40
- ? 'chat/{chat.key}/index.ttl#{key}'
41
- : row?.task
42
- ? 'task/{task.key}/index.ttl#{key}'
43
- : '{scope.dir}/index.ttl#{key}', {
44
- key: resourceKey(key, 'thread'),
45
- row,
46
- links: {
47
- chat: chatResource,
48
- task: taskResource,
49
- },
50
- }))),
51
- // Canonical product owner surface. The object can be a Chat, Task, or future command surface.
52
- scope: uri('scope').predicate(UDFS.inScope),
53
- // Solid Chat compatibility owner for conversation timelines. Do not set together with `task`.
54
- chat: uri('chat').predicate(SIOC.has_parent).link(chatResource),
55
- // Workflow compatibility/index owner for task execution timelines. Do not set together with `chat`.
56
- task: uri('task').predicate(UDFS.task).link(taskResource),
37
+ id: id('id').default((key, row) => {
38
+ return renderDefaultIdTemplate('{parent.dir}/index.ttl#{key}', {
39
+ key: resourceKey(key, 'thread'),
40
+ row,
41
+ });
42
+ }),
43
+ // Parent command surface/container. Chat and Task are both sioc:Container.
44
+ parent: uri('parent').predicate(SIOC.has_parent).notNull(),
57
45
  // Display / state
58
46
  title: string('title').predicate(DCTerms.title),
59
47
  status: string('status').predicate(UDFS.status).notNull().default(ThreadStatus.ACTIVE),
@@ -1,5 +1,6 @@
1
1
  /** Chat channel vocab (thin place/container). */
2
2
  export declare const ChatBaseVocab: {
3
+ readonly rdfType: string;
3
4
  readonly title: string;
4
5
  readonly description: string;
5
6
  readonly avatarUrl: string;
@@ -1,6 +1,7 @@
1
- import { DCTerms, SCHEMA, UDFS, WF } from '../namespaces.js';
1
+ import { DCTerms, RDF, SCHEMA, UDFS, WF } from '../namespaces.js';
2
2
  /** Chat channel vocab (thin place/container). */
3
3
  export const ChatBaseVocab = {
4
+ rdfType: RDF.type,
4
5
  // Display
5
6
  title: DCTerms.title,
6
7
  description: DCTerms.description,
@@ -1,5 +1,4 @@
1
1
  export declare const MessageVocab: {
2
- readonly scope: string;
3
2
  readonly thread: string;
4
3
  readonly chat: string;
5
4
  readonly maker: string;
@@ -1,7 +1,5 @@
1
1
  import { DCTerms, FOAF, SCHEMA, SIOC, UDFS, WF } from '../namespaces.js';
2
2
  export const MessageVocab = {
3
- // Existing
4
- scope: UDFS.inScope,
5
3
  thread: SIOC.has_member,
6
4
  chat: WF.message,
7
5
  maker: FOAF.maker,
@@ -1,7 +1,5 @@
1
1
  export declare const ThreadVocab: {
2
- readonly scope: string;
3
- readonly chat: string;
4
- readonly task: string;
2
+ readonly parent: string;
5
3
  readonly title: string;
6
4
  readonly starred: string;
7
5
  readonly metadata: string;
@@ -1,8 +1,6 @@
1
1
  import { DCTerms, SIOC, UDFS } from '../namespaces.js';
2
2
  export const ThreadVocab = {
3
- scope: UDFS.inScope,
4
- chat: SIOC.has_parent,
5
- task: UDFS.task,
3
+ parent: SIOC.has_parent,
6
4
  title: DCTerms.title,
7
5
  starred: UDFS.favorite,
8
6
  metadata: UDFS.metadata,
@@ -1,4 +1,5 @@
1
1
  export declare const TaskVocab: {
2
+ readonly rdfType: string;
2
3
  readonly title: string;
3
4
  readonly instruction: string;
4
5
  readonly prompt: string;
@@ -1,5 +1,6 @@
1
- import { AS, DCTerms, SCHEMA, UDFS } from '../namespaces.js';
1
+ import { AS, DCTerms, RDF, SCHEMA, UDFS } from '../namespaces.js';
2
2
  export const TaskVocab = {
3
+ rdfType: RDF.type,
3
4
  title: DCTerms.title,
4
5
  instruction: UDFS.instruction,
5
6
  prompt: UDFS.prompt,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@undefineds.co/models",
3
- "version": "0.2.37",
3
+ "version": "0.2.39",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -138,7 +138,7 @@ Use full URI relation fields:
138
138
  message.chat
139
139
  message.thread
140
140
  message.replyTo
141
- thread.chat
141
+ thread.parent
142
142
  run.thread
143
143
  run.task
144
144
  ```
@@ -148,7 +148,7 @@ Avoid persisted relation fields such as:
148
148
  ```ts
149
149
  message.chatId
150
150
  message.threadId
151
- thread.chatId
151
+ thread.parentId
152
152
  ```
153
153
 
154
154
  unless they are intentionally opaque literal protocol fields, not RDF links.
@@ -165,6 +165,15 @@ threadRepository.listByChatId(db, { chatId })
165
165
  These helpers should derive canonical Pod IRIs or base-relative ids internally.
166
166
  Do not force UI/CLI callers to manually construct Pod IRIs in every query.
167
167
 
168
+ When an application needs to group, filter, or address records through a linked
169
+ relation, push that need into the owning `models` repository/helper first. For
170
+ example, app code should call a `threadRepository.targetForChat(...)` or
171
+ `threadRepository.chatId(row)` style API instead of parsing
172
+ `thread.parent` strings locally. If the same relation-target operation appears
173
+ across multiple resources, then promote it down into `drizzle-solid` as a
174
+ generic ORM helper. Do not add resource-specific `extractXFromY` parsing
175
+ helpers in product shells.
176
+
168
177
  ## Chat, Task, Thread, Message, Run, Step
169
178
 
170
179
  Use these concepts consistently across products:
@@ -173,11 +182,10 @@ Use these concepts consistently across products:
173
182
  user is talking with.
174
183
  - `Task`: task-style command surface, parallel to Chat. It describes recurring,
175
184
  triggered, or one-off task intent.
176
- - `Thread`: implicit concrete timeline/place under exactly one command surface:
177
- Chat for conversation timelines, or Task for task execution timelines.
178
- - `Message`: human/runtime communication item in a command scope. It usually
179
- belongs to a Chat, but task/runtime messages may belong to a Task or Thread
180
- scope without inventing a Chat.
185
+ - `Thread`: implicit concrete timeline/place under exactly one parent
186
+ container. Chat and Task are both `sioc:Container`.
187
+ - `Message`: human/runtime communication item in a Thread. Chat messages also
188
+ keep the Chat relation for Solid Chat compatibility.
181
189
  - `Run`: one concrete execution attempt by an Agent Runtime.
182
190
  - `RunStep`: append-only execution facts for a Run.
183
191
 
@@ -191,17 +199,17 @@ Align with graph semantics:
191
199
 
192
200
  | Concept | Preferred RDF direction | Typical predicate |
193
201
  |---|---|---|
194
- | resource belongs to command scope | `resource -> scope` | `udfs:inScope` |
195
202
  | chat contains message | `chat -> message` | `wf:message` / project vocabulary |
196
- | chat owns thread | `thread -> chat` | `sioc:has_parent` for compatibility |
203
+ | thread parent container | `thread -> chat-or-task` | `sioc:has_parent` |
197
204
  | thread contains message | `thread -> message` | `sioc:has_member` or equivalent |
198
205
  | reply points to original | `replyMessage -> originalMessage` | `sioc:has_reply` / project predicate |
199
206
  | author/maker | `message -> maker` | `foaf:maker` |
200
207
 
201
- Use `udfs:inScope` for LinX product semantics when a Thread or Message can
202
- belong to either Chat or Task. Preserve Solid Chat compatibility by also writing
203
- `sioc:has_parent` for Chat-scoped Threads and `wf:message` for Chat-scoped
204
- Messages. Do not stretch Solid Chat predicates to mean Task ownership.
208
+ Use `sioc:has_parent` as the canonical Thread parent relation. Chat and Task
209
+ resources must be modeled as `sioc:Container`, so Thread does not need parallel
210
+ `chat`, `task`, or custom `scope` ownership fields. Preserve Solid Chat
211
+ compatibility with `wf:message` for Chat-contained Messages and
212
+ `sioc:has_member` for Thread-contained Messages.
205
213
 
206
214
  When inverse predicates are supported, use them for read/write symmetry. If the
207
215
  ORM cannot safely express the inverse write, put the relation writer in the