From an independent review pass:
- Guard search / get / add against a null or empty 2xx body (previously an
uncaught TypeError on .results / .status); return [] or an empty object.
- Stringify non-string API error detail so a thrown message never renders as
"[object Object]".
- Correct the Add sample to the default no-wait shape {event_id, status}.
- Add a regression unit test for the null-body path.
Verified: build + zapier validate + 16 tests (13 unit, 3 live E2E), plus a
live check of the v3-add to /v1/event poll cross-version path.
41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
import type { ZObject, Bundle, Memory } from '../types';
|
|
import { captureEvent } from '../telemetry';
|
|
|
|
const perform = async (z: ZObject, bundle: Bundle): Promise<Memory[]> => {
|
|
const body: Record<string, unknown> = {
|
|
query: bundle.inputData.query,
|
|
output_format: 'v1.1',
|
|
top_k: Math.max(1, Math.floor(Number(bundle.inputData.limit) || 50)),
|
|
};
|
|
if (bundle.inputData.user_id) body.filters = { user_id: bundle.inputData.user_id };
|
|
|
|
captureEvent('zapier.search_memories', bundle.authData?.apiKey);
|
|
|
|
const response = await z.request({
|
|
url: '/v3/memories/search/',
|
|
method: 'POST',
|
|
body,
|
|
});
|
|
// Searches must return an array; guard against a null/empty body.
|
|
const data = response.data as Memory[] | { results?: Memory[] } | null;
|
|
return Array.isArray(data) ? data : data?.results ?? [];
|
|
};
|
|
|
|
export default {
|
|
key: 'search_memories',
|
|
noun: 'Memory',
|
|
display: {
|
|
label: 'Search Memories',
|
|
description: 'Semantic search over stored memories.',
|
|
},
|
|
operation: {
|
|
perform,
|
|
inputFields: [
|
|
{ key: 'query', label: 'Query', type: 'string', required: true },
|
|
{ key: 'user_id', label: 'User ID', type: 'string', required: true },
|
|
{ key: 'limit', label: 'Limit', type: 'integer', default: '50' },
|
|
],
|
|
sample: { id: '00000000-0000-0000-0000-000000000000', memory: 'User loves hiking' },
|
|
},
|
|
};
|