@love-moon/conductor-sdk 0.7.7 → 0.8.0
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/CHANGELOG.md +12 -0
- package/dist/api/index.d.ts +1 -1
- package/dist/api/shared.d.ts +1 -1
- package/dist/api/tasks.d.ts +37 -0
- package/dist/api/tasks.js +76 -0
- package/dist/backend/client.d.ts +33 -13
- package/dist/backend/client.js +43 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @love-moon/conductor-sdk
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 959dd1d: Add project-configured worker and reviewer task groups, task-group discovery in
|
|
8
|
+
the SDK and `conductor task group`, and a lightweight daemon protocol for
|
|
9
|
+
refreshing the project agent registry.
|
|
10
|
+
- fe76139: Add `conductor task create` for creating app tasks with title, prompt, backend,
|
|
11
|
+
project resolution, and optional parent task-card grouping. App tasks now
|
|
12
|
+
require an online compatible daemon, and grouping results are exposed to
|
|
13
|
+
callers so partial success is visible without retrying task creation.
|
|
14
|
+
|
|
3
15
|
## 0.7.7
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { ProjectsApi, type Project, type CreateProjectInput, type ListProjectsOptions, type ResolveProjectInput, } from './projects.js';
|
|
2
2
|
export { IssuesApi, type Issue, type ListIssuesInput, type CreateIssueInput, type UpdateIssueInput, type UpdateIssueStatusOptions, } from './issues.js';
|
|
3
|
-
export { TasksApi, type Task, type Message, type ListTasksInput, type SendTaskMessageOptions, type ListTaskMessagesOptions, type ScheduledMessage, type ScheduledMessageSchedule, type CreateScheduledMessageInput, } from './tasks.js';
|
|
3
|
+
export { TasksApi, type Task, type TaskGroupingResult, type TaskGroup, type TaskGroupMember, type Message, type ListTasksInput, type CreateTaskInput, type SendTaskMessageOptions, type ListTaskMessagesOptions, type ScheduledMessage, type ScheduledMessageSchedule, type CreateScheduledMessageInput, } from './tasks.js';
|
|
4
4
|
export { ProjectNotResolvedError, buildAuditMetadata, isBackendApiError, type ApiClient, type SdkClientOptions, } from './shared.js';
|
package/dist/api/shared.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BackendApiClient, BackendApiError } from '../backend/index.js';
|
|
2
|
-
export type ApiClient = Pick<BackendApiClient, 'listProjects' | 'createProject' | 'getProject' | 'updateProject' | 'patchProjectByQuery' | 'setDefaultProject' | 'matchProjectByPath' | 'listIssues' | 'getIssue' | 'createIssue' | 'patchIssue' | 'deleteIssue' | 'listTasks' | 'getTask' | 'listTaskMessages' | 'postTaskMessage' | 'postTaskInsert' | 'listScheduledMessages' | 'createScheduledMessage' | 'deleteScheduledMessage'>;
|
|
2
|
+
export type ApiClient = Pick<BackendApiClient, 'listProjects' | 'createProject' | 'getProject' | 'updateProject' | 'patchProjectByQuery' | 'setDefaultProject' | 'matchProjectByPath' | 'listIssues' | 'getIssue' | 'createIssue' | 'patchIssue' | 'deleteIssue' | 'listTasks' | 'createTask' | 'createAppTask' | 'getTask' | 'getTaskGroup' | 'listTaskMessages' | 'postTaskMessage' | 'postTaskInsert' | 'listScheduledMessages' | 'createScheduledMessage' | 'deleteScheduledMessage'>;
|
|
3
3
|
export interface SdkClientOptions {
|
|
4
4
|
/**
|
|
5
5
|
* Optional override for the SDK version stamped onto audit metadata. Falls
|
package/dist/api/tasks.d.ts
CHANGED
|
@@ -10,8 +10,14 @@ export interface Task {
|
|
|
10
10
|
sessionFilePath?: string | null;
|
|
11
11
|
createdAt?: string | null;
|
|
12
12
|
updatedAt?: string | null;
|
|
13
|
+
grouping?: TaskGroupingResult | null;
|
|
13
14
|
raw: Record<string, unknown>;
|
|
14
15
|
}
|
|
16
|
+
export interface TaskGroupingResult {
|
|
17
|
+
parentTaskId: string;
|
|
18
|
+
grouped: boolean;
|
|
19
|
+
warning?: string | null;
|
|
20
|
+
}
|
|
15
21
|
export interface Message {
|
|
16
22
|
id: string;
|
|
17
23
|
taskId?: string | null;
|
|
@@ -21,6 +27,21 @@ export interface Message {
|
|
|
21
27
|
createdAt?: string | null;
|
|
22
28
|
raw: Record<string, unknown>;
|
|
23
29
|
}
|
|
30
|
+
/** RFC 0033 — one member of a multi-agent task group. */
|
|
31
|
+
export interface TaskGroupMember {
|
|
32
|
+
taskId: string;
|
|
33
|
+
role: string | null;
|
|
34
|
+
agent: string | null;
|
|
35
|
+
title: string | null;
|
|
36
|
+
status: string | null;
|
|
37
|
+
backendType: string | null;
|
|
38
|
+
isSelf: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** RFC 0033 — the group a task belongs to (groupId null when standalone). */
|
|
41
|
+
export interface TaskGroup {
|
|
42
|
+
groupId: string | null;
|
|
43
|
+
members: TaskGroupMember[];
|
|
44
|
+
}
|
|
24
45
|
export type ScheduledMessageSchedule = {
|
|
25
46
|
mode: 'delay';
|
|
26
47
|
amount: number;
|
|
@@ -71,6 +92,14 @@ export interface ListTasksInput {
|
|
|
71
92
|
issueId?: string;
|
|
72
93
|
status?: string | string[];
|
|
73
94
|
}
|
|
95
|
+
export interface CreateTaskInput {
|
|
96
|
+
projectId: string;
|
|
97
|
+
title: string;
|
|
98
|
+
backendType?: string;
|
|
99
|
+
initialContent?: string;
|
|
100
|
+
parentTaskId?: string;
|
|
101
|
+
metadata?: Record<string, unknown>;
|
|
102
|
+
}
|
|
74
103
|
export interface SendTaskMessageOptions {
|
|
75
104
|
role?: string;
|
|
76
105
|
metadata?: Record<string, unknown>;
|
|
@@ -99,6 +128,14 @@ export declare class TasksApi {
|
|
|
99
128
|
constructor(client: ApiClient, options?: SdkClientOptions);
|
|
100
129
|
listTasks(input?: ListTasksInput): Promise<Task[]>;
|
|
101
130
|
getTask(taskId: string): Promise<Task>;
|
|
131
|
+
createTask(input: CreateTaskInput): Promise<Task>;
|
|
132
|
+
/**
|
|
133
|
+
* RFC 0033 — resolve the multi-agent group a task belongs to. Returns the
|
|
134
|
+
* group id (null if the task is standalone) and every sibling task with its
|
|
135
|
+
* role/agent. Agents use this to discover the task(s) they read from / send
|
|
136
|
+
* feedback to.
|
|
137
|
+
*/
|
|
138
|
+
getTaskGroup(taskId: string): Promise<TaskGroup>;
|
|
102
139
|
sendTaskMessage(taskId: string, content: string, options?: SendTaskMessageOptions): Promise<Message>;
|
|
103
140
|
/**
|
|
104
141
|
* Insert a mid-turn message into a running task. The message is delivered and
|
package/dist/api/tasks.js
CHANGED
|
@@ -4,6 +4,21 @@ const normalizeTask = (payload) => {
|
|
|
4
4
|
if (!id) {
|
|
5
5
|
throw new Error('Task payload missing id');
|
|
6
6
|
}
|
|
7
|
+
const groupingPayload = payload.grouping && typeof payload.grouping === 'object' && !Array.isArray(payload.grouping)
|
|
8
|
+
? payload.grouping
|
|
9
|
+
: null;
|
|
10
|
+
const groupingParentTaskId = groupingPayload
|
|
11
|
+
? groupingPayload.parentTaskId ?? groupingPayload.parent_task_id
|
|
12
|
+
: null;
|
|
13
|
+
const grouping = groupingParentTaskId && typeof groupingPayload?.grouped === 'boolean'
|
|
14
|
+
? {
|
|
15
|
+
parentTaskId: String(groupingParentTaskId),
|
|
16
|
+
grouped: groupingPayload.grouped,
|
|
17
|
+
warning: typeof groupingPayload.warning === 'string'
|
|
18
|
+
? groupingPayload.warning
|
|
19
|
+
: null,
|
|
20
|
+
}
|
|
21
|
+
: null;
|
|
7
22
|
return {
|
|
8
23
|
id,
|
|
9
24
|
projectId: payload.projectId !== undefined
|
|
@@ -23,9 +38,27 @@ const normalizeTask = (payload) => {
|
|
|
23
38
|
sessionFilePath: payload.sessionFilePath ?? payload.session_file_path ?? null,
|
|
24
39
|
createdAt: payload.createdAt ?? payload.created_at ?? null,
|
|
25
40
|
updatedAt: payload.updatedAt ?? payload.updated_at ?? null,
|
|
41
|
+
grouping,
|
|
26
42
|
raw: payload,
|
|
27
43
|
};
|
|
28
44
|
};
|
|
45
|
+
const asStringOrNull = (value) => typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
46
|
+
const normalizeTaskGroup = (payload) => {
|
|
47
|
+
const rawMembers = Array.isArray(payload?.members) ? payload.members : [];
|
|
48
|
+
const members = rawMembers.map((m) => ({
|
|
49
|
+
taskId: String(m?.task_id ?? m?.taskId ?? ''),
|
|
50
|
+
role: asStringOrNull(m?.role),
|
|
51
|
+
agent: asStringOrNull(m?.agent),
|
|
52
|
+
title: asStringOrNull(m?.title),
|
|
53
|
+
status: asStringOrNull(m?.status),
|
|
54
|
+
backendType: asStringOrNull(m?.backend_type ?? m?.backendType),
|
|
55
|
+
isSelf: Boolean(m?.is_self ?? m?.isSelf),
|
|
56
|
+
}));
|
|
57
|
+
return {
|
|
58
|
+
groupId: asStringOrNull(payload?.group_id ?? payload?.groupId),
|
|
59
|
+
members,
|
|
60
|
+
};
|
|
61
|
+
};
|
|
29
62
|
const normalizeMessage = (payload) => {
|
|
30
63
|
const id = payload.id ? String(payload.id) : payload.message_id ? String(payload.message_id) : '';
|
|
31
64
|
if (!id) {
|
|
@@ -129,6 +162,49 @@ export class TasksApi {
|
|
|
129
162
|
? summary.asObject()
|
|
130
163
|
: summary);
|
|
131
164
|
}
|
|
165
|
+
async createTask(input) {
|
|
166
|
+
const projectId = String(input?.projectId ?? '').trim();
|
|
167
|
+
const title = String(input?.title ?? '').trim();
|
|
168
|
+
if (!projectId) {
|
|
169
|
+
throw new Error('projectId is required');
|
|
170
|
+
}
|
|
171
|
+
if (!title) {
|
|
172
|
+
throw new Error('title is required');
|
|
173
|
+
}
|
|
174
|
+
const params = {
|
|
175
|
+
projectId,
|
|
176
|
+
title,
|
|
177
|
+
taskType: 'ai_task',
|
|
178
|
+
metadata: buildAuditMetadata(input.metadata, this.options),
|
|
179
|
+
};
|
|
180
|
+
if (input.backendType !== undefined) {
|
|
181
|
+
params.backendType = input.backendType;
|
|
182
|
+
}
|
|
183
|
+
if (input.initialContent !== undefined) {
|
|
184
|
+
params.initialContent = input.initialContent;
|
|
185
|
+
}
|
|
186
|
+
if (input.parentTaskId !== undefined) {
|
|
187
|
+
params.parentTaskId = input.parentTaskId;
|
|
188
|
+
}
|
|
189
|
+
const payload = await this.client.createAppTask(params);
|
|
190
|
+
return normalizeTask(typeof payload.asObject === 'function'
|
|
191
|
+
? payload.asObject()
|
|
192
|
+
: payload);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* RFC 0033 — resolve the multi-agent group a task belongs to. Returns the
|
|
196
|
+
* group id (null if the task is standalone) and every sibling task with its
|
|
197
|
+
* role/agent. Agents use this to discover the task(s) they read from / send
|
|
198
|
+
* feedback to.
|
|
199
|
+
*/
|
|
200
|
+
async getTaskGroup(taskId) {
|
|
201
|
+
const trimmed = String(taskId ?? '').trim();
|
|
202
|
+
if (!trimmed) {
|
|
203
|
+
throw new Error('taskId is required');
|
|
204
|
+
}
|
|
205
|
+
const payload = await this.client.getTaskGroup(trimmed);
|
|
206
|
+
return normalizeTaskGroup(payload);
|
|
207
|
+
}
|
|
132
208
|
async sendTaskMessage(taskId, content, options = {}) {
|
|
133
209
|
const trimmed = String(taskId ?? '').trim();
|
|
134
210
|
if (!trimmed) {
|
package/dist/backend/client.d.ts
CHANGED
|
@@ -4,6 +4,20 @@ export interface BackendClientOptions {
|
|
|
4
4
|
fetchImpl?: FetchFn;
|
|
5
5
|
timeoutMs?: number;
|
|
6
6
|
}
|
|
7
|
+
export interface BackendCreateTaskParams {
|
|
8
|
+
id?: string;
|
|
9
|
+
projectId: string;
|
|
10
|
+
title: string;
|
|
11
|
+
taskType?: string;
|
|
12
|
+
status?: string;
|
|
13
|
+
backendType?: string;
|
|
14
|
+
sessionId?: string | null;
|
|
15
|
+
sessionFilePath?: string | null;
|
|
16
|
+
initialContent?: string;
|
|
17
|
+
agentHost?: string;
|
|
18
|
+
parentTaskId?: string;
|
|
19
|
+
metadata?: Record<string, unknown>;
|
|
20
|
+
}
|
|
7
21
|
export type AgentCommitEvent = {
|
|
8
22
|
eventType: 'sdk_message';
|
|
9
23
|
taskId: string;
|
|
@@ -48,6 +62,11 @@ export declare class ProjectSummary {
|
|
|
48
62
|
static fromJSON(payload: Record<string, any>): ProjectSummary;
|
|
49
63
|
asObject(): Record<string, unknown>;
|
|
50
64
|
}
|
|
65
|
+
export interface TaskGroupingSummary {
|
|
66
|
+
parentTaskId: string;
|
|
67
|
+
grouped: boolean;
|
|
68
|
+
warning?: string | null;
|
|
69
|
+
}
|
|
51
70
|
export declare class TaskSummary {
|
|
52
71
|
readonly id: string;
|
|
53
72
|
readonly projectId: string | null;
|
|
@@ -58,7 +77,8 @@ export declare class TaskSummary {
|
|
|
58
77
|
readonly sessionFilePath?: string | null | undefined;
|
|
59
78
|
readonly createdAt?: string | null | undefined;
|
|
60
79
|
readonly updatedAt?: string | null | undefined;
|
|
61
|
-
|
|
80
|
+
readonly grouping?: (TaskGroupingSummary | null) | undefined;
|
|
81
|
+
constructor(id: string, projectId: string | null, title: string, status: string, backendType?: string | null | undefined, sessionId?: string | null | undefined, sessionFilePath?: string | null | undefined, createdAt?: string | null | undefined, updatedAt?: string | null | undefined, grouping?: (TaskGroupingSummary | null) | undefined);
|
|
62
82
|
static fromJSON(payload: Record<string, any>): TaskSummary;
|
|
63
83
|
}
|
|
64
84
|
export declare class BackendApiClient {
|
|
@@ -85,19 +105,19 @@ export declare class BackendApiClient {
|
|
|
85
105
|
projectId?: string;
|
|
86
106
|
status?: string;
|
|
87
107
|
}): Promise<TaskSummary[]>;
|
|
88
|
-
createTask(params:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
sessionFilePath?: string | null;
|
|
96
|
-
initialContent?: string;
|
|
97
|
-
agentHost?: string;
|
|
98
|
-
metadata?: Record<string, unknown>;
|
|
99
|
-
}): Promise<TaskSummary>;
|
|
108
|
+
createTask(params: BackendCreateTaskParams): Promise<TaskSummary>;
|
|
109
|
+
/**
|
|
110
|
+
* Create an app-managed task through the frontend pipeline. This route
|
|
111
|
+
* assigns daemon ownership and delivers initialContent; it is intentionally
|
|
112
|
+
* separate from the legacy agent/fire POST /tasks endpoint.
|
|
113
|
+
*/
|
|
114
|
+
createAppTask(params: BackendCreateTaskParams): Promise<TaskSummary>;
|
|
100
115
|
getTask(taskId: string): Promise<TaskSummary>;
|
|
116
|
+
/**
|
|
117
|
+
* GET /tasks/[taskId]/group — RFC 0033 task-group discovery. Returns the raw
|
|
118
|
+
* payload `{ group_id, members }`; the higher layer normalizes it.
|
|
119
|
+
*/
|
|
120
|
+
getTaskGroup(taskId: string): Promise<Record<string, any>>;
|
|
101
121
|
updateTask(taskId: string, params: {
|
|
102
122
|
projectId?: string;
|
|
103
123
|
title?: string;
|
package/dist/backend/client.js
CHANGED
|
@@ -62,7 +62,8 @@ export class TaskSummary {
|
|
|
62
62
|
sessionFilePath;
|
|
63
63
|
createdAt;
|
|
64
64
|
updatedAt;
|
|
65
|
-
|
|
65
|
+
grouping;
|
|
66
|
+
constructor(id, projectId, title, status, backendType, sessionId, sessionFilePath, createdAt, updatedAt, grouping) {
|
|
66
67
|
this.id = id;
|
|
67
68
|
this.projectId = projectId;
|
|
68
69
|
this.title = title;
|
|
@@ -72,6 +73,7 @@ export class TaskSummary {
|
|
|
72
73
|
this.sessionFilePath = sessionFilePath;
|
|
73
74
|
this.createdAt = createdAt;
|
|
74
75
|
this.updatedAt = updatedAt;
|
|
76
|
+
this.grouping = grouping;
|
|
75
77
|
}
|
|
76
78
|
static fromJSON(payload) {
|
|
77
79
|
const id = payload.id ? String(payload.id) : '';
|
|
@@ -83,7 +85,22 @@ export class TaskSummary {
|
|
|
83
85
|
if (!title || !status) {
|
|
84
86
|
throw new Error('Task payload missing required fields');
|
|
85
87
|
}
|
|
86
|
-
|
|
88
|
+
const groupingPayload = payload.grouping && typeof payload.grouping === 'object' && !Array.isArray(payload.grouping)
|
|
89
|
+
? payload.grouping
|
|
90
|
+
: null;
|
|
91
|
+
const groupingParentTaskId = groupingPayload
|
|
92
|
+
? groupingPayload.parent_task_id ?? groupingPayload.parentTaskId
|
|
93
|
+
: null;
|
|
94
|
+
const grouping = groupingParentTaskId && typeof groupingPayload?.grouped === 'boolean'
|
|
95
|
+
? {
|
|
96
|
+
parentTaskId: String(groupingParentTaskId),
|
|
97
|
+
grouped: groupingPayload.grouped,
|
|
98
|
+
warning: typeof groupingPayload.warning === 'string'
|
|
99
|
+
? groupingPayload.warning
|
|
100
|
+
: null,
|
|
101
|
+
}
|
|
102
|
+
: null;
|
|
103
|
+
return new TaskSummary(id, payload.project_id ? String(payload.project_id) : null, title, status, payload.backend_type ?? payload.backendType ?? null, payload.session_id ?? payload.sessionId ?? null, payload.session_file_path ?? payload.sessionFilePath ?? null, payload.created_at ?? null, payload.updated_at ?? null, grouping);
|
|
87
104
|
}
|
|
88
105
|
}
|
|
89
106
|
export class BackendApiClient {
|
|
@@ -160,11 +177,35 @@ export class BackendApiClient {
|
|
|
160
177
|
const payload = await this.parseJson(response);
|
|
161
178
|
return TaskSummary.fromJSON(payload);
|
|
162
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Create an app-managed task through the frontend pipeline. This route
|
|
182
|
+
* assigns daemon ownership and delivers initialContent; it is intentionally
|
|
183
|
+
* separate from the legacy agent/fire POST /tasks endpoint.
|
|
184
|
+
*/
|
|
185
|
+
async createAppTask(params) {
|
|
186
|
+
const response = await this.request('POST', '/api/tasks', {
|
|
187
|
+
body: JSON.stringify(params),
|
|
188
|
+
});
|
|
189
|
+
const payload = await this.parseJson(response);
|
|
190
|
+
return TaskSummary.fromJSON(payload);
|
|
191
|
+
}
|
|
163
192
|
async getTask(taskId) {
|
|
164
193
|
const response = await this.request('GET', `/tasks/${taskId}`);
|
|
165
194
|
const payload = await this.parseJson(response);
|
|
166
195
|
return TaskSummary.fromJSON(payload);
|
|
167
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* GET /tasks/[taskId]/group — RFC 0033 task-group discovery. Returns the raw
|
|
199
|
+
* payload `{ group_id, members }`; the higher layer normalizes it.
|
|
200
|
+
*/
|
|
201
|
+
async getTaskGroup(taskId) {
|
|
202
|
+
const response = await this.request('GET', `/tasks/${taskId}/group`);
|
|
203
|
+
const payload = await this.parseJson(response);
|
|
204
|
+
if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
|
|
205
|
+
return payload;
|
|
206
|
+
}
|
|
207
|
+
throw new BackendApiError('Invalid task group response', response.status, payload);
|
|
208
|
+
}
|
|
168
209
|
async updateTask(taskId, params) {
|
|
169
210
|
const response = await this.request('PATCH', `/tasks/${taskId}`, {
|
|
170
211
|
body: JSON.stringify(params),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@love-moon/conductor-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/lovemoon-ai/conductor.git"
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"typescript": "^5.6.3",
|
|
34
34
|
"vitest": "^2.1.4"
|
|
35
35
|
},
|
|
36
|
-
"gitCommitId": "
|
|
36
|
+
"gitCommitId": "04d4f62"
|
|
37
37
|
}
|