feat(coding): add Pi Data Service product tools
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import type { DataServiceToolDetailsV1 } from './data-service';
|
||||
|
||||
export type ConversationThinkingLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high';
|
||||
|
||||
export interface ProductModelRef {
|
||||
@@ -192,6 +194,8 @@ export interface RuntimeContextDetailsV1 {
|
||||
}>;
|
||||
}
|
||||
|
||||
export type { DataServiceToolDetailsV1 } from './data-service';
|
||||
|
||||
export interface SubagentDetailsV1 {
|
||||
schema: 'subagent.v1';
|
||||
dispatchId: string;
|
||||
@@ -214,6 +218,7 @@ export type KnownToolDetails =
|
||||
| AgentBrowserDetailsV1
|
||||
| GameAssetsDetailsV1
|
||||
| RuntimeContextDetailsV1
|
||||
| DataServiceToolDetailsV1
|
||||
| SubagentDetailsV1;
|
||||
|
||||
export interface ConversationToolNode {
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import type {
|
||||
AgentBrowserDetailsV1,
|
||||
ChangedFileDetailsV1,
|
||||
DataServiceToolDetailsV1,
|
||||
GameAssetsDetailsV1,
|
||||
KnownToolDetails,
|
||||
RuntimeContextDetailsV1,
|
||||
TaskStateDetailsV1,
|
||||
} from './coding-conversation-contracts';
|
||||
import {
|
||||
DATA_SERVICE_PI_TOOL_NAMES,
|
||||
type DataServiceErrorContext,
|
||||
type DataServiceToolData,
|
||||
type DataServicePiToolName,
|
||||
} from './data-service';
|
||||
|
||||
const PRODUCT_TOOL_NAMES = new Set([
|
||||
'agent_browser',
|
||||
@@ -14,8 +21,21 @@ const PRODUCT_TOOL_NAMES = new Set([
|
||||
'task_state',
|
||||
'changed_file',
|
||||
'runtime_context',
|
||||
...DATA_SERVICE_PI_TOOL_NAMES,
|
||||
]);
|
||||
|
||||
const DATA_SERVICE_CONTEXT_KEYS = new Set([
|
||||
'resource',
|
||||
'limit',
|
||||
'current',
|
||||
'attempted',
|
||||
'actual',
|
||||
'allowed',
|
||||
'current_revision',
|
||||
'retry_after_seconds',
|
||||
]);
|
||||
const DATA_SERVICE_CONTEXT_RESOURCES = new Set(['instances', 'collections', 'documents', 'bytes']);
|
||||
|
||||
function record(value: unknown): Record<string, unknown> | null {
|
||||
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
||||
? value as Record<string, unknown>
|
||||
@@ -133,6 +153,63 @@ function runtimeContextDetails(value: Record<string, unknown>): RuntimeContextDe
|
||||
return { schema: 'runtime-context.v1', skills, commands };
|
||||
}
|
||||
|
||||
function dataServiceContext(value: unknown): DataServiceErrorContext | undefined | null {
|
||||
if (value === undefined) return undefined;
|
||||
const source = record(value);
|
||||
if (!source || Object.keys(source).length > 8) return null;
|
||||
const context: DataServiceErrorContext = {};
|
||||
for (const [key, item] of Object.entries(source)) {
|
||||
if (!DATA_SERVICE_CONTEXT_KEYS.has(key)) return null;
|
||||
if (key === 'resource') {
|
||||
if (typeof item !== 'string' || !DATA_SERVICE_CONTEXT_RESOURCES.has(item)) return null;
|
||||
context[key] = item;
|
||||
} else if (Number.isSafeInteger(item) && (item as number) >= 0) {
|
||||
context[key] = item as number;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return Object.keys(context).length > 0 ? context : undefined;
|
||||
}
|
||||
|
||||
function dataServiceDetails(value: Record<string, unknown>): DataServiceToolDetailsV1 | null {
|
||||
if (!DATA_SERVICE_PI_TOOL_NAMES.includes(value.operation as DataServicePiToolName)) return null;
|
||||
if (typeof value.success !== 'boolean'
|
||||
|| !Number.isSafeInteger(value.status)
|
||||
|| (value.status as number) < 100 || (value.status as number) > 599
|
||||
|| (value.code !== null && text(value.code, 128) === null)
|
||||
|| (value.error !== null && text(value.error, 2_000) === null)
|
||||
|| typeof value.retryable !== 'boolean'
|
||||
|| !Object.prototype.hasOwnProperty.call(value, 'data')) return null;
|
||||
if (value.success) {
|
||||
if ((value.status as number) < 200 || (value.status as number) > 299
|
||||
|| value.code !== null || value.error !== null || value.retryable !== false) return null;
|
||||
} else if ((value.status as number) < 400 || value.code === null || value.error === null) {
|
||||
return null;
|
||||
}
|
||||
const retryAfter = value.retry_after_seconds;
|
||||
if (retryAfter !== undefined
|
||||
&& (!Number.isSafeInteger(retryAfter) || (retryAfter as number) < 0 || (retryAfter as number) > 86_400)) {
|
||||
return null;
|
||||
}
|
||||
const context = dataServiceContext(value.context);
|
||||
if (context === null) return null;
|
||||
const data = value.data === null ? null : record(value.data);
|
||||
if (value.data !== null && !data) return null;
|
||||
return {
|
||||
schema: 'data-service.v1',
|
||||
operation: value.operation as DataServicePiToolName,
|
||||
success: value.success,
|
||||
status: value.status as number,
|
||||
code: value.code as string | null,
|
||||
error: value.error as string | null,
|
||||
retryable: value.retryable,
|
||||
...(retryAfter === undefined ? {} : { retry_after_seconds: retryAfter as number }),
|
||||
...(context === undefined ? {} : { context }),
|
||||
data: data as DataServiceToolData | null,
|
||||
};
|
||||
}
|
||||
|
||||
export function productToolDetails(value: unknown): Exclude<KnownToolDetails, { schema: 'subagent.v1' | 'write-lease.v1' }> | null {
|
||||
const details = record(value);
|
||||
if (!details) return null;
|
||||
@@ -144,6 +221,7 @@ export function productToolDetails(value: unknown): Exclude<KnownToolDetails, {
|
||||
if (details.schema === 'agent-browser.v1') return browserDetails(details);
|
||||
if (details.schema === 'game-assets.v1') return gameAssetDetails(details);
|
||||
if (details.schema === 'runtime-context.v1') return runtimeContextDetails(details);
|
||||
if (details.schema === 'data-service.v1') return dataServiceDetails(details);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,21 @@ export type DataServiceDocumentList = {
|
||||
|
||||
export type DataServiceErrorContext = Record<string, string | number>;
|
||||
|
||||
export const DATA_SERVICE_PI_TOOL_NAMES = [
|
||||
'data_service_configure',
|
||||
'data_service_inspect',
|
||||
'data_service_list_projects',
|
||||
'data_service_get_document',
|
||||
'data_service_list_documents',
|
||||
'data_service_put_document',
|
||||
'data_service_delete_document',
|
||||
'data_service_remove_collection',
|
||||
'data_service_reset',
|
||||
'data_service_remove_project',
|
||||
] as const;
|
||||
|
||||
export type DataServicePiToolName = (typeof DATA_SERVICE_PI_TOOL_NAMES)[number];
|
||||
|
||||
export type DataServiceHostResult<T> = {
|
||||
success: boolean;
|
||||
status: number;
|
||||
@@ -73,6 +88,19 @@ export type DataServiceHostResult<T> = {
|
||||
data: T | null;
|
||||
};
|
||||
|
||||
export type DataServiceToolData =
|
||||
| DataServiceInstanceState
|
||||
| DataServiceInstanceList
|
||||
| DataServiceDocument
|
||||
| DataServiceDocumentList
|
||||
| DataServiceCollectionRemoval
|
||||
| DataServiceInstanceRemoval;
|
||||
|
||||
export type DataServiceToolDetailsV1 = DataServiceHostResult<DataServiceToolData> & {
|
||||
schema: 'data-service.v1';
|
||||
operation: DataServicePiToolName;
|
||||
};
|
||||
|
||||
export type DataServicePutDocumentInput = {
|
||||
collection: string;
|
||||
document_id: string;
|
||||
|
||||
Reference in New Issue
Block a user