@taico/worker 0.0.6 → 0.1.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/dist/Coordinator.d.ts +1 -0
- package/dist/Coordinator.js +30 -3
- package/dist/Taico.d.ts +2 -1
- package/dist/Taico.js +12 -1
- package/dist/formatters/ADKMessageFormatter.d.ts +2 -0
- package/dist/formatters/ADKMessageFormatter.js +9 -4
- package/dist/formatters/ClaudeMessageFormatter.d.ts +2 -0
- package/dist/formatters/ClaudeMessageFormatter.js +16 -8
- package/dist/formatters/OpencodeMessageFormatter.d.ts +5 -1
- package/dist/formatters/OpencodeMessageFormatter.js +26 -16
- package/dist/runners/ADKAgentRunner.d.ts +0 -1
- package/dist/runners/ADKAgentRunner.js +2 -2
- package/dist/runners/AgentRunner.d.ts +2 -0
- package/dist/runners/ClaudeAgentRunner.d.ts +0 -1
- package/dist/runners/ClaudeAgentRunner.js +2 -2
- package/dist/runners/GitHubCopilotAgentRunner.js +5 -4
- package/dist/runners/OpenCodeAgentRunner.d.ts +0 -1
- package/dist/runners/OpenCodeAgentRunner.js +2 -2
- package/package.json +3 -3
package/dist/Coordinator.d.ts
CHANGED
package/dist/Coordinator.js
CHANGED
|
@@ -190,7 +190,21 @@ export class Coordinator {
|
|
|
190
190
|
}
|
|
191
191
|
return null;
|
|
192
192
|
}
|
|
193
|
-
|
|
193
|
+
buildThreadContextInstructions(task, thread) {
|
|
194
|
+
return [
|
|
195
|
+
'',
|
|
196
|
+
'Thread context:',
|
|
197
|
+
`- This task belongs to thread "${thread.id}" (${thread.title}).`,
|
|
198
|
+
`- This task is ${thread.parentTaskId === task.id ? 'the parent task' : 'an attached task'} in that thread.`,
|
|
199
|
+
`- Read shared thread memory at the start via mcp__context__get_thread_state_memory with threadId "${thread.id}".`,
|
|
200
|
+
`- Check sibling task status via mcp__tasks__list_tasks_by_thread with threadId "${thread.id}".`,
|
|
201
|
+
`- Keep decisions aligned with this shared memory and thread-level goal, not only this single task.`,
|
|
202
|
+
];
|
|
203
|
+
}
|
|
204
|
+
buildPrompt(task, agent, mode, inputRequest, thread) {
|
|
205
|
+
const threadContextInstructions = thread
|
|
206
|
+
? this.buildThreadContextInstructions(task, thread)
|
|
207
|
+
: [];
|
|
194
208
|
if (mode === 'input_request' && inputRequest) {
|
|
195
209
|
return [
|
|
196
210
|
`You got triggered by an unanswered input request in task "${task.id}".`,
|
|
@@ -200,10 +214,18 @@ export class Coordinator {
|
|
|
200
214
|
`Input request id: ${inputRequest.id}`,
|
|
201
215
|
`Question: ${String(inputRequest.question ?? '')}`,
|
|
202
216
|
'',
|
|
217
|
+
...threadContextInstructions,
|
|
218
|
+
'',
|
|
203
219
|
'Fetch the task, answer the input request assigned to you, and stop there.',
|
|
204
220
|
].join('\n');
|
|
205
221
|
}
|
|
206
|
-
return
|
|
222
|
+
return [
|
|
223
|
+
`You got triggered by new activity in task "${task.id}".`,
|
|
224
|
+
'Fetch the task and proceed according to the following instructions.',
|
|
225
|
+
...threadContextInstructions,
|
|
226
|
+
'',
|
|
227
|
+
agent.systemPrompt,
|
|
228
|
+
].join('\n');
|
|
207
229
|
}
|
|
208
230
|
async executeTask(task, agent, mode, inputRequest) {
|
|
209
231
|
if (this.activeTaskIds.has(task.id)) {
|
|
@@ -244,6 +266,10 @@ export class Coordinator {
|
|
|
244
266
|
// Prep workspace
|
|
245
267
|
const workDir = await prepareWorkspace(task.id, agent.actorId, repoUrl);
|
|
246
268
|
console.log(`- workspace prepped`);
|
|
269
|
+
const thread = await this.client.getThreadByTaskId(task.id);
|
|
270
|
+
if (thread) {
|
|
271
|
+
console.log(`- Task ${task.id} belongs to thread ${thread.id} (${thread.title})`);
|
|
272
|
+
}
|
|
247
273
|
const run = await this.client.startRun(task.id);
|
|
248
274
|
if (!run) {
|
|
249
275
|
console.error(`Failed to create a run ❌`);
|
|
@@ -276,10 +302,11 @@ export class Coordinator {
|
|
|
276
302
|
try {
|
|
277
303
|
const results = await runner.run({
|
|
278
304
|
taskId: task.id,
|
|
279
|
-
prompt: this.buildPrompt(task, agent, mode, inputRequest),
|
|
305
|
+
prompt: this.buildPrompt(task, agent, mode, inputRequest, thread),
|
|
280
306
|
cwd: workDir,
|
|
281
307
|
runId: run.id,
|
|
282
308
|
resume: sessionId ?? undefined,
|
|
309
|
+
agentSlug: agent.slug,
|
|
283
310
|
}, {
|
|
284
311
|
onEvent: (message) => {
|
|
285
312
|
console.log(`[agent message] ⤵️`);
|
package/dist/Taico.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AgentResponseDto, type AgentRunResponseDto, type ProjectResponseDto, type TaskResponseDto } from "@taico/client";
|
|
1
|
+
import { type AgentResponseDto, type AgentRunResponseDto, type ProjectResponseDto, type TaskResponseDto, type ThreadResponseDto } from "@taico/client";
|
|
2
2
|
export declare class Taico {
|
|
3
3
|
constructor(baseUrl: string, accessToken: string);
|
|
4
4
|
getAgent(agentSlug: string): Promise<AgentResponseDto | null>;
|
|
@@ -8,5 +8,6 @@ export declare class Taico {
|
|
|
8
8
|
listTasks(page?: number, limit?: number): Promise<TaskResponseDto[]>;
|
|
9
9
|
getTask(taskId: string): Promise<TaskResponseDto | null>;
|
|
10
10
|
getProjectBySlug(slug: string): Promise<ProjectResponseDto | null>;
|
|
11
|
+
getThreadByTaskId(taskId: string): Promise<ThreadResponseDto | null>;
|
|
11
12
|
startRun(taskId: string): Promise<AgentRunResponseDto | null>;
|
|
12
13
|
}
|
package/dist/Taico.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Taico.ts - API client wrapper using generated services
|
|
2
|
-
import { OpenAPI, ApiError, AgentService, TaskService, MetaProjectsService, AgentRunService, } from "@taico/client";
|
|
2
|
+
import { OpenAPI, ApiError, AgentService, TaskService, ThreadsService, MetaProjectsService, AgentRunService, } from "@taico/client";
|
|
3
3
|
function isApiError(error) {
|
|
4
4
|
return error instanceof ApiError;
|
|
5
5
|
}
|
|
@@ -70,6 +70,17 @@ export class Taico {
|
|
|
70
70
|
throw error;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
+
async getThreadByTaskId(taskId) {
|
|
74
|
+
try {
|
|
75
|
+
return await ThreadsService.threadsControllerGetThreadByTaskId(taskId);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (isApiError(error) && error.status === 404) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
73
84
|
async startRun(taskId) {
|
|
74
85
|
try {
|
|
75
86
|
return await AgentRunService.agentRunsControllerCreateAgentRun({
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export class ADKMessageFormatter {
|
|
2
|
+
agentSlug;
|
|
3
|
+
constructor(agentSlug) {
|
|
4
|
+
this.agentSlug = agentSlug;
|
|
5
|
+
}
|
|
2
6
|
format(message) {
|
|
7
|
+
const agentLabel = this.agentSlug ? `@${this.agentSlug}` : 'Assistant';
|
|
3
8
|
const content = message.content;
|
|
4
9
|
if (!content) {
|
|
5
10
|
return [];
|
|
@@ -11,19 +16,19 @@ export class ADKMessageFormatter {
|
|
|
11
16
|
const partMessages = parts.map(part => {
|
|
12
17
|
// Think
|
|
13
18
|
if (part.thought) {
|
|
14
|
-
return `💬 Thinking...`;
|
|
19
|
+
return `💬 ${agentLabel} Thinking...`;
|
|
15
20
|
}
|
|
16
21
|
// Tool call
|
|
17
22
|
if (part.functionCall) {
|
|
18
|
-
return `🔧 Tool call: ${part.functionCall.name}`;
|
|
23
|
+
return `🔧 ${agentLabel} Tool call: ${part.functionCall.name}`;
|
|
19
24
|
}
|
|
20
25
|
// Tool response
|
|
21
26
|
if (part.functionResponse) {
|
|
22
|
-
return `🔧 Tool response: ${part.functionResponse.name}`;
|
|
27
|
+
return `🔧 ${agentLabel} Tool response: ${part.functionResponse.name}`;
|
|
23
28
|
}
|
|
24
29
|
// Text
|
|
25
30
|
if (part.text) {
|
|
26
|
-
return `💬
|
|
31
|
+
return `💬 ${agentLabel}: ${part.text}`;
|
|
27
32
|
}
|
|
28
33
|
return null;
|
|
29
34
|
}).filter(p => p != null);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { SDKMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
2
2
|
export declare class ClaudeMessageFormatter {
|
|
3
|
+
private agentSlug?;
|
|
4
|
+
constructor(agentSlug?: string | undefined);
|
|
3
5
|
format(message: SDKMessage): string | null;
|
|
4
6
|
private formatAssistant;
|
|
5
7
|
private formatUser;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export class ClaudeMessageFormatter {
|
|
2
|
+
agentSlug;
|
|
3
|
+
constructor(agentSlug) {
|
|
4
|
+
this.agentSlug = agentSlug;
|
|
5
|
+
}
|
|
2
6
|
format(message) {
|
|
3
7
|
switch (message.type) {
|
|
4
8
|
case 'assistant':
|
|
@@ -25,15 +29,16 @@ export class ClaudeMessageFormatter {
|
|
|
25
29
|
const content = message.message?.content;
|
|
26
30
|
if (!Array.isArray(content))
|
|
27
31
|
return null;
|
|
32
|
+
const agentLabel = this.agentSlug ? `@${this.agentSlug}` : 'Assistant';
|
|
28
33
|
for (const c of content) {
|
|
29
34
|
if (c.type === 'tool_use') {
|
|
30
|
-
parts.push(`🔧 Tool call: ${c.name}`);
|
|
35
|
+
parts.push(`🔧 ${agentLabel} Tool call: ${c.name}`);
|
|
31
36
|
}
|
|
32
37
|
else if (c.type === 'text') {
|
|
33
|
-
parts.push(`💬
|
|
38
|
+
parts.push(`💬 ${agentLabel}: ${c.text}`);
|
|
34
39
|
}
|
|
35
40
|
else {
|
|
36
|
-
parts.push(`💬
|
|
41
|
+
parts.push(`💬 ${agentLabel} (${c.type})`);
|
|
37
42
|
}
|
|
38
43
|
}
|
|
39
44
|
return parts.length ? parts.join('\n') : null;
|
|
@@ -58,20 +63,22 @@ export class ClaudeMessageFormatter {
|
|
|
58
63
|
return parts.length ? parts.join('\n') : null;
|
|
59
64
|
}
|
|
60
65
|
formatResult(message) {
|
|
66
|
+
const agentLabel = this.agentSlug ? `@${this.agentSlug}` : 'Assistant';
|
|
61
67
|
if (message.subtype === 'success' &&
|
|
62
68
|
typeof message.result === 'string') {
|
|
63
69
|
return [
|
|
64
|
-
`---
|
|
70
|
+
`--- ${agentLabel} turn complete ---`,
|
|
65
71
|
message.result,
|
|
66
72
|
`---------------------------`,
|
|
67
73
|
].join('\n');
|
|
68
74
|
}
|
|
69
|
-
return `✅
|
|
75
|
+
return `✅ ${agentLabel} result received`;
|
|
70
76
|
}
|
|
71
77
|
formatSystem(message) {
|
|
78
|
+
const agentLabel = this.agentSlug ? `@${this.agentSlug}` : 'Assistant';
|
|
72
79
|
if (message.subtype === 'init') {
|
|
73
80
|
return [
|
|
74
|
-
`🧠 Claude initialized`,
|
|
81
|
+
`🧠 ${agentLabel} Claude initialized`,
|
|
75
82
|
`- Permissions: ${message.permissionMode}`,
|
|
76
83
|
`- Tools: ${message.tools.length}`,
|
|
77
84
|
`- MCP Servers: ${message.mcp_servers.length}`,
|
|
@@ -81,7 +88,7 @@ export class ClaudeMessageFormatter {
|
|
|
81
88
|
`- Agents: ${message.agents?.length || 0}`,
|
|
82
89
|
].join('\n');
|
|
83
90
|
}
|
|
84
|
-
return `⚙️ System message`;
|
|
91
|
+
return `⚙️ ${agentLabel} System message`;
|
|
85
92
|
}
|
|
86
93
|
formatStreamEvent(_) {
|
|
87
94
|
// usually too noisy — ignore by default
|
|
@@ -92,6 +99,7 @@ export class ClaudeMessageFormatter {
|
|
|
92
99
|
return null;
|
|
93
100
|
}
|
|
94
101
|
formatAuthStatus(_) {
|
|
95
|
-
|
|
102
|
+
const agentLabel = this.agentSlug ? `@${this.agentSlug}` : 'Assistant';
|
|
103
|
+
return `🔐 ${agentLabel} Auth status updated`;
|
|
96
104
|
}
|
|
97
105
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { AssistantMessage, Part, Event } from "@opencode-ai/sdk";
|
|
2
|
-
export declare function opencodePartToText(part: Part): string;
|
|
2
|
+
export declare function opencodePartToText(part: Part, agentSlug?: string): string;
|
|
3
3
|
export declare class OpencodeAsyncMessageFormatter {
|
|
4
|
+
private agentSlug?;
|
|
5
|
+
constructor(agentSlug?: string | undefined);
|
|
4
6
|
format(event: Event): string | null;
|
|
5
7
|
}
|
|
6
8
|
export declare class OpencodeSyncMessageFormatter {
|
|
9
|
+
private agentSlug?;
|
|
10
|
+
constructor(agentSlug?: string | undefined);
|
|
7
11
|
format(info: AssistantMessage, parts: Array<Part>): Array<string>;
|
|
8
12
|
}
|
|
@@ -1,32 +1,37 @@
|
|
|
1
|
-
export function opencodePartToText(part) {
|
|
1
|
+
export function opencodePartToText(part, agentSlug) {
|
|
2
|
+
const agentLabel = agentSlug ? `@${agentSlug}` : 'Assistant';
|
|
2
3
|
switch (part.type) {
|
|
3
4
|
case 'text':
|
|
4
|
-
return `💬
|
|
5
|
+
return `💬 ${agentLabel}: ${part.text}`;
|
|
5
6
|
case 'subtask':
|
|
6
|
-
return `💬
|
|
7
|
+
return `💬 ${agentLabel}: Creating subtask: ${part.description}`;
|
|
7
8
|
case 'reasoning':
|
|
8
|
-
return `💬
|
|
9
|
+
return `💬 ${agentLabel}: Thinking...`;
|
|
9
10
|
case 'file':
|
|
10
|
-
return `📂 File ${part.filename || ''}`;
|
|
11
|
+
return `📂 ${agentLabel} File ${part.filename || ''}`;
|
|
11
12
|
case 'tool':
|
|
12
|
-
return `🔧 Tool call: ${part.tool}`;
|
|
13
|
+
return `🔧 ${agentLabel} Tool call: ${part.tool}`;
|
|
13
14
|
case 'step-start':
|
|
14
|
-
return `💬
|
|
15
|
+
return `💬 ${agentLabel}: Starting step`;
|
|
15
16
|
case 'step-finish':
|
|
16
|
-
return `💬
|
|
17
|
+
return `💬 ${agentLabel}: Finish step: ${part.reason}`;
|
|
17
18
|
case 'snapshot':
|
|
18
|
-
return `📸 Snapshot: ${part.snapshot}`;
|
|
19
|
+
return `📸 ${agentLabel} Snapshot: ${part.snapshot}`;
|
|
19
20
|
case 'patch':
|
|
20
|
-
return `🔧 Patching files: ${part.files}`;
|
|
21
|
+
return `🔧 ${agentLabel} Patching files: ${part.files}`;
|
|
21
22
|
case 'agent':
|
|
22
|
-
return `🤖 Agent: ${part.name}`;
|
|
23
|
+
return `🤖 ${agentLabel} Agent: ${part.name}`;
|
|
23
24
|
case 'retry':
|
|
24
|
-
return `🔄 Retrying error due to error '${part.error.name}'. Attempt ${part.attempt}...`;
|
|
25
|
+
return `🔄 ${agentLabel} Retrying error due to error '${part.error.name}'. Attempt ${part.attempt}...`;
|
|
25
26
|
case 'compaction':
|
|
26
|
-
return `🚜 Compacting`;
|
|
27
|
+
return `🚜 ${agentLabel} Compacting`;
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
export class OpencodeAsyncMessageFormatter {
|
|
31
|
+
agentSlug;
|
|
32
|
+
constructor(agentSlug) {
|
|
33
|
+
this.agentSlug = agentSlug;
|
|
34
|
+
}
|
|
30
35
|
// Only listen to part update (this is where tool calls and messages happen)
|
|
31
36
|
format(event) {
|
|
32
37
|
if (event.type !== 'message.part.updated') {
|
|
@@ -38,19 +43,24 @@ export class OpencodeAsyncMessageFormatter {
|
|
|
38
43
|
}
|
|
39
44
|
// Parse part into text
|
|
40
45
|
const part = event.properties.part;
|
|
41
|
-
const message = opencodePartToText(part);
|
|
46
|
+
const message = opencodePartToText(part, this.agentSlug);
|
|
42
47
|
return message;
|
|
43
48
|
}
|
|
44
49
|
}
|
|
45
50
|
export class OpencodeSyncMessageFormatter {
|
|
51
|
+
agentSlug;
|
|
52
|
+
constructor(agentSlug) {
|
|
53
|
+
this.agentSlug = agentSlug;
|
|
54
|
+
}
|
|
46
55
|
format(info, parts) {
|
|
47
56
|
const messages = [];
|
|
57
|
+
const agentLabel = this.agentSlug ? `@${this.agentSlug}` : 'Assistant';
|
|
48
58
|
// Parse info
|
|
49
59
|
if (info.error) {
|
|
50
|
-
messages.push(
|
|
60
|
+
messages.push(`❌ ${agentLabel} Error ${info.error.name}: ${JSON.stringify(info.error.data)}`);
|
|
51
61
|
}
|
|
52
62
|
// Parse parts
|
|
53
|
-
const partMessages = parts.map(opencodePartToText);
|
|
63
|
+
const partMessages = parts.map(part => opencodePartToText(part, this.agentSlug));
|
|
54
64
|
return [...messages, ...partMessages];
|
|
55
65
|
}
|
|
56
66
|
}
|
|
@@ -2,7 +2,6 @@ import { BaseAgentRunner } from "./BaseAgentRunner.js";
|
|
|
2
2
|
import { AgentModelConfig, AgentRunContext } from "./AgentRunner.js";
|
|
3
3
|
export declare class ADKAgentRunner extends BaseAgentRunner {
|
|
4
4
|
readonly kind = "adk";
|
|
5
|
-
private formatter;
|
|
6
5
|
private modelId;
|
|
7
6
|
private sessionService;
|
|
8
7
|
constructor(modelConfig?: AgentModelConfig);
|
|
@@ -42,7 +42,6 @@ class NamespacedMCPToolset extends MCPToolset {
|
|
|
42
42
|
}
|
|
43
43
|
export class ADKAgentRunner extends BaseAgentRunner {
|
|
44
44
|
kind = 'adk';
|
|
45
|
-
formatter = new ADKMessageFormatter();
|
|
46
45
|
modelId;
|
|
47
46
|
sessionService = new InMemorySessionService();
|
|
48
47
|
constructor(modelConfig = {}) {
|
|
@@ -50,6 +49,7 @@ export class ADKAgentRunner extends BaseAgentRunner {
|
|
|
50
49
|
this.modelId = modelConfig.modelId ?? 'gemini-2.5-flash';
|
|
51
50
|
}
|
|
52
51
|
async runInternal(ctx, emit, setSession, onError) {
|
|
52
|
+
const formatter = new ADKMessageFormatter(ctx.agentSlug);
|
|
53
53
|
let finalResult = '';
|
|
54
54
|
// Init a session
|
|
55
55
|
const session = await this.sessionService.createSession({
|
|
@@ -100,7 +100,7 @@ export class ADKAgentRunner extends BaseAgentRunner {
|
|
|
100
100
|
});
|
|
101
101
|
for await (const msg of stream) {
|
|
102
102
|
// map → string
|
|
103
|
-
const messages =
|
|
103
|
+
const messages = formatter.format(msg);
|
|
104
104
|
messages.forEach(async (message) => {
|
|
105
105
|
await emit(message);
|
|
106
106
|
});
|
|
@@ -20,6 +20,8 @@ export type AgentRunContext = {
|
|
|
20
20
|
/** For backend traceability */
|
|
21
21
|
runId: string;
|
|
22
22
|
model?: Model;
|
|
23
|
+
/** Agent slug for personalized activity messages */
|
|
24
|
+
agentSlug?: string;
|
|
23
25
|
};
|
|
24
26
|
export type AgentRunCallbacks = {
|
|
25
27
|
/** Called once when a session/run ID is known */
|
|
@@ -2,7 +2,6 @@ import { BaseAgentRunner } from "./BaseAgentRunner.js";
|
|
|
2
2
|
import { AgentModelConfig, AgentRunContext } from "./AgentRunner.js";
|
|
3
3
|
export declare class ClaudeAgentRunner extends BaseAgentRunner {
|
|
4
4
|
readonly kind = "claude";
|
|
5
|
-
private formatter;
|
|
6
5
|
constructor(_modelConfig?: AgentModelConfig);
|
|
7
6
|
protected runInternal(ctx: AgentRunContext, emit: (msg: string) => Promise<void>, setSession: (id: string) => Promise<void>, onError?: (error: {
|
|
8
7
|
message: string;
|
|
@@ -5,11 +5,11 @@ import { ClaudeMessageFormatter } from "../formatters/ClaudeMessageFormatter.js"
|
|
|
5
5
|
import { ACCESS_TOKEN, BASE_URL, RUN_ID_HEADER } from "../helpers/config.js";
|
|
6
6
|
export class ClaudeAgentRunner extends BaseAgentRunner {
|
|
7
7
|
kind = 'claude';
|
|
8
|
-
formatter = new ClaudeMessageFormatter();
|
|
9
8
|
constructor(_modelConfig = {}) {
|
|
10
9
|
super();
|
|
11
10
|
}
|
|
12
11
|
async runInternal(ctx, emit, setSession, onError) {
|
|
12
|
+
const formatter = new ClaudeMessageFormatter(ctx.agentSlug);
|
|
13
13
|
let finalResult = '';
|
|
14
14
|
const stream = query({
|
|
15
15
|
prompt: ctx.prompt,
|
|
@@ -56,7 +56,7 @@ export class ClaudeAgentRunner extends BaseAgentRunner {
|
|
|
56
56
|
await setSession(msg.session_id);
|
|
57
57
|
}
|
|
58
58
|
// map → string
|
|
59
|
-
const text =
|
|
59
|
+
const text = formatter.format(msg);
|
|
60
60
|
if (text)
|
|
61
61
|
await emit(text);
|
|
62
62
|
if (msg.type === 'result' && msg.subtype === 'success') {
|
|
@@ -10,6 +10,7 @@ export class GitHubCopilotAgentRunner extends BaseAgentRunner {
|
|
|
10
10
|
this.model = modelConfig.modelId ?? 'gpt-5.2-codex';
|
|
11
11
|
}
|
|
12
12
|
async runInternal(ctx, emit, setSession, onError) {
|
|
13
|
+
const agentLabel = ctx.agentSlug ? `@${ctx.agentSlug}` : 'Assistant';
|
|
13
14
|
return new Promise(async (resolve, reject) => {
|
|
14
15
|
try {
|
|
15
16
|
// Init client
|
|
@@ -57,17 +58,17 @@ export class GitHubCopilotAgentRunner extends BaseAgentRunner {
|
|
|
57
58
|
resolve(lastAssistantMessage);
|
|
58
59
|
});
|
|
59
60
|
session.on('assistant.reasoning', (reasoning) => {
|
|
60
|
-
void emit(`💬 Thinking... ${reasoning.data.content}`);
|
|
61
|
+
void emit(`💬 ${agentLabel} Thinking... ${reasoning.data.content}`);
|
|
61
62
|
});
|
|
62
63
|
session.on('assistant.message', (message) => {
|
|
63
64
|
lastAssistantMessage = message.data.content ?? '';
|
|
64
|
-
void emit(`💬
|
|
65
|
+
void emit(`💬 ${agentLabel}: ${message.data.content}`);
|
|
65
66
|
});
|
|
66
67
|
session.on('tool.execution_start', (toolCall) => {
|
|
67
|
-
void emit(`🔧 Tool call: ${toolCall.data.toolName}`);
|
|
68
|
+
void emit(`🔧 ${agentLabel} Tool call: ${toolCall.data.toolName}`);
|
|
68
69
|
});
|
|
69
70
|
session.on('tool.execution_complete', () => {
|
|
70
|
-
void emit(`🔧 Tool response`);
|
|
71
|
+
void emit(`🔧 ${agentLabel} Tool response`);
|
|
71
72
|
});
|
|
72
73
|
// Fire up the prompt
|
|
73
74
|
await session.send({
|
|
@@ -3,7 +3,6 @@ import { AgentModelConfig, AgentRunContext } from "./AgentRunner.js";
|
|
|
3
3
|
export declare class OpencodeAgentRunner extends BaseAgentRunner {
|
|
4
4
|
readonly kind = "opencode";
|
|
5
5
|
private static chdirLock;
|
|
6
|
-
private formatter;
|
|
7
6
|
private client;
|
|
8
7
|
private abortController;
|
|
9
8
|
private close;
|
|
@@ -8,7 +8,6 @@ export class OpencodeAgentRunner extends BaseAgentRunner {
|
|
|
8
8
|
// Mutex for process.chdir: serializes all instances so only one
|
|
9
9
|
// changes the working directory at a time.
|
|
10
10
|
static chdirLock = Promise.resolve();
|
|
11
|
-
formatter = new OpencodeAsyncMessageFormatter();
|
|
12
11
|
client = null;
|
|
13
12
|
abortController = new AbortController();
|
|
14
13
|
close = () => { };
|
|
@@ -105,6 +104,7 @@ export class OpencodeAgentRunner extends BaseAgentRunner {
|
|
|
105
104
|
throw new Error(`Failed to start Opencode on ports ${PORT_START}–${PORT_END}: ${String(lastError)}`);
|
|
106
105
|
}
|
|
107
106
|
async runInternal(ctx, emit, setSession, onError) {
|
|
107
|
+
const formatter = new OpencodeAsyncMessageFormatter(ctx.agentSlug);
|
|
108
108
|
// Start client
|
|
109
109
|
await this.initBullshit({ runId: ctx.runId, cwd: ctx.cwd });
|
|
110
110
|
// await this.init({ runId: ctx.runId });
|
|
@@ -157,7 +157,7 @@ export class OpencodeAgentRunner extends BaseAgentRunner {
|
|
|
157
157
|
console.log('session.idle');
|
|
158
158
|
break;
|
|
159
159
|
}
|
|
160
|
-
const message =
|
|
160
|
+
const message = formatter.format(event);
|
|
161
161
|
if (message) {
|
|
162
162
|
emit(message);
|
|
163
163
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taico/worker",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"@github/copilot-sdk": "0.1.22",
|
|
44
44
|
"@google/adk": "^0.2.4",
|
|
45
45
|
"@opencode-ai/sdk": "^1.1.28",
|
|
46
|
-
"@taico/client": "^0.0
|
|
47
|
-
"@taico/events": "^0.0
|
|
46
|
+
"@taico/client": "^0.1.0",
|
|
47
|
+
"@taico/events": "^0.1.0",
|
|
48
48
|
"dotenv": "^16.4.7",
|
|
49
49
|
"socket.io-client": "^4.8.3"
|
|
50
50
|
},
|