@proteos/sdk 0.18.1

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.
Files changed (94) hide show
  1. package/LICENSE +40 -0
  2. package/dist/chunk-7RGN4E22.cjs +1185 -0
  3. package/dist/chunk-7RGN4E22.cjs.map +1 -0
  4. package/dist/chunk-XJP5WCRZ.js +1125 -0
  5. package/dist/chunk-XJP5WCRZ.js.map +1 -0
  6. package/dist/index.cjs +2384 -0
  7. package/dist/index.cjs.map +1 -0
  8. package/dist/index.d.cts +5225 -0
  9. package/dist/index.d.ts +5225 -0
  10. package/dist/index.js +2146 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/meta/index.cjs +204 -0
  13. package/dist/meta/index.cjs.map +1 -0
  14. package/dist/meta/index.d.cts +2 -0
  15. package/dist/meta/index.d.ts +2 -0
  16. package/dist/meta/index.js +3 -0
  17. package/dist/meta/index.js.map +1 -0
  18. package/dist/types-BNsjfU8N.d.cts +3299 -0
  19. package/dist/types-BNsjfU8N.d.ts +3299 -0
  20. package/package.json +86 -0
  21. package/src/agent/agents.ts +53 -0
  22. package/src/agent/index.ts +134 -0
  23. package/src/agent/mcp-servers.ts +102 -0
  24. package/src/agent/prompts.ts +80 -0
  25. package/src/agent/session-types.ts +397 -0
  26. package/src/agent/sessions.ts +197 -0
  27. package/src/agent/skills.ts +89 -0
  28. package/src/agent/tools.ts +53 -0
  29. package/src/agent/types.ts +362 -0
  30. package/src/auth/index.ts +111 -0
  31. package/src/auth/me.ts +46 -0
  32. package/src/auth/organizations.ts +128 -0
  33. package/src/auth/platform-entities.ts +78 -0
  34. package/src/auth/roles.ts +213 -0
  35. package/src/auth/types.ts +294 -0
  36. package/src/auth/users.ts +226 -0
  37. package/src/client.ts +441 -0
  38. package/src/connector/index.ts +120 -0
  39. package/src/connector/types.ts +150 -0
  40. package/src/conversation/index.ts +297 -0
  41. package/src/conversation/types.ts +590 -0
  42. package/src/conversation/voice.ts +123 -0
  43. package/src/data/index.ts +53 -0
  44. package/src/data/queries.ts +66 -0
  45. package/src/data/records.ts +122 -0
  46. package/src/data/types.ts +89 -0
  47. package/src/errors.ts +148 -0
  48. package/src/events/index.ts +172 -0
  49. package/src/events/types.ts +77 -0
  50. package/src/functions/actions.ts +95 -0
  51. package/src/functions/index.ts +32 -0
  52. package/src/functions/types.ts +71 -0
  53. package/src/http/index.ts +2 -0
  54. package/src/http/query-params.ts +106 -0
  55. package/src/index.ts +598 -0
  56. package/src/iterator.ts +183 -0
  57. package/src/knowledge/graph.ts +35 -0
  58. package/src/knowledge/index.ts +104 -0
  59. package/src/knowledge/labels.ts +70 -0
  60. package/src/knowledge/links.ts +65 -0
  61. package/src/knowledge/nodes.ts +198 -0
  62. package/src/knowledge/record-links.ts +66 -0
  63. package/src/knowledge/types.ts +569 -0
  64. package/src/meta/apps.ts +107 -0
  65. package/src/meta/components.ts +124 -0
  66. package/src/meta/currency/index.ts +202 -0
  67. package/src/meta/entities.ts +193 -0
  68. package/src/meta/filters.ts +76 -0
  69. package/src/meta/index.ts +227 -0
  70. package/src/meta/layout/common-props.ts +93 -0
  71. package/src/meta/layout/control-registry.json +70 -0
  72. package/src/meta/layout/control-registry.ts +92 -0
  73. package/src/meta/layout/elements.ts +203 -0
  74. package/src/meta/layout/index.ts +41 -0
  75. package/src/meta/layout/page-layout.ts +35 -0
  76. package/src/meta/layout/size-value.ts +27 -0
  77. package/src/meta/list-views.ts +109 -0
  78. package/src/meta/lists.ts +104 -0
  79. package/src/meta/menu-configurations.ts +128 -0
  80. package/src/meta/modules.ts +159 -0
  81. package/src/meta/pages.ts +106 -0
  82. package/src/meta/types.ts +1115 -0
  83. package/src/meta/variables.ts +98 -0
  84. package/src/storage/files.ts +183 -0
  85. package/src/storage/index.ts +33 -0
  86. package/src/storage/types.ts +70 -0
  87. package/src/types/common.ts +143 -0
  88. package/src/types/index.ts +28 -0
  89. package/src/types/options.ts +95 -0
  90. package/src/workflow/executions.ts +99 -0
  91. package/src/workflow/index.ts +109 -0
  92. package/src/workflow/node-types.ts +50 -0
  93. package/src/workflow/types.ts +658 -0
  94. package/src/workflow/workflows.ts +152 -0
