@agents-at-scale/ark 0.1.35-rc2 → 0.1.36-rc1
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/arkServices.js +7 -7
- package/dist/commands/agents/index.js +14 -0
- package/dist/commands/completion/index.js +1 -61
- package/dist/commands/dev/tool/shared.js +3 -1
- package/dist/commands/generate/generators/agent.js +2 -2
- package/dist/commands/generate/generators/team.js +2 -2
- package/dist/commands/install/index.js +1 -6
- package/dist/commands/models/index.js +15 -0
- package/dist/commands/models/index.spec.js +20 -0
- package/dist/commands/query/index.js +9 -116
- package/dist/commands/query/index.spec.d.ts +1 -0
- package/dist/commands/query/index.spec.js +53 -0
- package/dist/commands/status/index.d.ts +2 -3
- package/dist/commands/status/index.js +36 -17
- package/dist/commands/targets/index.js +26 -19
- package/dist/commands/targets/index.spec.js +95 -46
- package/dist/commands/teams/index.js +15 -0
- package/dist/commands/uninstall/index.js +0 -5
- package/dist/components/statusChecker.d.ts +2 -2
- package/dist/index.js +1 -3
- package/dist/lib/chatClient.js +70 -76
- package/dist/lib/config.d.ts +0 -2
- package/dist/lib/executeQuery.d.ts +20 -0
- package/dist/lib/executeQuery.js +135 -0
- package/dist/lib/executeQuery.spec.d.ts +1 -0
- package/dist/lib/executeQuery.spec.js +170 -0
- package/dist/lib/nextSteps.js +1 -1
- package/dist/lib/queryRunner.d.ts +22 -0
- package/dist/lib/queryRunner.js +142 -0
- package/dist/lib/startup.d.ts +1 -1
- package/dist/lib/startup.js +25 -31
- package/dist/lib/startup.spec.js +29 -45
- package/dist/lib/types.d.ts +70 -0
- package/dist/lib/versions.d.ts +23 -0
- package/dist/lib/versions.js +51 -0
- package/dist/ui/MainMenu.js +15 -11
- package/package.json +1 -2
|
@@ -1,34 +1,46 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
import { execa } from 'execa';
|
|
2
3
|
import output from '../../lib/output.js';
|
|
3
|
-
|
|
4
|
+
async function fetchResourceTargets(resourceType) {
|
|
5
|
+
const result = await execa('kubectl', ['get', `${resourceType}s`, '-o', 'json'], {
|
|
6
|
+
stdio: 'pipe',
|
|
7
|
+
});
|
|
8
|
+
const data = JSON.parse(result.stdout);
|
|
9
|
+
const items = data.items || [];
|
|
10
|
+
return items.map((item) => ({
|
|
11
|
+
type: resourceType,
|
|
12
|
+
name: item.metadata.name,
|
|
13
|
+
id: `${resourceType}/${item.metadata.name}`,
|
|
14
|
+
available: item.status?.available || item.status?.phase === 'ready' || true,
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
4
17
|
async function listTargets(options) {
|
|
5
|
-
let proxy;
|
|
6
18
|
try {
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
// Fetch all resource types in parallel
|
|
20
|
+
const resourceTypes = options.type
|
|
21
|
+
? [options.type]
|
|
22
|
+
: ['model', 'agent', 'team', 'tool'];
|
|
23
|
+
const targetPromises = resourceTypes.map((type) => fetchResourceTargets(type));
|
|
24
|
+
const targetArrays = await Promise.all(targetPromises);
|
|
25
|
+
// Flatten all targets into single array
|
|
26
|
+
const allTargets = targetArrays.flat();
|
|
15
27
|
// Sort targets by type and name
|
|
16
|
-
|
|
28
|
+
allTargets.sort((a, b) => {
|
|
17
29
|
if (a.type !== b.type) {
|
|
18
30
|
return a.type.localeCompare(b.type);
|
|
19
31
|
}
|
|
20
32
|
return a.name.localeCompare(b.name);
|
|
21
33
|
});
|
|
22
34
|
if (options.output === 'json') {
|
|
23
|
-
console.log(JSON.stringify(
|
|
35
|
+
console.log(JSON.stringify(allTargets, null, 2));
|
|
24
36
|
}
|
|
25
37
|
else {
|
|
26
|
-
if (
|
|
38
|
+
if (allTargets.length === 0) {
|
|
27
39
|
output.warning('no targets available');
|
|
28
40
|
return;
|
|
29
41
|
}
|
|
30
42
|
// Simple list output with type/name format
|
|
31
|
-
for (const target of
|
|
43
|
+
for (const target of allTargets) {
|
|
32
44
|
console.log(target.id);
|
|
33
45
|
}
|
|
34
46
|
}
|
|
@@ -37,11 +49,6 @@ async function listTargets(options) {
|
|
|
37
49
|
output.error('fetching targets:', error instanceof Error ? error.message : error);
|
|
38
50
|
process.exit(1);
|
|
39
51
|
}
|
|
40
|
-
finally {
|
|
41
|
-
if (proxy) {
|
|
42
|
-
proxy.stop();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
52
|
}
|
|
46
53
|
export function createTargetsCommand(_) {
|
|
47
54
|
const targets = new Command('targets');
|
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
import { jest } from '@jest/globals';
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const mockStart = jest.fn();
|
|
7
|
-
mockStart.mockResolvedValue(mockArkApiClient);
|
|
8
|
-
const mockArkApiProxy = jest.fn();
|
|
9
|
-
mockArkApiProxy.prototype = {
|
|
10
|
-
start: mockStart,
|
|
11
|
-
stop: jest.fn(),
|
|
12
|
-
};
|
|
13
|
-
jest.unstable_mockModule('../../lib/arkApiProxy.js', () => ({
|
|
14
|
-
ArkApiProxy: mockArkApiProxy,
|
|
3
|
+
// Mock execa to avoid real kubectl calls
|
|
4
|
+
jest.unstable_mockModule('execa', () => ({
|
|
5
|
+
execa: jest.fn(),
|
|
15
6
|
}));
|
|
16
7
|
const mockOutput = {
|
|
17
8
|
warning: jest.fn(),
|
|
@@ -24,6 +15,8 @@ const mockExit = jest.spyOn(process, 'exit').mockImplementation((() => {
|
|
|
24
15
|
throw new Error('process.exit called');
|
|
25
16
|
}));
|
|
26
17
|
const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
18
|
+
const { execa } = await import('execa');
|
|
19
|
+
const mockExeca = execa;
|
|
27
20
|
const { createTargetsCommand } = await import('./index.js');
|
|
28
21
|
describe('targets command', () => {
|
|
29
22
|
beforeEach(() => {
|
|
@@ -35,71 +28,127 @@ describe('targets command', () => {
|
|
|
35
28
|
expect(command.name()).toBe('targets');
|
|
36
29
|
});
|
|
37
30
|
it('lists targets in text format', async () => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
// Mock kubectl responses for each resource type (order: model, agent, team, tool)
|
|
32
|
+
mockExeca
|
|
33
|
+
.mockResolvedValueOnce({
|
|
34
|
+
stdout: JSON.stringify({
|
|
35
|
+
items: [{ metadata: { name: 'gpt-4' }, status: { available: true } }],
|
|
36
|
+
}),
|
|
37
|
+
})
|
|
38
|
+
.mockResolvedValueOnce({
|
|
39
|
+
stdout: JSON.stringify({
|
|
40
|
+
items: [
|
|
41
|
+
{ metadata: { name: 'gpt-assistant' }, status: { phase: 'ready' } },
|
|
42
|
+
],
|
|
43
|
+
}),
|
|
44
|
+
})
|
|
45
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
46
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) });
|
|
43
47
|
const command = createTargetsCommand({});
|
|
44
48
|
await command.parseAsync(['node', 'test']);
|
|
45
|
-
expect(
|
|
46
|
-
|
|
49
|
+
expect(mockExeca).toHaveBeenCalledWith('kubectl', ['get', 'models', '-o', 'json'], {
|
|
50
|
+
stdio: 'pipe',
|
|
51
|
+
});
|
|
52
|
+
expect(mockExeca).toHaveBeenCalledWith('kubectl', ['get', 'agents', '-o', 'json'], {
|
|
53
|
+
stdio: 'pipe',
|
|
54
|
+
});
|
|
47
55
|
expect(mockConsoleLog).toHaveBeenCalledWith('agent/gpt-assistant');
|
|
48
56
|
expect(mockConsoleLog).toHaveBeenCalledWith('model/gpt-4');
|
|
49
|
-
expect(mockArkApiProxy.prototype.stop).toHaveBeenCalled();
|
|
50
57
|
});
|
|
51
58
|
it('lists targets in json format', async () => {
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
// Order: model, agent, team, tool
|
|
60
|
+
mockExeca
|
|
61
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
62
|
+
.mockResolvedValueOnce({
|
|
63
|
+
stdout: JSON.stringify({
|
|
64
|
+
items: [{ metadata: { name: 'gpt' }, status: { phase: 'ready' } }],
|
|
65
|
+
}),
|
|
66
|
+
})
|
|
67
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
68
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) });
|
|
54
69
|
const command = createTargetsCommand({});
|
|
55
70
|
await command.parseAsync(['node', 'test', '-o', 'json']);
|
|
56
|
-
|
|
71
|
+
const expectedTargets = [
|
|
72
|
+
{ type: 'agent', name: 'gpt', id: 'agent/gpt', available: true },
|
|
73
|
+
];
|
|
74
|
+
expect(mockConsoleLog).toHaveBeenCalledWith(JSON.stringify(expectedTargets, null, 2));
|
|
57
75
|
});
|
|
58
76
|
it('filters targets by type', async () => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
77
|
+
mockExeca.mockResolvedValueOnce({
|
|
78
|
+
stdout: JSON.stringify({
|
|
79
|
+
items: [
|
|
80
|
+
{ metadata: { name: 'gpt' }, status: { phase: 'ready' } },
|
|
81
|
+
{ metadata: { name: 'helper' }, status: { phase: 'ready' } },
|
|
82
|
+
],
|
|
83
|
+
}),
|
|
84
|
+
});
|
|
65
85
|
const command = createTargetsCommand({});
|
|
66
86
|
await command.parseAsync(['node', 'test', '-t', 'agent']);
|
|
87
|
+
expect(mockExeca).toHaveBeenCalledWith('kubectl', ['get', 'agents', '-o', 'json'], {
|
|
88
|
+
stdio: 'pipe',
|
|
89
|
+
});
|
|
90
|
+
expect(mockExeca).toHaveBeenCalledTimes(1); // Only agents, not other types
|
|
67
91
|
expect(mockConsoleLog).toHaveBeenCalledWith('agent/gpt');
|
|
68
92
|
expect(mockConsoleLog).toHaveBeenCalledWith('agent/helper');
|
|
69
|
-
expect(mockConsoleLog).not.toHaveBeenCalledWith('model/claude');
|
|
70
93
|
});
|
|
71
94
|
it('sorts targets by type then name', async () => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
95
|
+
// Order: model, agent, team, tool
|
|
96
|
+
mockExeca
|
|
97
|
+
.mockResolvedValueOnce({
|
|
98
|
+
stdout: JSON.stringify({
|
|
99
|
+
items: [
|
|
100
|
+
{ metadata: { name: 'b' }, status: { available: true } },
|
|
101
|
+
{ metadata: { name: 'a' }, status: { available: true } },
|
|
102
|
+
],
|
|
103
|
+
}),
|
|
104
|
+
})
|
|
105
|
+
.mockResolvedValueOnce({
|
|
106
|
+
stdout: JSON.stringify({
|
|
107
|
+
items: [
|
|
108
|
+
{ metadata: { name: 'z' }, status: { phase: 'ready' } },
|
|
109
|
+
{ metadata: { name: 'a' }, status: { phase: 'ready' } },
|
|
110
|
+
],
|
|
111
|
+
}),
|
|
112
|
+
})
|
|
113
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
114
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) });
|
|
79
115
|
const command = createTargetsCommand({});
|
|
80
116
|
await command.parseAsync(['node', 'test']);
|
|
81
|
-
// Check order of calls
|
|
82
|
-
const calls = mockConsoleLog.mock.calls
|
|
117
|
+
// Check order of calls - sorted by type then name
|
|
118
|
+
const calls = mockConsoleLog.mock.calls
|
|
119
|
+
.filter((call) => call[0] && call[0].includes('/'))
|
|
120
|
+
.map((call) => call[0]);
|
|
83
121
|
expect(calls).toEqual(['agent/a', 'agent/z', 'model/a', 'model/b']);
|
|
84
122
|
});
|
|
85
123
|
it('shows warning when no targets', async () => {
|
|
86
|
-
|
|
124
|
+
// All resource types return empty (order: model, agent, team, tool)
|
|
125
|
+
mockExeca
|
|
126
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
127
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
128
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
129
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) });
|
|
87
130
|
const command = createTargetsCommand({});
|
|
88
131
|
await command.parseAsync(['node', 'test']);
|
|
89
132
|
expect(mockOutput.warning).toHaveBeenCalledWith('no targets available');
|
|
90
133
|
});
|
|
91
|
-
it('handles errors
|
|
92
|
-
|
|
134
|
+
it('handles errors', async () => {
|
|
135
|
+
mockExeca.mockRejectedValue(new Error('kubectl not found'));
|
|
93
136
|
const command = createTargetsCommand({});
|
|
94
137
|
await expect(command.parseAsync(['node', 'test'])).rejects.toThrow('process.exit called');
|
|
95
|
-
expect(mockOutput.error).toHaveBeenCalledWith('fetching targets:', '
|
|
138
|
+
expect(mockOutput.error).toHaveBeenCalledWith('fetching targets:', 'kubectl not found');
|
|
96
139
|
expect(mockExit).toHaveBeenCalledWith(1);
|
|
97
|
-
expect(mockArkApiProxy.prototype.stop).toHaveBeenCalled();
|
|
98
140
|
});
|
|
99
141
|
it('list subcommand works', async () => {
|
|
100
|
-
|
|
142
|
+
// Order: model, agent, team, tool
|
|
143
|
+
mockExeca
|
|
144
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
145
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
146
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) })
|
|
147
|
+
.mockResolvedValueOnce({ stdout: JSON.stringify({ items: [] }) });
|
|
101
148
|
const command = createTargetsCommand({});
|
|
102
149
|
await command.parseAsync(['node', 'test', 'list']);
|
|
103
|
-
expect(
|
|
150
|
+
expect(mockExeca).toHaveBeenCalledWith('kubectl', ['get', 'models', '-o', 'json'], {
|
|
151
|
+
stdio: 'pipe',
|
|
152
|
+
});
|
|
104
153
|
});
|
|
105
154
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { execa } from 'execa';
|
|
3
3
|
import output from '../../lib/output.js';
|
|
4
|
+
import { executeQuery } from '../../lib/executeQuery.js';
|
|
4
5
|
async function listTeams(options) {
|
|
5
6
|
try {
|
|
6
7
|
// Use kubectl to get teams
|
|
@@ -45,5 +46,19 @@ export function createTeamsCommand(_) {
|
|
|
45
46
|
await listTeams(options);
|
|
46
47
|
});
|
|
47
48
|
teamsCommand.addCommand(listCommand);
|
|
49
|
+
// Add query command
|
|
50
|
+
const queryCommand = new Command('query');
|
|
51
|
+
queryCommand
|
|
52
|
+
.description('Query a team')
|
|
53
|
+
.argument('<name>', 'Team name')
|
|
54
|
+
.argument('<message>', 'Message to send')
|
|
55
|
+
.action(async (name, message) => {
|
|
56
|
+
await executeQuery({
|
|
57
|
+
targetType: 'team',
|
|
58
|
+
targetName: name,
|
|
59
|
+
message,
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
teamsCommand.addCommand(queryCommand);
|
|
48
63
|
return teamsCommand;
|
|
49
64
|
}
|
|
@@ -22,11 +22,6 @@ async function uninstallArk(config, serviceName, options = {}) {
|
|
|
22
22
|
const clusterInfo = config.clusterInfo;
|
|
23
23
|
// Show cluster info
|
|
24
24
|
output.success(`connected to cluster: ${chalk.bold(clusterInfo.context)}`);
|
|
25
|
-
output.info(`type: ${clusterInfo.type}`);
|
|
26
|
-
output.info(`namespace: ${clusterInfo.namespace}`);
|
|
27
|
-
if (clusterInfo.ip) {
|
|
28
|
-
output.info(`ip: ${clusterInfo.ip}`);
|
|
29
|
-
}
|
|
30
25
|
console.log(); // Add blank line after cluster info
|
|
31
26
|
// If a specific service is requested, uninstall only that service
|
|
32
27
|
if (serviceName) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StatusData, CommandVersionConfig } from '../lib/types.js';
|
|
1
|
+
import { StatusData, CommandVersionConfig, ClusterInfo } from '../lib/types.js';
|
|
2
2
|
export declare const getNodeVersion: () => CommandVersionConfig;
|
|
3
3
|
export declare const getNpmVersion: () => CommandVersionConfig;
|
|
4
4
|
export declare const getKubectlVersion: () => CommandVersionConfig;
|
|
@@ -33,6 +33,6 @@ export declare class StatusChecker {
|
|
|
33
33
|
*/
|
|
34
34
|
checkAll(): Promise<StatusData & {
|
|
35
35
|
clusterAccess: boolean;
|
|
36
|
-
clusterInfo?:
|
|
36
|
+
clusterInfo?: ClusterInfo;
|
|
37
37
|
}>;
|
|
38
38
|
}
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,6 @@ import { createClusterCommand } from './commands/cluster/index.js';
|
|
|
13
13
|
import { createCompletionCommand } from './commands/completion/index.js';
|
|
14
14
|
import { createDashboardCommand } from './commands/dashboard/index.js';
|
|
15
15
|
import { createDocsCommand } from './commands/docs/index.js';
|
|
16
|
-
import { createDevCommand } from './commands/dev/index.js';
|
|
17
16
|
import { createGenerateCommand } from './commands/generate/index.js';
|
|
18
17
|
import { createInstallCommand } from './commands/install/index.js';
|
|
19
18
|
import { createModelsCommand } from './commands/models/index.js';
|
|
@@ -44,13 +43,12 @@ async function main() {
|
|
|
44
43
|
program.addCommand(createCompletionCommand(config));
|
|
45
44
|
program.addCommand(createDashboardCommand(config));
|
|
46
45
|
program.addCommand(createDocsCommand(config));
|
|
47
|
-
program.addCommand(createDevCommand(config));
|
|
48
46
|
program.addCommand(createGenerateCommand(config));
|
|
49
47
|
program.addCommand(createInstallCommand(config));
|
|
50
48
|
program.addCommand(createModelsCommand(config));
|
|
51
49
|
program.addCommand(createQueryCommand(config));
|
|
52
50
|
program.addCommand(createUninstallCommand(config));
|
|
53
|
-
program.addCommand(createStatusCommand(
|
|
51
|
+
program.addCommand(createStatusCommand());
|
|
54
52
|
program.addCommand(createConfigCommand(config));
|
|
55
53
|
program.addCommand(createTargetsCommand(config));
|
|
56
54
|
program.addCommand(createTeamsCommand(config));
|
package/dist/lib/chatClient.js
CHANGED
|
@@ -10,90 +10,84 @@ export class ChatClient {
|
|
|
10
10
|
*/
|
|
11
11
|
async sendMessage(targetId, messages, config, onChunk, signal) {
|
|
12
12
|
const shouldStream = config.streamingEnabled && !!onChunk;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
13
|
+
const params = {
|
|
14
|
+
model: targetId,
|
|
15
|
+
messages: messages,
|
|
16
|
+
signal: signal,
|
|
17
|
+
};
|
|
18
|
+
if (shouldStream) {
|
|
19
|
+
let fullResponse = '';
|
|
20
|
+
const toolCallsById = new Map();
|
|
21
|
+
const stream = this.arkApiClient.createChatCompletionStream(params);
|
|
22
|
+
for await (const chunk of stream) {
|
|
23
|
+
if (signal?.aborted) {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
const delta = chunk.choices[0]?.delta;
|
|
27
|
+
// Extract ARK metadata if present
|
|
28
|
+
const arkMetadata = chunk.ark;
|
|
29
|
+
// Handle regular content
|
|
30
|
+
const content = delta?.content || '';
|
|
31
|
+
if (content) {
|
|
32
|
+
fullResponse += content;
|
|
33
|
+
if (onChunk) {
|
|
34
|
+
onChunk(content, undefined, arkMetadata);
|
|
26
35
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
}
|
|
37
|
+
// Handle tool calls
|
|
38
|
+
if (delta?.tool_calls) {
|
|
39
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
40
|
+
const index = toolCallDelta.index;
|
|
41
|
+
// Initialize tool call if this is the first chunk for this index
|
|
42
|
+
if (!toolCallsById.has(index)) {
|
|
43
|
+
toolCallsById.set(index, {
|
|
44
|
+
id: toolCallDelta.id || '',
|
|
45
|
+
type: toolCallDelta.type || 'function',
|
|
46
|
+
function: {
|
|
47
|
+
name: toolCallDelta.function?.name || '',
|
|
48
|
+
arguments: '',
|
|
49
|
+
},
|
|
50
|
+
});
|
|
36
51
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
type: toolCallDelta.type || 'function',
|
|
47
|
-
function: {
|
|
48
|
-
name: toolCallDelta.function?.name || '',
|
|
49
|
-
arguments: '',
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
// Accumulate function arguments
|
|
54
|
-
const toolCall = toolCallsById.get(index);
|
|
55
|
-
if (toolCallDelta.function?.arguments) {
|
|
56
|
-
toolCall.function.arguments += toolCallDelta.function.arguments;
|
|
57
|
-
}
|
|
58
|
-
// Send the current state of all tool calls
|
|
59
|
-
if (onChunk) {
|
|
60
|
-
const toolCallsArray = Array.from(toolCallsById.values());
|
|
61
|
-
onChunk('', toolCallsArray, arkMetadata);
|
|
62
|
-
}
|
|
52
|
+
// Accumulate function arguments
|
|
53
|
+
const toolCall = toolCallsById.get(index);
|
|
54
|
+
if (toolCallDelta.function?.arguments) {
|
|
55
|
+
toolCall.function.arguments += toolCallDelta.function.arguments;
|
|
56
|
+
}
|
|
57
|
+
// Send the current state of all tool calls
|
|
58
|
+
if (onChunk) {
|
|
59
|
+
const toolCallsArray = Array.from(toolCallsById.values());
|
|
60
|
+
onChunk('', toolCallsArray, arkMetadata);
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
}
|
|
66
|
-
return fullResponse;
|
|
67
64
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// Send content after tool calls
|
|
88
|
-
if (content && onChunk) {
|
|
89
|
-
onChunk(content);
|
|
65
|
+
return fullResponse;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const response = await this.arkApiClient.createChatCompletion(params);
|
|
69
|
+
const message = response.choices[0]?.message;
|
|
70
|
+
const content = message?.content || '';
|
|
71
|
+
// Handle tool calls in non-streaming mode
|
|
72
|
+
if (message?.tool_calls && message.tool_calls.length > 0) {
|
|
73
|
+
const toolCalls = message.tool_calls.map((tc) => ({
|
|
74
|
+
id: tc.id,
|
|
75
|
+
type: tc.type || 'function',
|
|
76
|
+
function: {
|
|
77
|
+
name: tc.function?.name || '',
|
|
78
|
+
arguments: tc.function?.arguments || '',
|
|
79
|
+
},
|
|
80
|
+
}));
|
|
81
|
+
// Send tool calls first
|
|
82
|
+
if (onChunk) {
|
|
83
|
+
onChunk('', toolCalls);
|
|
90
84
|
}
|
|
91
|
-
return content;
|
|
92
85
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
// Send content after tool calls
|
|
87
|
+
if (content && onChunk) {
|
|
88
|
+
onChunk(content);
|
|
89
|
+
}
|
|
90
|
+
return content;
|
|
97
91
|
}
|
|
98
92
|
}
|
|
99
93
|
}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared query execution logic for both universal and resource-specific query commands
|
|
3
|
+
*/
|
|
4
|
+
import type { QueryTarget } from './types.js';
|
|
5
|
+
export interface QueryOptions {
|
|
6
|
+
targetType: string;
|
|
7
|
+
targetName: string;
|
|
8
|
+
message: string;
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Execute a query against any ARK target (model, agent, team)
|
|
13
|
+
* This is the shared implementation used by all query commands
|
|
14
|
+
*/
|
|
15
|
+
export declare function executeQuery(options: QueryOptions): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Parse a target string like "model/default" or "agent/weather"
|
|
18
|
+
* Returns QueryTarget or null if invalid
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseTarget(target: string): QueryTarget | null;
|