@google/gemini-cli-a2a-server 0.10.0-nightly.20251014.0a3e492e
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/README.md +5 -0
- package/dist/.last_build +0 -0
- package/dist/a2a-server.mjs +354316 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/src/agent/executor.d.ts +40 -0
- package/dist/src/agent/executor.js +406 -0
- package/dist/src/agent/executor.js.map +1 -0
- package/dist/src/agent/task.d.ts +54 -0
- package/dist/src/agent/task.js +652 -0
- package/dist/src/agent/task.js.map +1 -0
- package/dist/src/agent/task.test.d.ts +6 -0
- package/dist/src/agent/task.test.js +44 -0
- package/dist/src/agent/task.test.js.map +1 -0
- package/dist/src/config/config.d.ts +14 -0
- package/dist/src/config/config.js +150 -0
- package/dist/src/config/config.js.map +1 -0
- package/dist/src/config/extension.d.ts +11 -0
- package/dist/src/config/extension.js +104 -0
- package/dist/src/config/extension.js.map +1 -0
- package/dist/src/config/settings.d.ts +38 -0
- package/dist/src/config/settings.js +102 -0
- package/dist/src/config/settings.js.map +1 -0
- package/dist/src/http/app.d.ts +8 -0
- package/dist/src/http/app.js +170 -0
- package/dist/src/http/app.js.map +1 -0
- package/dist/src/http/app.test.d.ts +6 -0
- package/dist/src/http/app.test.js +520 -0
- package/dist/src/http/app.test.js.map +1 -0
- package/dist/src/http/endpoints.test.d.ts +6 -0
- package/dist/src/http/endpoints.test.js +138 -0
- package/dist/src/http/endpoints.test.js.map +1 -0
- package/dist/src/http/requestStorage.d.ts +10 -0
- package/dist/src/http/requestStorage.js +8 -0
- package/dist/src/http/requestStorage.js.map +1 -0
- package/dist/src/http/server.d.ts +7 -0
- package/dist/src/http/server.js +26 -0
- package/dist/src/http/server.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/persistence/gcs.d.ts +24 -0
- package/dist/src/persistence/gcs.js +238 -0
- package/dist/src/persistence/gcs.js.map +1 -0
- package/dist/src/persistence/gcs.test.d.ts +6 -0
- package/dist/src/persistence/gcs.test.js +265 -0
- package/dist/src/persistence/gcs.test.js.map +1 -0
- package/dist/src/types.d.ts +91 -0
- package/dist/src/types.js +44 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/executor_utils.d.ts +7 -0
- package/dist/src/utils/executor_utils.js +41 -0
- package/dist/src/utils/executor_utils.js.map +1 -0
- package/dist/src/utils/logger.d.ts +8 -0
- package/dist/src/utils/logger.js +23 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/testing_utils.d.ts +33 -0
- package/dist/src/utils/testing_utils.js +91 -0
- package/dist/src/utils/testing_utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
|
|
7
|
+
import request from 'supertest';
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import * as os from 'node:os';
|
|
11
|
+
import { createApp, updateCoderAgentCardUrl } from './app.js';
|
|
12
|
+
import { createMockConfig } from '../utils/testing_utils.js';
|
|
13
|
+
// Mock the logger to avoid polluting test output
|
|
14
|
+
// Comment out to help debug
|
|
15
|
+
vi.mock('../utils/logger.js', () => ({
|
|
16
|
+
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
|
17
|
+
}));
|
|
18
|
+
// Mock Task.create to avoid its complex setup
|
|
19
|
+
vi.mock('../agent/task.js', () => {
|
|
20
|
+
class MockTask {
|
|
21
|
+
id;
|
|
22
|
+
contextId;
|
|
23
|
+
taskState = 'submitted';
|
|
24
|
+
config = {
|
|
25
|
+
getContentGeneratorConfig: vi
|
|
26
|
+
.fn()
|
|
27
|
+
.mockReturnValue({ model: 'gemini-pro' }),
|
|
28
|
+
};
|
|
29
|
+
geminiClient = {
|
|
30
|
+
initialize: vi.fn().mockResolvedValue(undefined),
|
|
31
|
+
};
|
|
32
|
+
constructor(id, contextId) {
|
|
33
|
+
this.id = id;
|
|
34
|
+
this.contextId = contextId;
|
|
35
|
+
}
|
|
36
|
+
static create = vi
|
|
37
|
+
.fn()
|
|
38
|
+
.mockImplementation((id, contextId) => Promise.resolve(new MockTask(id, contextId)));
|
|
39
|
+
getMetadata = vi.fn().mockImplementation(async () => ({
|
|
40
|
+
id: this.id,
|
|
41
|
+
contextId: this.contextId,
|
|
42
|
+
taskState: this.taskState,
|
|
43
|
+
model: 'gemini-pro',
|
|
44
|
+
mcpServers: [],
|
|
45
|
+
availableTools: [],
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
return { Task: MockTask };
|
|
49
|
+
});
|
|
50
|
+
vi.mock('../config/config.js', async () => {
|
|
51
|
+
const actual = await vi.importActual('../config/config.js');
|
|
52
|
+
return {
|
|
53
|
+
...actual,
|
|
54
|
+
loadConfig: vi
|
|
55
|
+
.fn()
|
|
56
|
+
.mockImplementation(async () => createMockConfig({})),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
describe('Agent Server Endpoints', () => {
|
|
60
|
+
let app;
|
|
61
|
+
let server;
|
|
62
|
+
let testWorkspace;
|
|
63
|
+
const createTask = (contextId) => request(app)
|
|
64
|
+
.post('/tasks')
|
|
65
|
+
.send({
|
|
66
|
+
contextId,
|
|
67
|
+
agentSettings: {
|
|
68
|
+
kind: 'agent-settings',
|
|
69
|
+
workspacePath: testWorkspace,
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
.set('Content-Type', 'application/json');
|
|
73
|
+
beforeAll(async () => {
|
|
74
|
+
// Create a unique temporary directory for the workspace to avoid conflicts
|
|
75
|
+
testWorkspace = fs.mkdtempSync(path.join(os.tmpdir(), 'gemini-agent-test-'));
|
|
76
|
+
app = await createApp();
|
|
77
|
+
await new Promise((resolve) => {
|
|
78
|
+
server = app.listen(0, () => {
|
|
79
|
+
const port = server.address().port;
|
|
80
|
+
updateCoderAgentCardUrl(port);
|
|
81
|
+
resolve();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
afterAll(async () => {
|
|
86
|
+
if (server) {
|
|
87
|
+
await new Promise((resolve, reject) => {
|
|
88
|
+
server.close((err) => {
|
|
89
|
+
if (err)
|
|
90
|
+
return reject(err);
|
|
91
|
+
resolve();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (testWorkspace) {
|
|
96
|
+
try {
|
|
97
|
+
fs.rmSync(testWorkspace, { recursive: true, force: true });
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
console.warn(`Could not remove temp dir '${testWorkspace}':`, e);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
it('should create a new task via POST /tasks', async () => {
|
|
105
|
+
const response = await createTask('test-context');
|
|
106
|
+
expect(response.status).toBe(201);
|
|
107
|
+
expect(response.body).toBeTypeOf('string'); // Should return the task ID
|
|
108
|
+
}, 7000);
|
|
109
|
+
it('should get metadata for a specific task via GET /tasks/:taskId/metadata', async () => {
|
|
110
|
+
const createResponse = await createTask('test-context-2');
|
|
111
|
+
const taskId = createResponse.body;
|
|
112
|
+
const response = await request(app).get(`/tasks/${taskId}/metadata`);
|
|
113
|
+
expect(response.status).toBe(200);
|
|
114
|
+
expect(response.body.metadata.id).toBe(taskId);
|
|
115
|
+
}, 6000);
|
|
116
|
+
it('should get metadata for all tasks via GET /tasks/metadata', async () => {
|
|
117
|
+
const createResponse = await createTask('test-context-3');
|
|
118
|
+
const taskId = createResponse.body;
|
|
119
|
+
const response = await request(app).get('/tasks/metadata');
|
|
120
|
+
expect(response.status).toBe(200);
|
|
121
|
+
expect(Array.isArray(response.body)).toBe(true);
|
|
122
|
+
expect(response.body.length).toBeGreaterThan(0);
|
|
123
|
+
const taskMetadata = response.body.find((m) => m.id === taskId);
|
|
124
|
+
expect(taskMetadata).toBeDefined();
|
|
125
|
+
});
|
|
126
|
+
it('should return 404 for a non-existent task', async () => {
|
|
127
|
+
const response = await request(app).get('/tasks/fake-task/metadata');
|
|
128
|
+
expect(response.status).toBe(404);
|
|
129
|
+
});
|
|
130
|
+
it('should return agent metadata via GET /.well-known/agent-card.json', async () => {
|
|
131
|
+
const response = await request(app).get('/.well-known/agent-card.json');
|
|
132
|
+
const port = server.address().port;
|
|
133
|
+
expect(response.status).toBe(200);
|
|
134
|
+
expect(response.body.name).toBe('Gemini SDLC Agent');
|
|
135
|
+
expect(response.body.url).toBe(`http://localhost:${port}/`);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=endpoints.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.test.js","sourceRoot":"","sources":["../../../src/http/endpoints.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type express from 'express';
|
|
7
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
8
|
+
export declare const requestStorage: AsyncLocalStorage<{
|
|
9
|
+
req: express.Request;
|
|
10
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestStorage.js","sourceRoot":"","sources":["../../../src/http/requestStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,iBAAiB,EAA4B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2025 Google LLC
|
|
5
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
import * as url from 'node:url';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { logger } from '../utils/logger.js';
|
|
10
|
+
import { main } from './app.js';
|
|
11
|
+
// Check if the module is the main script being run
|
|
12
|
+
const isMainModule = path.basename(process.argv[1]) ===
|
|
13
|
+
path.basename(url.fileURLToPath(import.meta.url));
|
|
14
|
+
if (import.meta.url.startsWith('file:') &&
|
|
15
|
+
isMainModule &&
|
|
16
|
+
process.env['NODE_ENV'] !== 'test') {
|
|
17
|
+
process.on('uncaughtException', (error) => {
|
|
18
|
+
logger.error('Unhandled exception:', error);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
});
|
|
21
|
+
main().catch((error) => {
|
|
22
|
+
logger.error('[CoreAgent] Unhandled error in main:', error);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/http/server.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,mDAAmD;AACnD,MAAM,YAAY,GAChB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEpD,IACE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;IACnC,YAAY;IACZ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,MAAM,EAClC,CAAC;IACD,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;QACxC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrB,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { Task as SDKTask } from '@a2a-js/sdk';
|
|
7
|
+
import type { TaskStore } from '@a2a-js/sdk/server';
|
|
8
|
+
export declare class GCSTaskStore implements TaskStore {
|
|
9
|
+
private storage;
|
|
10
|
+
private bucketName;
|
|
11
|
+
private bucketInitialized;
|
|
12
|
+
constructor(bucketName: string);
|
|
13
|
+
private initializeBucket;
|
|
14
|
+
private ensureBucketInitialized;
|
|
15
|
+
private getObjectPath;
|
|
16
|
+
save(task: SDKTask): Promise<void>;
|
|
17
|
+
load(taskId: string): Promise<SDKTask | undefined>;
|
|
18
|
+
}
|
|
19
|
+
export declare class NoOpTaskStore implements TaskStore {
|
|
20
|
+
private realStore;
|
|
21
|
+
constructor(realStore: TaskStore);
|
|
22
|
+
save(task: SDKTask): Promise<void>;
|
|
23
|
+
load(taskId: string): Promise<SDKTask | undefined>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { Storage } from '@google-cloud/storage';
|
|
7
|
+
import { gzipSync, gunzipSync } from 'node:zlib';
|
|
8
|
+
import * as tar from 'tar';
|
|
9
|
+
import * as fse from 'fs-extra';
|
|
10
|
+
import { promises as fsPromises, createReadStream } from 'node:fs';
|
|
11
|
+
import { tmpdir } from 'node:os';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { logger } from '../utils/logger.js';
|
|
14
|
+
import { setTargetDir } from '../config/config.js';
|
|
15
|
+
import { getPersistedState } from '../types.js';
|
|
16
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
17
|
+
const getTmpArchiveFilename = (taskId) => `task-${taskId}-workspace-${uuidv4()}.tar.gz`;
|
|
18
|
+
export class GCSTaskStore {
|
|
19
|
+
storage;
|
|
20
|
+
bucketName;
|
|
21
|
+
bucketInitialized;
|
|
22
|
+
constructor(bucketName) {
|
|
23
|
+
if (!bucketName) {
|
|
24
|
+
throw new Error('GCS bucket name is required.');
|
|
25
|
+
}
|
|
26
|
+
this.storage = new Storage();
|
|
27
|
+
this.bucketName = bucketName;
|
|
28
|
+
logger.info(`GCSTaskStore initializing with bucket: ${this.bucketName}`);
|
|
29
|
+
// Prerequisites: user account or service account must have storage admin IAM role
|
|
30
|
+
// and the bucket name must be unique.
|
|
31
|
+
this.bucketInitialized = this.initializeBucket();
|
|
32
|
+
}
|
|
33
|
+
async initializeBucket() {
|
|
34
|
+
try {
|
|
35
|
+
const [buckets] = await this.storage.getBuckets();
|
|
36
|
+
const exists = buckets.some((bucket) => bucket.name === this.bucketName);
|
|
37
|
+
if (!exists) {
|
|
38
|
+
logger.info(`Bucket ${this.bucketName} does not exist in the list. Attempting to create...`);
|
|
39
|
+
try {
|
|
40
|
+
await this.storage.createBucket(this.bucketName);
|
|
41
|
+
logger.info(`Bucket ${this.bucketName} created successfully.`);
|
|
42
|
+
}
|
|
43
|
+
catch (createError) {
|
|
44
|
+
logger.info(`Failed to create bucket ${this.bucketName}: ${createError}`);
|
|
45
|
+
throw new Error(`Failed to create GCS bucket ${this.bucketName}: ${createError}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
logger.info(`Bucket ${this.bucketName} exists.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
logger.info(`Error during bucket initialization for ${this.bucketName}: ${error}`);
|
|
54
|
+
throw new Error(`Failed to initialize GCS bucket ${this.bucketName}: ${error}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async ensureBucketInitialized() {
|
|
58
|
+
await this.bucketInitialized;
|
|
59
|
+
}
|
|
60
|
+
getObjectPath(taskId, type) {
|
|
61
|
+
return `tasks/${taskId}/${type}.tar.gz`;
|
|
62
|
+
}
|
|
63
|
+
async save(task) {
|
|
64
|
+
await this.ensureBucketInitialized();
|
|
65
|
+
const taskId = task.id;
|
|
66
|
+
const persistedState = getPersistedState(task.metadata);
|
|
67
|
+
if (!persistedState) {
|
|
68
|
+
throw new Error(`Task ${taskId} is missing persisted state in metadata.`);
|
|
69
|
+
}
|
|
70
|
+
const workDir = process.cwd();
|
|
71
|
+
const metadataObjectPath = this.getObjectPath(taskId, 'metadata');
|
|
72
|
+
const workspaceObjectPath = this.getObjectPath(taskId, 'workspace');
|
|
73
|
+
const dataToStore = task.metadata;
|
|
74
|
+
try {
|
|
75
|
+
const jsonString = JSON.stringify(dataToStore);
|
|
76
|
+
const compressedMetadata = gzipSync(Buffer.from(jsonString));
|
|
77
|
+
const metadataFile = this.storage
|
|
78
|
+
.bucket(this.bucketName)
|
|
79
|
+
.file(metadataObjectPath);
|
|
80
|
+
await metadataFile.save(compressedMetadata, {
|
|
81
|
+
contentType: 'application/gzip',
|
|
82
|
+
});
|
|
83
|
+
logger.info(`Task ${taskId} metadata saved to GCS: gs://${this.bucketName}/${metadataObjectPath}`);
|
|
84
|
+
if (await fse.pathExists(workDir)) {
|
|
85
|
+
const entries = await fsPromises.readdir(workDir);
|
|
86
|
+
if (entries.length > 0) {
|
|
87
|
+
const tmpArchiveFile = join(tmpdir(), getTmpArchiveFilename(taskId));
|
|
88
|
+
try {
|
|
89
|
+
await tar.c({
|
|
90
|
+
gzip: true,
|
|
91
|
+
file: tmpArchiveFile,
|
|
92
|
+
cwd: workDir,
|
|
93
|
+
portable: true,
|
|
94
|
+
}, entries);
|
|
95
|
+
if (!(await fse.pathExists(tmpArchiveFile))) {
|
|
96
|
+
throw new Error(`tar.c command failed to create ${tmpArchiveFile}`);
|
|
97
|
+
}
|
|
98
|
+
const workspaceFile = this.storage
|
|
99
|
+
.bucket(this.bucketName)
|
|
100
|
+
.file(workspaceObjectPath);
|
|
101
|
+
const sourceStream = createReadStream(tmpArchiveFile);
|
|
102
|
+
const destStream = workspaceFile.createWriteStream({
|
|
103
|
+
contentType: 'application/gzip',
|
|
104
|
+
resumable: true,
|
|
105
|
+
});
|
|
106
|
+
await new Promise((resolve, reject) => {
|
|
107
|
+
sourceStream.on('error', (err) => {
|
|
108
|
+
logger.error(`Error in source stream for ${tmpArchiveFile}:`, err);
|
|
109
|
+
// Attempt to close destStream if source fails
|
|
110
|
+
if (!destStream.destroyed) {
|
|
111
|
+
destStream.destroy(err);
|
|
112
|
+
}
|
|
113
|
+
reject(err);
|
|
114
|
+
});
|
|
115
|
+
destStream.on('error', (err) => {
|
|
116
|
+
logger.error(`Error in GCS dest stream for ${workspaceObjectPath}:`, err);
|
|
117
|
+
reject(err);
|
|
118
|
+
});
|
|
119
|
+
destStream.on('finish', () => {
|
|
120
|
+
logger.info(`GCS destStream finished for ${workspaceObjectPath}`);
|
|
121
|
+
resolve();
|
|
122
|
+
});
|
|
123
|
+
logger.info(`Piping ${tmpArchiveFile} to GCS object ${workspaceObjectPath}`);
|
|
124
|
+
sourceStream.pipe(destStream);
|
|
125
|
+
});
|
|
126
|
+
logger.info(`Task ${taskId} workspace saved to GCS: gs://${this.bucketName}/${workspaceObjectPath}`);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
logger.error(`Error during workspace save process for ${taskId}:`, error);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
logger.info(`Cleaning up temporary file: ${tmpArchiveFile}`);
|
|
134
|
+
try {
|
|
135
|
+
if (await fse.pathExists(tmpArchiveFile)) {
|
|
136
|
+
await fse.remove(tmpArchiveFile);
|
|
137
|
+
logger.info(`Successfully removed temporary file: ${tmpArchiveFile}`);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
logger.warn(`Temporary file not found for cleanup: ${tmpArchiveFile}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (removeError) {
|
|
144
|
+
logger.error(`Error removing temporary file ${tmpArchiveFile}:`, removeError);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
logger.info(`Workspace directory ${workDir} is empty, skipping workspace save for task ${taskId}.`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
logger.info(`Workspace directory ${workDir} not found, skipping workspace save for task ${taskId}.`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
logger.error(`Failed to save task ${taskId} to GCS:`, error);
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async load(taskId) {
|
|
162
|
+
await this.ensureBucketInitialized();
|
|
163
|
+
const metadataObjectPath = this.getObjectPath(taskId, 'metadata');
|
|
164
|
+
const workspaceObjectPath = this.getObjectPath(taskId, 'workspace');
|
|
165
|
+
try {
|
|
166
|
+
const metadataFile = this.storage
|
|
167
|
+
.bucket(this.bucketName)
|
|
168
|
+
.file(metadataObjectPath);
|
|
169
|
+
const [metadataExists] = await metadataFile.exists();
|
|
170
|
+
if (!metadataExists) {
|
|
171
|
+
logger.info(`Task ${taskId} metadata not found in GCS.`);
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
const [compressedMetadata] = await metadataFile.download();
|
|
175
|
+
const jsonData = gunzipSync(compressedMetadata).toString();
|
|
176
|
+
const loadedMetadata = JSON.parse(jsonData);
|
|
177
|
+
logger.info(`Task ${taskId} metadata loaded from GCS.`);
|
|
178
|
+
const persistedState = getPersistedState(loadedMetadata);
|
|
179
|
+
if (!persistedState) {
|
|
180
|
+
throw new Error(`Loaded metadata for task ${taskId} is missing internal persisted state.`);
|
|
181
|
+
}
|
|
182
|
+
const agentSettings = persistedState._agentSettings;
|
|
183
|
+
const workDir = setTargetDir(agentSettings);
|
|
184
|
+
await fse.ensureDir(workDir);
|
|
185
|
+
const workspaceFile = this.storage
|
|
186
|
+
.bucket(this.bucketName)
|
|
187
|
+
.file(workspaceObjectPath);
|
|
188
|
+
const [workspaceExists] = await workspaceFile.exists();
|
|
189
|
+
if (workspaceExists) {
|
|
190
|
+
const tmpArchiveFile = join(tmpdir(), getTmpArchiveFilename(taskId));
|
|
191
|
+
try {
|
|
192
|
+
await workspaceFile.download({ destination: tmpArchiveFile });
|
|
193
|
+
await tar.x({ file: tmpArchiveFile, cwd: workDir });
|
|
194
|
+
logger.info(`Task ${taskId} workspace restored from GCS to ${workDir}`);
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
if (await fse.pathExists(tmpArchiveFile)) {
|
|
198
|
+
await fse.remove(tmpArchiveFile);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
logger.info(`Task ${taskId} workspace archive not found in GCS.`);
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
id: taskId,
|
|
207
|
+
contextId: loadedMetadata._contextId || uuidv4(),
|
|
208
|
+
kind: 'task',
|
|
209
|
+
status: {
|
|
210
|
+
state: persistedState._taskState,
|
|
211
|
+
timestamp: new Date().toISOString(),
|
|
212
|
+
},
|
|
213
|
+
metadata: loadedMetadata,
|
|
214
|
+
history: [],
|
|
215
|
+
artifacts: [],
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
logger.error(`Failed to load task ${taskId} from GCS:`, error);
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
export class NoOpTaskStore {
|
|
225
|
+
realStore;
|
|
226
|
+
constructor(realStore) {
|
|
227
|
+
this.realStore = realStore;
|
|
228
|
+
}
|
|
229
|
+
async save(task) {
|
|
230
|
+
logger.info(`[NoOpTaskStore] save called for task ${task.id} - IGNORED`);
|
|
231
|
+
return Promise.resolve();
|
|
232
|
+
}
|
|
233
|
+
async load(taskId) {
|
|
234
|
+
logger.info(`[NoOpTaskStore] load called for task ${taskId}, delegating to real store.`);
|
|
235
|
+
return this.realStore.load(taskId);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=gcs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcs.js","sourceRoot":"","sources":["../../../src/persistence/gcs.ts"],"names":[],"mappings":"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"}
|