@@ -0,0 +1,183 @@
1
+ import type { ListOptions, ListResult } from './types/common.js'
2
+
3
+ /**
4
+ * Sentinel symbol indicating iteration is complete.
5
+ */
6
+ export const DONE = Symbol('DONE')
7
+ export type Done = typeof DONE
8
+
9
+ /**
10
+ * Function type for fetching a page of results.
11
+ * @typeParam T - The type of items in the list
12
+ * @typeParam O - The type of options for the list request
13
+ */
14
+ export type ListFn<T, O extends ListOptions> = (options: O) => Promise<ListResult<T>>
15
+
16
+ /**
17
+ * Default page size for pagination.
18
+ */
19
+ export const DEFAULT_PAGE_SIZE = 100
20
+
21
+ /**
22
+ * Async iterator for paginated resources.
23
+ * Provides Google Cloud-style iteration with automatic page fetching.
24
+ *
25
+ * @typeParam T - The type of items being iterated
26
+ * @typeParam O - The type of options for list requests
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * // Using for-await-of
31
+ * const iterator = new PageIterator(fetchEntities, { page_size: 50 });
32
+ * for await (const entity of iterator) {
33
+ * console.log(entity);
34
+ * }
35
+ *
36
+ * // Using next() directly
37
+ * const item = await iterator.next();
38
+ * if (item !== DONE) {
39
+ * console.log(item);
40
+ * }
41
+ *
42
+ * // Collecting all items
43
+ * const allItems = await iterator.all();
44
+ * ```
45
+ */
46
+ export class PageIterator<T, O extends ListOptions> implements AsyncIterable<T> {
47
+ private readonly listFn: ListFn<T, O>
48
+ private readonly options: O
49
+ // Pages are 0-indexed across all Proteos services. First fetch is page 0,
50
+ // last is pagesTotal - 1.
51
+ private page: number = 0
52
+ private buffer: T[] = []
53
+ private bufferIndex: number = 0
54
+ private pagesTotal: number | undefined
55
+
56
+ /**
57
+ * Creates a new PageIterator.
58
+ *
59
+ * @param listFn - Function to fetch a page of results
60
+ * @param options - Options for list requests (including pagination)
61
+ */
62
+ constructor(listFn: ListFn<T, O>, options: O) {
63
+ this.listFn = listFn
64
+ this.options = { ...options }
65
+
66
+ // Set default page size if not provided
67
+ if (!this.options.page_size) {
68
+ this.options.page_size = DEFAULT_PAGE_SIZE
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Returns the next item in the iterator.
74
+ * Returns DONE symbol when iteration is complete.
75
+ *
76
+ * @returns The next item or DONE
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * const item = await iterator.next();
81
+ * if (item !== DONE) {
82
+ * console.log(item);
83
+ * }
84
+ * ```
85
+ */
86
+ async next(): Promise<T | Done> {
87
+ // Return next item from buffer if available
88
+ if (this.bufferIndex < this.buffer.length) {
89
+ const item = this.buffer[this.bufferIndex]
90
+ this.bufferIndex++
91
+ return item as T
92
+ }
93
+
94
+ // Check if we've exhausted all pages. Pages are 0-indexed, so the last
95
+ // valid page is `pagesTotal - 1`; once `this.page` reaches `pagesTotal`
96
+ // there are no more to fetch.
97
+ if (this.pagesTotal !== undefined && this.page >= this.pagesTotal) {
98
+ return DONE
99
+ }
100
+
101
+ // Fetch next page
102
+ const result = await this.listFn({
103
+ ...this.options,
104
+ page: this.page,
105
+ })
106
+
107
+ // Update total pages from response
108
+ this.pagesTotal = result.meta.pages_total
109
+
110
+ // Empty page means we're done
111
+ if (result.data.length === 0) {
112
+ return DONE
113
+ }
114
+
115
+ // Update buffer and indices
116
+ this.buffer = result.data
117
+ this.bufferIndex = 1 // Start at 1 since we'll return index 0
118
+ this.page++
119
+
120
+ return this.buffer[0] as T
121
+ }
122
+
123
+ /**
124
+ * Collects all remaining items into an array.
125
+ * Useful when you need all items at once.
126
+ *
127
+ * @returns Array of all remaining items
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * const allEntities = await iterator.all();
132
+ * console.log(`Found ${allEntities.length} entities`);
133
+ * ```
134
+ */
135
+ async all(): Promise<T[]> {
136
+ const items: T[] = []
137
+
138
+ while (true) {
139
+ const item = await this.next()
140
+ if (item === DONE) {
141
+ break
142
+ }
143
+ items.push(item)
144
+ }
145
+
146
+ return items
147
+ }
148
+
149
+ /**
150
+ * Implements AsyncIterable for use with for-await-of loops.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * for await (const entity of iterator) {
155
+ * console.log(entity.name);
156
+ * }
157
+ * ```
158
+ */
159
+ async *[Symbol.asyncIterator](): AsyncIterator<T> {
160
+ while (true) {
161
+ const item = await this.next()
162
+ if (item === DONE) {
163
+ return
164
+ }
165
+ yield item
166
+ }
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Creates a PageIterator with the given list function and options.
172
+ * Convenience function for creating iterators.
173
+ *
174
+ * @param listFn - Function to fetch a page of results
175
+ * @param options - Options for list requests
176
+ * @returns A new PageIterator instance
177
+ */
178
+ export function createIterator<T, O extends ListOptions>(
179
+ listFn: ListFn<T, O>,
180
+ options: O,
181
+ ): PageIterator<T, O> {
182
+ return new PageIterator(listFn, options)
183
+ }
@@ -0,0 +1,35 @@
1
+ import type { ProteosClient } from '../client.js'
2
+ import type { GetGraphOptions, KnowledgeGraph } from './types.js'
3
+
4
+ const GRAPH_BASE_PATH = '/knowledge/v1/graph'
5
+
6
+ /**
7
+ * Service for the whole-org knowledge graph (bulk read backing the radiant graph
8
+ * view). One request returns lean nodes (with per-node label ids + degree),
9
+ * links, the org label set and the total node count.
10
+ */
11
+ export interface GraphService {
12
+ /**
13
+ * Reads the whole org graph in one payload. `options.label_ids` prunes to
14
+ * nodes carrying ANY of the given labels (union); omitted returns everything.
15
+ */
16
+ get(options?: GetGraphOptions): Promise<KnowledgeGraph>
17
+ }
18
+
19
+ /**
20
+ * Implementation of GraphService.
21
+ */
22
+ export class GraphServiceImpl implements GraphService {
23
+ constructor(private readonly client: ProteosClient) {}
24
+
25
+ async get(options: GetGraphOptions = {}): Promise<KnowledgeGraph> {
26
+ // The server reads label_ids as a single comma-separated query param (the
27
+ // query binder takes only the first value of a repeated param), so the
28
+ // union list is joined here rather than appended as repeated params.
29
+ const query: { label_ids?: string } = {}
30
+ if (options.label_ids && options.label_ids.length > 0) {
31
+ query.label_ids = options.label_ids.join(',')
32
+ }
33
+ return this.client.requestWithQuery<KnowledgeGraph>('GET', GRAPH_BASE_PATH, query)
34
+ }
35
+ }
@@ -0,0 +1,104 @@
1
+ import type { ProteosClient } from '../client.js'
2
+ import { type GraphService, GraphServiceImpl } from './graph.js'
3
+ import { type LabelService, LabelServiceImpl } from './labels.js'
4
+ import { type LinkService, LinkServiceImpl } from './links.js'
5
+ import { type NodeService, NodeServiceImpl } from './nodes.js'
6
+ import { type RecordLinkService, RecordLinkServiceImpl } from './record-links.js'
7
+
8
+ /**
9
+ * Facade for the knowledge-service (graph-native knowledge base: nodes, typed
10
+ * links, labels, content sub-resource, keyword search and neighbor traversal).
11
+ *
12
+ * Usage:
13
+ * ```ts
14
+ * const client = new ProteosClient({ baseUrl, tokenProvider });
15
+ * const knowledge = new KnowledgeClient(client);
16
+ * const node = await knowledge.nodes.create({ title: 'ADR 1', type: 'markdown', status: 'draft', content: '# ...' });
17
+ * const hits = await knowledge.nodes.search({ query: 'invoicing' });
18
+ * ```
19
+ */
20
+ export class KnowledgeClient {
21
+ readonly nodes: NodeService
22
+ readonly links: LinkService
23
+ /** Node→record edges (links to data-service records): `knowledge.recordLinks`. */
24
+ readonly recordLinks: RecordLinkService
25
+ readonly labels: LabelService
26
+ /** Whole-org graph bulk read (radiant graph view): `knowledge.graph.get()`. */
27
+ readonly graph: GraphService
28
+
29
+ constructor(client: ProteosClient) {
30
+ this.nodes = new NodeServiceImpl(client)
31
+ this.links = new LinkServiceImpl(client)
32
+ this.recordLinks = new RecordLinkServiceImpl(client)
33
+ this.labels = new LabelServiceImpl(client)
34
+ this.graph = new GraphServiceImpl(client)
35
+ }
36
+ }
37
+
38
+ // Re-export service interfaces
39
+ export type { GraphService } from './graph.js'
40
+ export type { LabelService } from './labels.js'
41
+ export type { LinkService } from './links.js'
42
+ export type { NodeService } from './nodes.js'
43
+ export type { RecordLinkService } from './record-links.js'
44
+
45
+ // Re-export types
46
+ export type {
47
+ ContentMatch,
48
+ ContentResponse,
49
+ CreateLabelRequest,
50
+ CreateLinkRequest,
51
+ CreateNodeRequest,
52
+ CreateRecordLinkRequest,
53
+ EditContentRequest,
54
+ EditContentResponse,
55
+ GetGraphOptions,
56
+ InlineLinkRequest,
57
+ KnowledgeGraph,
58
+ KnowledgeGraphLink,
59
+ KnowledgeGraphNode,
60
+ KnowledgeLabel,
61
+ KnowledgeLink,
62
+ KnowledgeNode,
63
+ KnowledgeNodeLabel,
64
+ KnowledgeNodeMetadata,
65
+ KnowledgeNodeSearchResult,
66
+ KnowledgeRecordLink,
67
+ LinkType,
68
+ ListLabelsOptions,
69
+ ListLinksOptions,
70
+ ListNodesOptions,
71
+ ListRecordLinksOptions,
72
+ MatchMode,
73
+ NeighborDirection,
74
+ NeighborEdge,
75
+ NeighborNode,
76
+ NeighborsOptions,
77
+ NodeContentMatches,
78
+ NodeNeighborhood,
79
+ NodeOutline,
80
+ NodeStatus,
81
+ NodeType,
82
+ OutlineHeading,
83
+ OutlineRequest,
84
+ OutlineResponse,
85
+ SearchContentRequest,
86
+ SearchContentResponse,
87
+ SearchNodesRequest,
88
+ UpdateLabelRequest,
89
+ UpdateLinkRequest,
90
+ UpdateNodeRequest,
91
+ WriteContentResponse,
92
+ } from './types.js'
93
+
94
+ // Re-export Zod schemas
95
+ export {
96
+ KnowledgeLabelSchema,
97
+ KnowledgeLinkSchema,
98
+ KnowledgeNodeLabelSchema,
99
+ KnowledgeNodeMetadataSchema,
100
+ KnowledgeNodeSchema,
101
+ KnowledgeNodeSearchResultSchema,
102
+ KnowledgeRecordLinkSchema,
103
+ NodeNeighborhoodSchema,
104
+ } from './types.js'
@@ -0,0 +1,70 @@
1
+ import type { ProteosClient } from '../client.js'
2
+ import { PageIterator } from '../iterator.js'
3
+ import type { ListResult } from '../types/common.js'
4
+ import type {
5
+ CreateLabelRequest,
6
+ KnowledgeLabel,
7
+ ListLabelsOptions,
8
+ UpdateLabelRequest,
9
+ } from './types.js'
10
+
11
+ const LABELS_BASE_PATH = '/knowledge/v1/labels'
12
+
13
+ /**
14
+ * Service for knowledge labels (categorization handles). To attach/detach a
15
+ * label to a node, use the node service's label methods.
16
+ */
17
+ export interface LabelService {
18
+ /** Lists labels as an async iterator (pages are 0-indexed). */
19
+ list(options?: ListLabelsOptions): PageIterator<KnowledgeLabel, ListLabelsOptions>
20
+
21
+ /** Fetches a single page of labels. */
22
+ listPage(options?: ListLabelsOptions): Promise<ListResult<KnowledgeLabel>>
23
+
24
+ /** Gets a single label by id. */
25
+ get(id: string): Promise<KnowledgeLabel>
26
+
27
+ /** Creates a label. */
28
+ create(request: CreateLabelRequest): Promise<KnowledgeLabel>
29
+
30
+ /** Updates a label. */
31
+ update(id: string, request: UpdateLabelRequest): Promise<KnowledgeLabel>
32
+
33
+ /** Deletes a label; its node associations cascade. */
34
+ delete(id: string): Promise<void>
35
+ }
36
+
37
+ /**
38
+ * Implementation of LabelService.
39
+ */
40
+ export class LabelServiceImpl implements LabelService {
41
+ constructor(private readonly client: ProteosClient) {}
42
+
43
+ list(options: ListLabelsOptions = {}): PageIterator<KnowledgeLabel, ListLabelsOptions> {
44
+ return new PageIterator((opts) => this.listPage(opts), options)
45
+ }
46
+
47
+ async listPage(options: ListLabelsOptions = {}): Promise<ListResult<KnowledgeLabel>> {
48
+ return this.client.requestWithQuery<ListResult<KnowledgeLabel>>(
49
+ 'GET',
50
+ LABELS_BASE_PATH,
51
+ options,
52
+ )
53
+ }
54
+
55
+ async get(id: string): Promise<KnowledgeLabel> {
56
+ return this.client.request<KnowledgeLabel>('GET', `${LABELS_BASE_PATH}/${id}`)
57
+ }
58
+
59
+ async create(request: CreateLabelRequest): Promise<KnowledgeLabel> {
60
+ return this.client.request<KnowledgeLabel>('POST', LABELS_BASE_PATH, request)
61
+ }
62
+
63
+ async update(id: string, request: UpdateLabelRequest): Promise<KnowledgeLabel> {
64
+ return this.client.request<KnowledgeLabel>('PATCH', `${LABELS_BASE_PATH}/${id}`, request)
65
+ }
66
+
67
+ async delete(id: string): Promise<void> {
68
+ await this.client.request<void>('DELETE', `${LABELS_BASE_PATH}/${id}`)
69
+ }
70
+ }
@@ -0,0 +1,65 @@
1
+ import type { ProteosClient } from '../client.js'
2
+ import { PageIterator } from '../iterator.js'
3
+ import type { ListResult } from '../types/common.js'
4
+ import type {
5
+ CreateLinkRequest,
6
+ KnowledgeLink,
7
+ ListLinksOptions,
8
+ UpdateLinkRequest,
9
+ } from './types.js'
10
+
11
+ const LINKS_BASE_PATH = '/knowledge/v1/links'
12
+
13
+ /**
14
+ * Service for typed edges (links) between knowledge nodes.
15
+ */
16
+ export interface LinkService {
17
+ /** Lists links as an async iterator (pages are 0-indexed). */
18
+ list(options?: ListLinksOptions): PageIterator<KnowledgeLink, ListLinksOptions>
19
+
20
+ /** Fetches a single page of links. */
21
+ listPage(options?: ListLinksOptions): Promise<ListResult<KnowledgeLink>>
22
+
23
+ /** Gets a single link by id. */
24
+ get(id: string): Promise<KnowledgeLink>
25
+
26
+ /** Creates a typed edge between two nodes. */
27
+ create(request: CreateLinkRequest): Promise<KnowledgeLink>
28
+
29
+ /** Updates a link's type / description. */
30
+ update(id: string, request: UpdateLinkRequest): Promise<KnowledgeLink>
31
+
32
+ /** Deletes a link. */
33
+ delete(id: string): Promise<void>
34
+ }
35
+
36
+ /**
37
+ * Implementation of LinkService.
38
+ */
39
+ export class LinkServiceImpl implements LinkService {
40
+ constructor(private readonly client: ProteosClient) {}
41
+
42
+ list(options: ListLinksOptions = {}): PageIterator<KnowledgeLink, ListLinksOptions> {
43
+ return new PageIterator((opts) => this.listPage(opts), options)
44
+ }
45
+
46
+ async listPage(options: ListLinksOptions = {}): Promise<ListResult<KnowledgeLink>> {
47
+ return this.client.requestWithQuery<ListResult<KnowledgeLink>>('GET', LINKS_BASE_PATH, options)
48
+ }
49
+
50
+ async get(id: string): Promise<KnowledgeLink> {
51
+ return this.client.request<KnowledgeLink>('GET', `${LINKS_BASE_PATH}/${id}`)
52
+ }
53
+
54
+ async create(request: CreateLinkRequest): Promise<KnowledgeLink> {
55
+ return this.client.request<KnowledgeLink>('POST', LINKS_BASE_PATH, request)
56
+ }
57
+
58
+ async update(id: string, request: UpdateLinkRequest): Promise<KnowledgeLink> {
59
+ return this.client.request<KnowledgeLink>('PATCH', `${LINKS_BASE_PATH}/${id}`, request)
60
+ }
61
+
62
+ async delete(id: string): Promise<void> {
63
+ await this.client.request<void>('DELETE', `${LINKS_BASE_PATH}/${id}`)
64
+ }
65
+ }
@@ -0,0 +1,198 @@
1
+ import type { ProteosClient } from '../client.js'
2
+ import { PageIterator } from '../iterator.js'
3
+ import type { ListResult } from '../types/common.js'
4
+ import type {
5
+ ContentResponse,
6
+ CreateNodeRequest,
7
+ EditContentRequest,
8
+ EditContentResponse,
9
+ KnowledgeLabel,
10
+ KnowledgeNode,
11
+ KnowledgeNodeLabel,
12
+ KnowledgeNodeMetadata,
13
+ KnowledgeNodeSearchResult,
14
+ ListNodesOptions,
15
+ NeighborsOptions,
16
+ NodeNeighborhood,
17
+ OutlineRequest,
18
+ OutlineResponse,
19
+ SearchContentRequest,
20
+ SearchContentResponse,
21
+ SearchNodesRequest,
22
+ UpdateNodeRequest,
23
+ WriteContentResponse,
24
+ } from './types.js'
25
+
26
+ const NODES_BASE_PATH = '/knowledge/v1/nodes'
27
+
28
+ /**
29
+ * Service for knowledge nodes and their content, search, graph neighbors and
30
+ * labels. Reads return node metadata (no body) by default; the body is fetched
31
+ * explicitly with {@link NodeService.getContent}.
32
+ */
33
+ export interface NodeService {
34
+ /** Lists node metadata as an async iterator (pages are 0-indexed). */
35
+ list(options?: ListNodesOptions): PageIterator<KnowledgeNodeMetadata, ListNodesOptions>
36
+
37
+ /** Fetches a single page of node metadata. */
38
+ listPage(options?: ListNodesOptions): Promise<ListResult<KnowledgeNodeMetadata>>
39
+
40
+ /** Gets a node's metadata (body excluded). */
41
+ get(id: string): Promise<KnowledgeNodeMetadata>
42
+
43
+ /** Creates a node, optionally connecting it to labels/links in one call. */
44
+ create(request: CreateNodeRequest): Promise<KnowledgeNode>
45
+
46
+ /** Updates a node's metadata (title / status / summary). */
47
+ update(id: string, request: UpdateNodeRequest): Promise<KnowledgeNodeMetadata>
48
+
49
+ /** Hard-deletes a node; its links and label associations cascade. */
50
+ delete(id: string): Promise<void>
51
+
52
+ /**
53
+ * Hybrid retrieval. Only `keyword` is wired today; `semantic`/`hybrid` throw a
54
+ * 501 ProteosError until embeddings land.
55
+ */
56
+ search(request: SearchNodesRequest): Promise<ListResult<KnowledgeNodeSearchResult>>
57
+
58
+ /** Depth-bounded graph walk from a node. */
59
+ neighbors(id: string, options?: NeighborsOptions): Promise<NodeNeighborhood>
60
+
61
+ /** Reads a node's raw content body plus its line count. */
62
+ getContent(id: string): Promise<ContentResponse>
63
+
64
+ /** Overwrites a node's content body. Rejects derived (file/url) nodes. */
65
+ writeContent(id: string, content: string): Promise<WriteContentResponse>
66
+
67
+ /** Applies a surgical anchored edit to a node's content body. */
68
+ editContent(id: string, request: EditContentRequest): Promise<EditContentResponse>
69
+
70
+ /**
71
+ * Maps each requested node's body by its markdown heading structure (one or
72
+ * several nodes) — skim a large node, then read just a section's line range.
73
+ */
74
+ getOutline(request: OutlineRequest): Promise<OutlineResponse>
75
+
76
+ /** Greps each requested node's body for a pattern, with matching lines + context. */
77
+ searchContent(request: SearchContentRequest): Promise<SearchContentResponse>
78
+
79
+ /** Lists the labels attached to a node. */
80
+ listLabels(id: string): Promise<KnowledgeLabel[]>
81
+
82
+ /** Attaches an existing label to a node. */
83
+ attachLabel(id: string, labelId: string): Promise<KnowledgeNodeLabel>
84
+
85
+ /** Detaches a label from a node. */
86
+ detachLabel(id: string, labelId: string): Promise<void>
87
+ }
88
+
89
+ /**
90
+ * Implementation of NodeService.
91
+ */
92
+ export class NodeServiceImpl implements NodeService {
93
+ constructor(private readonly client: ProteosClient) {}
94
+
95
+ list(options: ListNodesOptions = {}): PageIterator<KnowledgeNodeMetadata, ListNodesOptions> {
96
+ return new PageIterator((opts) => this.listPage(opts), options)
97
+ }
98
+
99
+ async listPage(options: ListNodesOptions = {}): Promise<ListResult<KnowledgeNodeMetadata>> {
100
+ // The server reads label_ids as a single comma-separated query param (the query
101
+ // binder takes only the first value of a repeated param), so the union list is
102
+ // joined here rather than appended as repeated params (mirrors GraphService.get).
103
+ const { label_ids, ...rest } = options
104
+ const query: Record<string, unknown> = { ...rest }
105
+ if (label_ids && label_ids.length > 0) {
106
+ query.label_ids = label_ids.join(',')
107
+ }
108
+ return this.client.requestWithQuery<ListResult<KnowledgeNodeMetadata>>(
109
+ 'GET',
110
+ NODES_BASE_PATH,
111
+ query,
112
+ )
113
+ }
114
+
115
+ async get(id: string): Promise<KnowledgeNodeMetadata> {
116
+ return this.client.request<KnowledgeNodeMetadata>('GET', `${NODES_BASE_PATH}/${id}`)
117
+ }
118
+
119
+ async create(request: CreateNodeRequest): Promise<KnowledgeNode> {
120
+ return this.client.request<KnowledgeNode>('POST', NODES_BASE_PATH, request)
121
+ }
122
+
123
+ async update(id: string, request: UpdateNodeRequest): Promise<KnowledgeNodeMetadata> {
124
+ return this.client.request<KnowledgeNodeMetadata>('PATCH', `${NODES_BASE_PATH}/${id}`, request)
125
+ }
126
+
127
+ async delete(id: string): Promise<void> {
128
+ await this.client.request<void>('DELETE', `${NODES_BASE_PATH}/${id}`)
129
+ }
130
+
131
+ async search(request: SearchNodesRequest): Promise<ListResult<KnowledgeNodeSearchResult>> {
132
+ return this.client.request<ListResult<KnowledgeNodeSearchResult>>(
133
+ 'POST',
134
+ `${NODES_BASE_PATH}/actions/search`,
135
+ request,
136
+ )
137
+ }
138
+
139
+ async neighbors(id: string, options: NeighborsOptions = {}): Promise<NodeNeighborhood> {
140
+ return this.client.requestWithQuery<NodeNeighborhood>(
141
+ 'GET',
142
+ `${NODES_BASE_PATH}/${id}/neighbors`,
143
+ options,
144
+ )
145
+ }
146
+
147
+ async getContent(id: string): Promise<ContentResponse> {
148
+ return this.client.request<ContentResponse>('GET', `${NODES_BASE_PATH}/${id}/content`)
149
+ }
150
+
151
+ async writeContent(id: string, content: string): Promise<WriteContentResponse> {
152
+ return this.client.request<WriteContentResponse>('PUT', `${NODES_BASE_PATH}/${id}/content`, {
153
+ content,
154
+ })
155
+ }
156
+
157
+ async editContent(id: string, request: EditContentRequest): Promise<EditContentResponse> {
158
+ return this.client.request<EditContentResponse>(
159
+ 'POST',
160
+ `${NODES_BASE_PATH}/${id}/content/actions/edit`,
161
+ request,
162
+ )
163
+ }
164
+
165
+ async getOutline(request: OutlineRequest): Promise<OutlineResponse> {
166
+ return this.client.request<OutlineResponse>(
167
+ 'POST',
168
+ `${NODES_BASE_PATH}/content/actions/outline`,
169
+ request,
170
+ )
171
+ }
172
+
173
+ async searchContent(request: SearchContentRequest): Promise<SearchContentResponse> {
174
+ return this.client.request<SearchContentResponse>(
175
+ 'POST',
176
+ `${NODES_BASE_PATH}/content/actions/search`,
177
+ request,
178
+ )
179
+ }
180
+
181
+ async listLabels(id: string): Promise<KnowledgeLabel[]> {
182
+ const result = await this.client.request<{ data: KnowledgeLabel[] }>(
183
+ 'GET',
184
+ `${NODES_BASE_PATH}/${id}/labels`,
185
+ )
186
+ return result.data
187
+ }
188
+
189
+ async attachLabel(id: string, labelId: string): Promise<KnowledgeNodeLabel> {
190
+ return this.client.request<KnowledgeNodeLabel>('POST', `${NODES_BASE_PATH}/${id}/labels`, {
191
+ label_id: labelId,
192
+ })
193
+ }
194
+
195
+ async detachLabel(id: string, labelId: string): Promise<void> {
196
+ await this.client.request<void>('DELETE', `${NODES_BASE_PATH}/${id}/labels/${labelId}`)
197
+ }
198
+ }