quidproquo-actionprocessor-awslambda 0.1.24 → 0.1.25
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/lib/commonjs/getActionProcessor/core/ai/getAiPromptActionProcessor.js +1 -1
- package/lib/commonjs/getActionProcessor/core/ai/getAiPromptActionProcessor.js.map +1 -1
- package/lib/commonjs/getActionProcessor/core/ai/getAiPromptStreamActionProcessor.js +1 -4
- package/lib/commonjs/getActionProcessor/core/ai/getAiPromptStreamActionProcessor.js.map +1 -1
- package/lib/commonjs/getActionProcessor/core/ai/logic/buildAiStopConditions.d.ts +13 -0
- package/lib/commonjs/getActionProcessor/core/ai/logic/buildAiStopConditions.js +24 -0
- package/lib/commonjs/getActionProcessor/core/ai/logic/buildAiStopConditions.js.map +1 -0
- package/lib/commonjs/getActionProcessor/core/ai/logic/index.d.ts +1 -0
- package/lib/commonjs/getActionProcessor/core/ai/logic/index.js +1 -0
- package/lib/commonjs/getActionProcessor/core/ai/logic/index.js.map +1 -1
- package/lib/commonjs/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.d.ts +8 -0
- package/lib/commonjs/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.js +26 -0
- package/lib/commonjs/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.js.map +1 -0
- package/lib/commonjs/lambdaHandlers/helpers/getQpqLambdaRuntimeForEvent.js +6 -3
- package/lib/commonjs/lambdaHandlers/helpers/getQpqLambdaRuntimeForEvent.js.map +1 -1
- package/lib/commonjs/lambdaHandlers/helpers/index.d.ts +1 -0
- package/lib/commonjs/lambdaHandlers/helpers/index.js +1 -0
- package/lib/commonjs/lambdaHandlers/helpers/index.js.map +1 -1
- package/lib/esm/getActionProcessor/core/ai/getAiPromptActionProcessor.js +4 -3
- package/lib/esm/getActionProcessor/core/ai/getAiPromptActionProcessor.js.map +1 -1
- package/lib/esm/getActionProcessor/core/ai/getAiPromptStreamActionProcessor.js +4 -5
- package/lib/esm/getActionProcessor/core/ai/getAiPromptStreamActionProcessor.js.map +1 -1
- package/lib/esm/getActionProcessor/core/ai/logic/buildAiStopConditions.d.ts +13 -0
- package/lib/esm/getActionProcessor/core/ai/logic/buildAiStopConditions.js +20 -0
- package/lib/esm/getActionProcessor/core/ai/logic/buildAiStopConditions.js.map +1 -0
- package/lib/esm/getActionProcessor/core/ai/logic/index.d.ts +1 -0
- package/lib/esm/getActionProcessor/core/ai/logic/index.js +1 -0
- package/lib/esm/getActionProcessor/core/ai/logic/index.js.map +1 -1
- package/lib/esm/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.d.ts +8 -0
- package/lib/esm/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.js +13 -0
- package/lib/esm/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.js.map +1 -0
- package/lib/esm/lambdaHandlers/helpers/getQpqLambdaRuntimeForEvent.js +6 -2
- package/lib/esm/lambdaHandlers/helpers/getQpqLambdaRuntimeForEvent.js.map +1 -1
- package/lib/esm/lambdaHandlers/helpers/index.d.ts +1 -0
- package/lib/esm/lambdaHandlers/helpers/index.js +1 -0
- package/lib/esm/lambdaHandlers/helpers/index.js.map +1 -1
- package/package.json +7 -7
|
@@ -30,7 +30,7 @@ const getProcessAiPrompt = (qpqConfig) => {
|
|
|
30
30
|
const providerOptions = payload.reasoning
|
|
31
31
|
? { bedrock: { reasoningConfig: { type: 'enabled', budgetTokens: (_a = payload.reasoning.budgetTokens) !== null && _a !== void 0 ? _a : 4096 } } }
|
|
32
32
|
: undefined;
|
|
33
|
-
const result = yield (0, ai_1.generateText)(Object.assign(Object.assign({ model: prepared.model, system: (0, logic_1.toCacheableSystem)(payload.system, payload.caching) }, promptOrMessages), { tools: prepared.tools, providerOptions, stopWhen: (0,
|
|
33
|
+
const result = yield (0, ai_1.generateText)(Object.assign(Object.assign({ model: prepared.model, system: (0, logic_1.toCacheableSystem)(payload.system, payload.caching) }, promptOrMessages), { tools: prepared.tools, providerOptions, stopWhen: (0, logic_1.buildAiStopConditions)(payload), maxOutputTokens: payload.maxOutputTokens }));
|
|
34
34
|
if (payload.caching) {
|
|
35
35
|
// The SDK's cross-provider usage breakdown, not providerMetadata.bedrock.usage; that
|
|
36
36
|
// field never carries cacheReadInputTokens through on @ai-sdk/amazon-bedrock (5.0.11).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAiPromptActionProcessor.js","sourceRoot":"","sources":["../../../../../src/getActionProcessor/core/ai/getAiPromptActionProcessor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDASyB;AAEzB,
|
|
1
|
+
{"version":3,"file":"getAiPromptActionProcessor.js","sourceRoot":"","sources":["../../../../../src/getActionProcessor/core/ai/getAiPromptActionProcessor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDASyB;AAEzB,2BAAkC;AAElC,mCAAqJ;AAErJ,MAAM,kBAAkB,GAAG,CAAC,SAAoB,EAAoC,EAAE;IACpF,OAAO,CAAO,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,aAAa,EAAE,mBAAmB,EAAE,cAAc,EAAE,EAAE;;QACjH,MAAM,QAAQ,GAAG,IAAA,2BAAmB,EAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,EAAE,cAAc,CAAC,CAAC;QACpI,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;YACxB,OAAO,IAAA,mCAAiB,EAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ;gBACvC,CAAC,CAAC;oBACE,QAAQ,EAAE,IAAA,2BAAmB,EAC3B,MAAM,IAAA,qBAAa,EACjB,OAAO,CAAC,QAAQ,EAChB,IAAA,+BAAuB,EAAC,SAAS,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,EAAE,cAAc,CAAC,CAC9G,EACD,OAAO,CAAC,OAAO,CAChB;iBACF;gBACH,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YAE/B,kFAAkF;YAClF,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS;gBACvC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,SAAkB,EAAE,YAAY,EAAE,MAAA,OAAO,CAAC,SAAS,CAAC,YAAY,mCAAI,IAAI,EAAE,EAAE,EAAE;gBACtH,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,MAAM,GAAG,MAAM,IAAA,iBAAY,gCAC/B,KAAK,EAAE,QAAQ,CAAC,KAAK,EACrB,MAAM,EAAE,IAAA,yBAAiB,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,IACvD,gBAAgB,KACnB,KAAK,EAAE,QAAQ,CAAC,KAAK,EACrB,eAAe,EACf,QAAQ,EAAE,IAAA,6BAAqB,EAAC,OAAO,CAAC,EACxC,eAAe,EAAE,OAAO,CAAC,eAAe,IACxC,CAAC;YAEH,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,qFAAqF;gBACrF,uFAAuF;gBACvF,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAA,MAAA,MAAM,CAAC,SAAS,0CAAE,KAAK,0CAAE,iBAAiB,CAAC,CAAC;YACpF,CAAC;YAED,OAAO,IAAA,8BAAY,EAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,OAAO,IAAA,mCAAiB,EAAC,+BAAa,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACtE,CAAC;YAED,OAAO,IAAA,mCAAiB,EAAC,+BAAa,CAAC,YAAY,EAAE,+CAA+C,CAAC,CAAC;QACxG,CAAC;IACH,CAAC,CAAA,CAAC;AACJ,CAAC,CAAC;AAEW,QAAA,0BAA0B,GAAG,IAAA,uCAAqB,EAAC,6BAAW,EAAE,kBAAkB,CAAC,CAAC","sourcesContent":["import {\n actionResult,\n actionResultError,\n AiActionType,\n askAiPrompt,\n createActionProcessor,\n ErrorTypeEnum,\n ProcessorFor,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport { generateText } from 'ai';\n\nimport { buildAiStopConditions, createDriveFileResolver, prepareAiPromptCall, toCacheableMessages, toCacheableSystem, toSdkMessages } from './logic';\n\nconst getProcessAiPrompt = (qpqConfig: QPQConfig): ProcessorFor<typeof askAiPrompt> => {\n return async (payload, session, actionProcessorList, logger, updateSession, dynamicModuleLoader, streamRegistry) => {\n const prepared = prepareAiPromptCall(qpqConfig, payload, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry);\n if ('error' in prepared) {\n return actionResultError(prepared.error.type, prepared.error.message);\n }\n\n try {\n const promptOrMessages = payload.messages\n ? {\n messages: toCacheableMessages(\n await toSdkMessages(\n payload.messages,\n createDriveFileResolver(qpqConfig, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry),\n ),\n payload.caching,\n ),\n }\n : { prompt: payload.prompt };\n\n // Extended thinking: the model reasons before answering, within the token budget.\n const providerOptions = payload.reasoning\n ? { bedrock: { reasoningConfig: { type: 'enabled' as const, budgetTokens: payload.reasoning.budgetTokens ?? 4096 } } }\n : undefined;\n\n const result = await generateText({\n model: prepared.model,\n system: toCacheableSystem(payload.system, payload.caching),\n ...promptOrMessages,\n tools: prepared.tools,\n providerOptions,\n stopWhen: buildAiStopConditions(payload),\n maxOutputTokens: payload.maxOutputTokens,\n });\n\n if (payload.caching) {\n // The SDK's cross-provider usage breakdown, not providerMetadata.bedrock.usage; that\n // field never carries cacheReadInputTokens through on @ai-sdk/amazon-bedrock (5.0.11).\n console.log('AI prompt cache usage:', result.finalStep?.usage?.inputTokenDetails);\n }\n\n return actionResult({ text: result.text });\n } catch (error) {\n if (error instanceof Error) {\n return actionResultError(ErrorTypeEnum.GenericError, error.message);\n }\n\n return actionResultError(ErrorTypeEnum.GenericError, 'An error occurred during AI prompt execution.');\n }\n };\n};\n\nexport const getAiPromptActionProcessor = createActionProcessor(askAiPrompt, getProcessAiPrompt);\n"]}
|
|
@@ -51,10 +51,7 @@ const getProcessAiPromptStream = (qpqConfig) => {
|
|
|
51
51
|
const providerOptions = payload.reasoning
|
|
52
52
|
? { bedrock: { reasoningConfig: { type: 'enabled', budgetTokens: (_a = payload.reasoning.budgetTokens) !== null && _a !== void 0 ? _a : 4096 } } }
|
|
53
53
|
: undefined;
|
|
54
|
-
const { fullStream, finalStep } = (0, ai_1.streamText)(Object.assign(Object.assign({ model: prepared.model, system: (0, logic_1.toCacheableSystem)(payload.system, payload.caching) }, promptOrMessages), { tools: prepared.tools, providerOptions,
|
|
55
|
-
// Caps the server-side tool loop. Client-side tools (no executor) still halt
|
|
56
|
-
// immediately with finishReason 'tool-calls' so the caller can resume the turn.
|
|
57
|
-
stopWhen: (0, ai_1.stepCountIs)(20),
|
|
54
|
+
const { fullStream, finalStep } = (0, ai_1.streamText)(Object.assign(Object.assign({ model: prepared.model, system: (0, logic_1.toCacheableSystem)(payload.system, payload.caching) }, promptOrMessages), { tools: prepared.tools, providerOptions, stopWhen: (0, logic_1.buildAiStopConditions)(payload), maxOutputTokens: payload.maxOutputTokens,
|
|
58
55
|
// streamText swallows errors by default to keep the server alive; surface them to
|
|
59
56
|
// CloudWatch. The same error also reaches the consumer as an Error stream part.
|
|
60
57
|
onError: ({ error }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAiPromptStreamActionProcessor.js","sourceRoot":"","sources":["../../../../../src/getActionProcessor/core/ai/getAiPromptStreamActionProcessor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qDASyB;AAEzB,
|
|
1
|
+
{"version":3,"file":"getAiPromptStreamActionProcessor.js","sourceRoot":"","sources":["../../../../../src/getActionProcessor/core/ai/getAiPromptStreamActionProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n actionResult,\n actionResultError,\n AiActionType,\n askAiPromptStream,\n createActionProcessor,\n ErrorTypeEnum,\n ProcessorFor,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport { streamText } from 'ai';\n\nimport { randomGuid } from '../../../awsLambdaUtils';\nimport {\n buildAiStopConditions,\n createDriveFileResolver,\n mapAiStreamPart,\n prepareAiPromptCall,\n toCacheableMessages,\n toCacheableSystem,\n toErrorMessage,\n toSdkMessages,\n} from './logic';\n\nconst getProcessAiPromptStream = (qpqConfig: QPQConfig): ProcessorFor<typeof askAiPromptStream> => {\n return async (payload, session, actionProcessorList, logger, updateSession, dynamicModuleLoader, streamRegistry) => {\n const prepared = prepareAiPromptCall(qpqConfig, payload, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry);\n if ('error' in prepared) {\n return actionResultError(prepared.error.type, prepared.error.message);\n }\n\n try {\n const promptOrMessages = payload.messages\n ? {\n messages: toCacheableMessages(\n await toSdkMessages(\n payload.messages,\n createDriveFileResolver(qpqConfig, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry),\n ),\n payload.caching,\n ),\n }\n : { prompt: payload.prompt };\n\n // Extended thinking: thinking progress streams out as Reasoning* parts.\n const providerOptions = payload.reasoning\n ? { bedrock: { reasoningConfig: { type: 'enabled' as const, budgetTokens: payload.reasoning.budgetTokens ?? 4096 } } }\n : undefined;\n\n const { fullStream, finalStep } = streamText({\n model: prepared.model,\n system: toCacheableSystem(payload.system, payload.caching),\n ...promptOrMessages,\n tools: prepared.tools,\n providerOptions,\n stopWhen: buildAiStopConditions(payload),\n maxOutputTokens: payload.maxOutputTokens,\n // streamText swallows errors by default to keep the server alive; surface them to\n // CloudWatch. The same error also reaches the consumer as an Error stream part.\n onError: ({ error }) => {\n console.error('AI prompt stream error:', error);\n },\n });\n\n const streamId = `ai-prompt-${Date.now()}-${randomGuid()}`;\n\n async function* aiStreamIterator(): AsyncIterableIterator<string> {\n for await (const part of fullStream) {\n yield JSON.stringify(mapAiStreamPart(part));\n }\n\n if (payload.caching) {\n try {\n // The SDK's cross-provider usage breakdown, not providerMetadata.bedrock.usage; that\n // field never carries cacheReadInputTokens through on @ai-sdk/amazon-bedrock (5.0.11).\n const step = await finalStep;\n console.log('AI prompt cache usage:', step.usage?.inputTokenDetails);\n } catch (error) {\n // finalStep rejects (AI_NoOutputGeneratedError) when the stream errored before\n // completing a step. The error part has already been streamed to the consumer;\n // throwing here would replace that real error with the unhelpful wrapper.\n console.warn('AI prompt cache usage unavailable:', toErrorMessage(error));\n }\n }\n }\n\n streamRegistry.register(streamId, aiStreamIterator());\n\n return actionResult({ id: streamId, encoding: 'json' as const });\n } catch (error) {\n if (error instanceof Error) {\n return actionResultError(ErrorTypeEnum.GenericError, error.message);\n }\n\n return actionResultError(ErrorTypeEnum.GenericError, 'An error occurred during AI prompt stream.');\n }\n };\n};\n\nexport const getAiPromptStreamActionProcessor = createActionProcessor(askAiPromptStream, getProcessAiPromptStream);\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StopCondition, ToolSet } from 'ai';
|
|
2
|
+
export type AiStopLimits = {
|
|
3
|
+
maxSteps?: number;
|
|
4
|
+
maxDurationMs?: number;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* The `stopWhen` set for a prompt. The SDK defaults to a single step, so this always
|
|
8
|
+
* returns a list, even an empty one: with no limits the loop runs until the model stops
|
|
9
|
+
* on its own (a client-side tool call still halts it). Conditions only run between
|
|
10
|
+
* steps, so the time cap can overrun by one step; callers leave headroom. Its clock
|
|
11
|
+
* starts when this is built, which is just before the SDK call.
|
|
12
|
+
*/
|
|
13
|
+
export declare const buildAiStopConditions: ({ maxSteps, maxDurationMs }: AiStopLimits, now?: () => number) => StopCondition<ToolSet>[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildAiStopConditions = void 0;
|
|
4
|
+
const ai_1 = require("ai");
|
|
5
|
+
/**
|
|
6
|
+
* The `stopWhen` set for a prompt. The SDK defaults to a single step, so this always
|
|
7
|
+
* returns a list, even an empty one: with no limits the loop runs until the model stops
|
|
8
|
+
* on its own (a client-side tool call still halts it). Conditions only run between
|
|
9
|
+
* steps, so the time cap can overrun by one step; callers leave headroom. Its clock
|
|
10
|
+
* starts when this is built, which is just before the SDK call.
|
|
11
|
+
*/
|
|
12
|
+
const buildAiStopConditions = ({ maxSteps, maxDurationMs }, now = Date.now) => {
|
|
13
|
+
const conditions = [];
|
|
14
|
+
if (maxSteps !== undefined) {
|
|
15
|
+
conditions.push((0, ai_1.stepCountIs)(maxSteps));
|
|
16
|
+
}
|
|
17
|
+
if (maxDurationMs !== undefined) {
|
|
18
|
+
const startedAt = now();
|
|
19
|
+
conditions.push(() => now() - startedAt >= maxDurationMs);
|
|
20
|
+
}
|
|
21
|
+
return conditions;
|
|
22
|
+
};
|
|
23
|
+
exports.buildAiStopConditions = buildAiStopConditions;
|
|
24
|
+
//# sourceMappingURL=buildAiStopConditions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildAiStopConditions.js","sourceRoot":"","sources":["../../../../../../src/getActionProcessor/core/ai/logic/buildAiStopConditions.ts"],"names":[],"mappings":";;;AAAA,2BAAyD;AAOzD;;;;;;GAMG;AACI,MAAM,qBAAqB,GAAG,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAgB,EAAE,MAAoB,IAAI,CAAC,GAAG,EAA4B,EAAE;IACzI,MAAM,UAAU,GAA6B,EAAE,CAAC;IAEhD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,IAAA,gBAAW,EAAC,QAAQ,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;QACxB,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,aAAa,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAbW,QAAA,qBAAqB,yBAahC","sourcesContent":["import { stepCountIs, StopCondition, ToolSet } from 'ai';\n\nexport type AiStopLimits = {\n maxSteps?: number;\n maxDurationMs?: number;\n};\n\n/**\n * The `stopWhen` set for a prompt. The SDK defaults to a single step, so this always\n * returns a list, even an empty one: with no limits the loop runs until the model stops\n * on its own (a client-side tool call still halts it). Conditions only run between\n * steps, so the time cap can overrun by one step; callers leave headroom. Its clock\n * starts when this is built, which is just before the SDK call.\n */\nexport const buildAiStopConditions = ({ maxSteps, maxDurationMs }: AiStopLimits, now: () => number = Date.now): StopCondition<ToolSet>[] => {\n const conditions: StopCondition<ToolSet>[] = [];\n\n if (maxSteps !== undefined) {\n conditions.push(stepCountIs(maxSteps));\n }\n\n if (maxDurationMs !== undefined) {\n const startedAt = now();\n conditions.push(() => now() - startedAt >= maxDurationMs);\n }\n\n return conditions;\n};\n"]}
|
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./aiStreamPartMappers"), exports);
|
|
18
|
+
__exportStar(require("./buildAiStopConditions"), exports);
|
|
18
19
|
__exportStar(require("./createDriveFileResolver"), exports);
|
|
19
20
|
__exportStar(require("./mapAiStreamAbort"), exports);
|
|
20
21
|
__exportStar(require("./mapAiStreamCustom"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/getActionProcessor/core/ai/logic/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,4DAA0C;AAC1C,qDAAmC;AACnC,sDAAoC;AACpC,qDAAmC;AACnC,wDAAsC;AACtC,sDAAoC;AACpC,0DAAwC;AACxC,oDAAkC;AAClC,mDAAiC;AACjC,8DAA4C;AAC5C,4DAA0C;AAC1C,iEAA+C;AAC/C,8DAA4C;AAC5C,0DAAwC;AACxC,qDAAmC;AACnC,yDAAuC;AACvC,yDAAuC;AACvC,uDAAqC;AACrC,yDAAuC;AACvC,mEAAiD;AACjD,oEAAkD;AAClD,wDAAsC;AACtC,yDAAuC;AACvC,8DAA4C;AAC5C,4DAA0C;AAC1C,8DAA4C;AAC5C,gEAA8C;AAC9C,0DAAwC;AACxC,wDAAsC;AACtC,2DAAyC;AACzC,oDAAkC;AAClC,wDAAsC;AACtC,sDAAoC;AACpC,mDAAiC;AACjC,kDAAgC","sourcesContent":["export * from './aiStreamPartMappers';\nexport * from './createDriveFileResolver';\nexport * from './mapAiStreamAbort';\nexport * from './mapAiStreamCustom';\nexport * from './mapAiStreamError';\nexport * from './mapAiStreamFilePart';\nexport * from './mapAiStreamFinish';\nexport * from './mapAiStreamFinishStep';\nexport * from './mapAiStreamPart';\nexport * from './mapAiStreamRaw';\nexport * from './mapAiStreamReasoningDelta';\nexport * from './mapAiStreamReasoningEnd';\nexport * from './mapAiStreamReasoningFilePart';\nexport * from './mapAiStreamReasoningStart';\nexport * from './mapAiStreamSourcePart';\nexport * from './mapAiStreamStart';\nexport * from './mapAiStreamStartStep';\nexport * from './mapAiStreamTextDelta';\nexport * from './mapAiStreamTextEnd';\nexport * from './mapAiStreamTextStart';\nexport * from './mapAiStreamToolApprovalRequest';\nexport * from './mapAiStreamToolApprovalResponse';\nexport * from './mapAiStreamToolCall';\nexport * from './mapAiStreamToolError';\nexport * from './mapAiStreamToolInputDelta';\nexport * from './mapAiStreamToolInputEnd';\nexport * from './mapAiStreamToolInputStart';\nexport * from './mapAiStreamToolOutputDenied';\nexport * from './mapAiStreamToolResult';\nexport * from './prepareAiPromptCall';\nexport * from './toAiStreamFinishReason';\nexport * from './toAiStreamUsage';\nexport * from './toCacheableMessages';\nexport * from './toCacheableSystem';\nexport * from './toErrorMessage';\nexport * from './toSdkMessages';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/getActionProcessor/core/ai/logic/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,0DAAwC;AACxC,4DAA0C;AAC1C,qDAAmC;AACnC,sDAAoC;AACpC,qDAAmC;AACnC,wDAAsC;AACtC,sDAAoC;AACpC,0DAAwC;AACxC,oDAAkC;AAClC,mDAAiC;AACjC,8DAA4C;AAC5C,4DAA0C;AAC1C,iEAA+C;AAC/C,8DAA4C;AAC5C,0DAAwC;AACxC,qDAAmC;AACnC,yDAAuC;AACvC,yDAAuC;AACvC,uDAAqC;AACrC,yDAAuC;AACvC,mEAAiD;AACjD,oEAAkD;AAClD,wDAAsC;AACtC,yDAAuC;AACvC,8DAA4C;AAC5C,4DAA0C;AAC1C,8DAA4C;AAC5C,gEAA8C;AAC9C,0DAAwC;AACxC,wDAAsC;AACtC,2DAAyC;AACzC,oDAAkC;AAClC,wDAAsC;AACtC,sDAAoC;AACpC,mDAAiC;AACjC,kDAAgC","sourcesContent":["export * from './aiStreamPartMappers';\nexport * from './buildAiStopConditions';\nexport * from './createDriveFileResolver';\nexport * from './mapAiStreamAbort';\nexport * from './mapAiStreamCustom';\nexport * from './mapAiStreamError';\nexport * from './mapAiStreamFilePart';\nexport * from './mapAiStreamFinish';\nexport * from './mapAiStreamFinishStep';\nexport * from './mapAiStreamPart';\nexport * from './mapAiStreamRaw';\nexport * from './mapAiStreamReasoningDelta';\nexport * from './mapAiStreamReasoningEnd';\nexport * from './mapAiStreamReasoningFilePart';\nexport * from './mapAiStreamReasoningStart';\nexport * from './mapAiStreamSourcePart';\nexport * from './mapAiStreamStart';\nexport * from './mapAiStreamStartStep';\nexport * from './mapAiStreamTextDelta';\nexport * from './mapAiStreamTextEnd';\nexport * from './mapAiStreamTextStart';\nexport * from './mapAiStreamToolApprovalRequest';\nexport * from './mapAiStreamToolApprovalResponse';\nexport * from './mapAiStreamToolCall';\nexport * from './mapAiStreamToolError';\nexport * from './mapAiStreamToolInputDelta';\nexport * from './mapAiStreamToolInputEnd';\nexport * from './mapAiStreamToolInputStart';\nexport * from './mapAiStreamToolOutputDenied';\nexport * from './mapAiStreamToolResult';\nexport * from './prepareAiPromptCall';\nexport * from './toAiStreamFinishReason';\nexport * from './toAiStreamUsage';\nexport * from './toCacheableMessages';\nexport * from './toCacheableSystem';\nexport * from './toErrorMessage';\nexport * from './toSdkMessages';\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActionProcessorList } from 'quidproquo-core';
|
|
2
|
+
import { Context } from 'aws-lambda';
|
|
3
|
+
/**
|
|
4
|
+
* Overrides the js "unlimited" GetRuntimeRemainingTime processor with the real lambda
|
|
5
|
+
* deadline. The context is per invocation, so this is built inside the handler and
|
|
6
|
+
* spread over the shared processor list on every invoke.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getLambdaRuntimeRemainingTimeActionProcessor: (context: Context) => ActionProcessorList;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getLambdaRuntimeRemainingTimeActionProcessor = void 0;
|
|
13
|
+
const quidproquo_core_1 = require("quidproquo-core");
|
|
14
|
+
/**
|
|
15
|
+
* Overrides the js "unlimited" GetRuntimeRemainingTime processor with the real lambda
|
|
16
|
+
* deadline. The context is per invocation, so this is built inside the handler and
|
|
17
|
+
* spread over the shared processor list on every invoke.
|
|
18
|
+
*/
|
|
19
|
+
const getLambdaRuntimeRemainingTimeActionProcessor = (context) => {
|
|
20
|
+
const processGetRuntimeRemainingTime = () => __awaiter(void 0, void 0, void 0, function* () { return (0, quidproquo_core_1.actionResult)(context.getRemainingTimeInMillis()); });
|
|
21
|
+
return {
|
|
22
|
+
[quidproquo_core_1.SystemActionType.GetRuntimeRemainingTime]: processGetRuntimeRemainingTime,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
exports.getLambdaRuntimeRemainingTimeActionProcessor = getLambdaRuntimeRemainingTimeActionProcessor;
|
|
26
|
+
//# sourceMappingURL=getLambdaRuntimeRemainingTimeActionProcessor.js.map
|
package/lib/commonjs/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getLambdaRuntimeRemainingTimeActionProcessor.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAgI;AAIhI;;;;GAIG;AACI,MAAM,4CAA4C,GAAG,CAAC,OAAgB,EAAuB,EAAE;IACpG,MAAM,8BAA8B,GAAoD,GAAS,EAAE,kDACjG,OAAA,IAAA,8BAAY,EAAC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAA,GAAA,CAAC;IAEnD,OAAO;QACL,CAAC,kCAAgB,CAAC,uBAAuB,CAAC,EAAE,8BAA8B;KAC3E,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,4CAA4C,gDAOvD","sourcesContent":["import { ActionProcessorList, actionResult, askGetRuntimeRemainingTime, ProcessorFor, SystemActionType } from 'quidproquo-core';\n\nimport { Context } from 'aws-lambda';\n\n/**\n * Overrides the js \"unlimited\" GetRuntimeRemainingTime processor with the real lambda\n * deadline. The context is per invocation, so this is built inside the handler and\n * spread over the shared processor list on every invoke.\n */\nexport const getLambdaRuntimeRemainingTimeActionProcessor = (context: Context): ActionProcessorList => {\n const processGetRuntimeRemainingTime: ProcessorFor<typeof askGetRuntimeRemainingTime> = async () =>\n actionResult(context.getRemainingTimeInMillis());\n\n return {\n [SystemActionType.GetRuntimeRemainingTime]: processGetRuntimeRemainingTime,\n };\n};\n"]}
|
|
@@ -14,6 +14,7 @@ const quidproquo_actionprocessor_js_1 = require("quidproquo-actionprocessor-js")
|
|
|
14
14
|
const quidproquo_core_1 = require("quidproquo-core");
|
|
15
15
|
const getActionProcessor_1 = require("../../getActionProcessor");
|
|
16
16
|
const dynamicModuleLoaderWarmer_1 = require("./dynamicModuleLoaderWarmer");
|
|
17
|
+
const getLambdaRuntimeRemainingTimeActionProcessor_1 = require("./getLambdaRuntimeRemainingTimeActionProcessor");
|
|
17
18
|
const getLogger_1 = require("./getLogger");
|
|
18
19
|
const getRuntimeCorrelation_1 = require("./getRuntimeCorrelation");
|
|
19
20
|
const isSnsWarmerRecord_1 = require("./isSnsWarmerRecord");
|
|
@@ -32,13 +33,15 @@ const isSnsEvent = (event) => {
|
|
|
32
33
|
* short-circuits SNS warmer pings, runs the process-event story and ships logs.
|
|
33
34
|
*/
|
|
34
35
|
const getQpqLambdaRuntimeForEvent = (runtimeType, getStorySession, getActionProcessorList, dynamicModuleLoader, qpqConfig, getProcessEventStory = () => quidproquo_core_1.askProcessEvent) => {
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
// Built per invoke: the lambda context (and so the execution deadline) is not
|
|
37
|
+
// known until the handler runs.
|
|
38
|
+
const getResolveActionProcessorList = (context) => () => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
return (Object.assign(Object.assign(Object.assign(Object.assign({}, (yield (0, getActionProcessor_1.getAwsActionProcessors)(qpqConfig, dynamicModuleLoader))), (yield getActionProcessorList(qpqConfig, dynamicModuleLoader))), (0, getLambdaRuntimeRemainingTimeActionProcessor_1.getLambdaRuntimeRemainingTimeActionProcessor)(context)), (yield (0, quidproquo_actionprocessor_js_1.getCustomActionActionProcessor)(qpqConfig, dynamicModuleLoader))));
|
|
37
40
|
});
|
|
38
41
|
return (event, context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
42
|
console.log('tick: ', JSON.stringify(event, null, 2));
|
|
40
43
|
const logger = (0, getLogger_1.getLogger)(qpqConfig);
|
|
41
|
-
const resolveStory = (0, quidproquo_core_1.createRuntime)(qpqConfig, getStorySession(event),
|
|
44
|
+
const resolveStory = (0, quidproquo_core_1.createRuntime)(qpqConfig, getStorySession(event), getResolveActionProcessorList(context), () => new Date().toISOString(), logger, (0, getRuntimeCorrelation_1.getRuntimeCorrelation)(qpqConfig), runtimeType, dynamicModuleLoader);
|
|
42
45
|
const processEvent = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
46
|
const result = yield resolveStory(getProcessEventStory(), [event, context]);
|
|
44
47
|
yield logger.waitToFinishWriting();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getQpqLambdaRuntimeForEvent.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/getQpqLambdaRuntimeForEvent.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iFAA+E;AAC/E,qDASyB;AAIzB,iEAAkE;AAElE,2EAAwE;AACxE,2CAAwC;AACxC,mEAAgE;AAChE,2DAAwD;AAExD,gFAAgF;AAChF,gFAAgF;AAChF,iFAAiF;AACjF,MAAM,UAAU,GAAG,CAAI,KAAmC,EAAqB,EAAE;IAC/E,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,gBAAgB,GAAG,KAA4B,CAAC;QACtD,OAAO,gBAAgB,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;GAGG;AACI,MAAM,2BAA2B,GAAG,CACzC,WAA2B,EAC3B,eAA2C,EAC3C,sBAAmD,EACnD,mBAAwC,EACxC,SAAoB,EACpB,uBAAqD,GAAG,EAAE,CAAC,iCAAe,EAC1E,EAAE;IACF,MAAM,
|
|
1
|
+
{"version":3,"file":"getQpqLambdaRuntimeForEvent.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/getQpqLambdaRuntimeForEvent.ts"],"names":[],"mappings":"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","sourcesContent":["import { getCustomActionActionProcessor } from 'quidproquo-actionprocessor-js';\nimport {\n ActionProcessorList,\n ActionProcessorListResolver,\n askProcessEvent,\n createRuntime,\n DynamicModuleLoader,\n QPQConfig,\n QpqRuntimeType,\n StorySession,\n} from 'quidproquo-core';\n\nimport { Context, SNSEvent } from 'aws-lambda';\n\nimport { getAwsActionProcessors } from '../../getActionProcessor';\nimport { QpqFunctionExecutionEvent } from '../types';\nimport { dynamicModuleLoaderWarmer } from './dynamicModuleLoaderWarmer';\nimport { getLambdaRuntimeRemainingTimeActionProcessor } from './getLambdaRuntimeRemainingTimeActionProcessor';\nimport { getLogger } from './getLogger';\nimport { getRuntimeCorrelation } from './getRuntimeCorrelation';\nimport { isSnsWarmerRecord } from './isSnsWarmerRecord';\n\n// SQS/S3/CloudFront events also have a Records array, so this matches more than\n// real SNS events. That is harmless: the warmer scan below only acts on records\n// whose EventSource is 'aws:sns', everything else falls through to processEvent.\nconst isSnsEvent = <T>(event: QpqFunctionExecutionEvent<T>): event is SNSEvent => {\n if (event && typeof event === 'object') {\n const possibleSnsEvent = event as unknown as SNSEvent;\n return possibleSnsEvent.Records && Array.isArray(possibleSnsEvent.Records);\n }\n\n return false;\n};\n\n/**\n * Builds the shared lambda handler: wires a qpq runtime for the event type,\n * short-circuits SNS warmer pings, runs the process-event story and ships logs.\n */\nexport const getQpqLambdaRuntimeForEvent = <E extends QpqFunctionExecutionEvent<any>>(\n runtimeType: QpqRuntimeType,\n getStorySession: (event: E) => StorySession,\n getActionProcessorList: ActionProcessorListResolver,\n dynamicModuleLoader: DynamicModuleLoader,\n qpqConfig: QPQConfig,\n getProcessEventStory: () => typeof askProcessEvent = () => askProcessEvent,\n) => {\n // Built per invoke: the lambda context (and so the execution deadline) is not\n // known until the handler runs.\n const getResolveActionProcessorList = (context: Context) => async (): Promise<ActionProcessorList> => ({\n ...(await getAwsActionProcessors(qpqConfig, dynamicModuleLoader)),\n ...(await getActionProcessorList(qpqConfig, dynamicModuleLoader)),\n ...getLambdaRuntimeRemainingTimeActionProcessor(context),\n\n // Always done last, so they can override the default ones if the user wants.\n ...(await getCustomActionActionProcessor(qpqConfig, dynamicModuleLoader)),\n });\n\n return async (event: E, context: Context) => {\n console.log('tick: ', JSON.stringify(event, null, 2));\n\n const logger = getLogger(qpqConfig);\n\n const resolveStory = createRuntime(\n qpqConfig,\n getStorySession(event),\n getResolveActionProcessorList(context),\n () => new Date().toISOString(),\n logger,\n getRuntimeCorrelation(qpqConfig),\n runtimeType,\n dynamicModuleLoader,\n );\n\n const processEvent = async () => {\n const result = await resolveStory(getProcessEventStory(), [event, context]);\n await logger.waitToFinishWriting();\n\n if (result.error) {\n throw new Error(result.error.errorText);\n }\n\n console.log('Finished, returning: ', result.result);\n return result.result;\n };\n\n if (isSnsEvent(event)) {\n const recordsNoWarm = event.Records.filter((record) => !isSnsWarmerRecord(record));\n\n // A warmer ping arrives as its own single-record SNS event; any warmer\n // present means this invoke exists only to keep the sandbox warm.\n if (recordsNoWarm.length !== event.Records.length) {\n console.log('Found SNS warmer');\n\n // TODO: Warm qpq things with dynamic functions\n // federate in dynamic modules\n await dynamicModuleLoaderWarmer();\n\n // Might as well move the logs to permanent storage\n await logger.moveToPermanentStorage();\n\n return 'Warmed up!';\n }\n }\n\n return await processEvent();\n };\n};\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './dynamicModuleLoaderWarmer';
|
|
2
2
|
export * from './getBlankStorySession';
|
|
3
|
+
export * from './getLambdaRuntimeRemainingTimeActionProcessor';
|
|
3
4
|
export * from './getLogger';
|
|
4
5
|
export * from './getQpqLambdaRuntimeForEvent';
|
|
5
6
|
export * from './getRuntimeCorrelation';
|
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./dynamicModuleLoaderWarmer"), exports);
|
|
18
18
|
__exportStar(require("./getBlankStorySession"), exports);
|
|
19
|
+
__exportStar(require("./getLambdaRuntimeRemainingTimeActionProcessor"), exports);
|
|
19
20
|
__exportStar(require("./getLogger"), exports);
|
|
20
21
|
__exportStar(require("./getQpqLambdaRuntimeForEvent"), exports);
|
|
21
22
|
__exportStar(require("./getRuntimeCorrelation"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8DAA4C;AAC5C,yDAAuC;AACvC,8CAA4B;AAC5B,gEAA8C;AAC9C,0DAAwC;AACxC,sDAAoC","sourcesContent":["export * from './dynamicModuleLoaderWarmer';\nexport * from './getBlankStorySession';\nexport * from './getLogger';\nexport * from './getQpqLambdaRuntimeForEvent';\nexport * from './getRuntimeCorrelation';\nexport * from './isSnsWarmerRecord';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8DAA4C;AAC5C,yDAAuC;AACvC,iFAA+D;AAC/D,8CAA4B;AAC5B,gEAA8C;AAC9C,0DAAwC;AACxC,sDAAoC","sourcesContent":["export * from './dynamicModuleLoaderWarmer';\nexport * from './getBlankStorySession';\nexport * from './getLambdaRuntimeRemainingTimeActionProcessor';\nexport * from './getLogger';\nexport * from './getQpqLambdaRuntimeForEvent';\nexport * from './getRuntimeCorrelation';\nexport * from './isSnsWarmerRecord';\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { actionResult, actionResultError, askAiPrompt, createActionProcessor, ErrorTypeEnum, } from 'quidproquo-core';
|
|
2
|
-
import { generateText
|
|
3
|
-
import { createDriveFileResolver, prepareAiPromptCall, toCacheableMessages, toCacheableSystem, toSdkMessages } from './logic';
|
|
2
|
+
import { generateText } from 'ai';
|
|
3
|
+
import { buildAiStopConditions, createDriveFileResolver, prepareAiPromptCall, toCacheableMessages, toCacheableSystem, toSdkMessages } from './logic';
|
|
4
4
|
const getProcessAiPrompt = (qpqConfig) => {
|
|
5
5
|
return async (payload, session, actionProcessorList, logger, updateSession, dynamicModuleLoader, streamRegistry) => {
|
|
6
6
|
const prepared = prepareAiPromptCall(qpqConfig, payload, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry);
|
|
@@ -23,7 +23,8 @@ const getProcessAiPrompt = (qpqConfig) => {
|
|
|
23
23
|
...promptOrMessages,
|
|
24
24
|
tools: prepared.tools,
|
|
25
25
|
providerOptions,
|
|
26
|
-
stopWhen:
|
|
26
|
+
stopWhen: buildAiStopConditions(payload),
|
|
27
|
+
maxOutputTokens: payload.maxOutputTokens,
|
|
27
28
|
});
|
|
28
29
|
if (payload.caching) {
|
|
29
30
|
// The SDK's cross-provider usage breakdown, not providerMetadata.bedrock.usage; that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAiPromptActionProcessor.js","sourceRoot":"","sources":["../../../../../src/getActionProcessor/core/ai/getAiPromptActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,iBAAiB,EAEjB,WAAW,EACX,qBAAqB,EACrB,aAAa,GAGd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"getAiPromptActionProcessor.js","sourceRoot":"","sources":["../../../../../src/getActionProcessor/core/ai/getAiPromptActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,iBAAiB,EAEjB,WAAW,EACX,qBAAqB,EACrB,aAAa,GAGd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAElC,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAErJ,MAAM,kBAAkB,GAAG,CAAC,SAAoB,EAAoC,EAAE;IACpF,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,aAAa,EAAE,mBAAmB,EAAE,cAAc,EAAE,EAAE;QACjH,MAAM,QAAQ,GAAG,mBAAmB,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,EAAE,cAAc,CAAC,CAAC;QACpI,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;YACxB,OAAO,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ;gBACvC,CAAC,CAAC;oBACE,QAAQ,EAAE,mBAAmB,CAC3B,MAAM,aAAa,CACjB,OAAO,CAAC,QAAQ,EAChB,uBAAuB,CAAC,SAAS,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,EAAE,cAAc,CAAC,CAC9G,EACD,OAAO,CAAC,OAAO,CAChB;iBACF;gBACH,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YAE/B,kFAAkF;YAClF,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS;gBACvC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,SAAkB,EAAE,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,YAAY,IAAI,IAAI,EAAE,EAAE,EAAE;gBACtH,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;gBAChC,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,MAAM,EAAE,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC;gBAC1D,GAAG,gBAAgB;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,eAAe;gBACf,QAAQ,EAAE,qBAAqB,CAAC,OAAO,CAAC;gBACxC,eAAe,EAAE,OAAO,CAAC,eAAe;aACzC,CAAC,CAAC;YAEH,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,qFAAqF;gBACrF,uFAAuF;gBACvF,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;YACpF,CAAC;YAED,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,OAAO,iBAAiB,CAAC,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACtE,CAAC;YAED,OAAO,iBAAiB,CAAC,aAAa,CAAC,YAAY,EAAE,+CAA+C,CAAC,CAAC;QACxG,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,qBAAqB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC","sourcesContent":["import {\n actionResult,\n actionResultError,\n AiActionType,\n askAiPrompt,\n createActionProcessor,\n ErrorTypeEnum,\n ProcessorFor,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport { generateText } from 'ai';\n\nimport { buildAiStopConditions, createDriveFileResolver, prepareAiPromptCall, toCacheableMessages, toCacheableSystem, toSdkMessages } from './logic';\n\nconst getProcessAiPrompt = (qpqConfig: QPQConfig): ProcessorFor<typeof askAiPrompt> => {\n return async (payload, session, actionProcessorList, logger, updateSession, dynamicModuleLoader, streamRegistry) => {\n const prepared = prepareAiPromptCall(qpqConfig, payload, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry);\n if ('error' in prepared) {\n return actionResultError(prepared.error.type, prepared.error.message);\n }\n\n try {\n const promptOrMessages = payload.messages\n ? {\n messages: toCacheableMessages(\n await toSdkMessages(\n payload.messages,\n createDriveFileResolver(qpqConfig, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry),\n ),\n payload.caching,\n ),\n }\n : { prompt: payload.prompt };\n\n // Extended thinking: the model reasons before answering, within the token budget.\n const providerOptions = payload.reasoning\n ? { bedrock: { reasoningConfig: { type: 'enabled' as const, budgetTokens: payload.reasoning.budgetTokens ?? 4096 } } }\n : undefined;\n\n const result = await generateText({\n model: prepared.model,\n system: toCacheableSystem(payload.system, payload.caching),\n ...promptOrMessages,\n tools: prepared.tools,\n providerOptions,\n stopWhen: buildAiStopConditions(payload),\n maxOutputTokens: payload.maxOutputTokens,\n });\n\n if (payload.caching) {\n // The SDK's cross-provider usage breakdown, not providerMetadata.bedrock.usage; that\n // field never carries cacheReadInputTokens through on @ai-sdk/amazon-bedrock (5.0.11).\n console.log('AI prompt cache usage:', result.finalStep?.usage?.inputTokenDetails);\n }\n\n return actionResult({ text: result.text });\n } catch (error) {\n if (error instanceof Error) {\n return actionResultError(ErrorTypeEnum.GenericError, error.message);\n }\n\n return actionResultError(ErrorTypeEnum.GenericError, 'An error occurred during AI prompt execution.');\n }\n };\n};\n\nexport const getAiPromptActionProcessor = createActionProcessor(askAiPrompt, getProcessAiPrompt);\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { actionResult, actionResultError, askAiPromptStream, createActionProcessor, ErrorTypeEnum, } from 'quidproquo-core';
|
|
2
|
-
import {
|
|
2
|
+
import { streamText } from 'ai';
|
|
3
3
|
import { randomGuid } from '../../../awsLambdaUtils';
|
|
4
|
-
import { createDriveFileResolver, mapAiStreamPart, prepareAiPromptCall, toCacheableMessages, toCacheableSystem, toErrorMessage, toSdkMessages, } from './logic';
|
|
4
|
+
import { buildAiStopConditions, createDriveFileResolver, mapAiStreamPart, prepareAiPromptCall, toCacheableMessages, toCacheableSystem, toErrorMessage, toSdkMessages, } from './logic';
|
|
5
5
|
const getProcessAiPromptStream = (qpqConfig) => {
|
|
6
6
|
return async (payload, session, actionProcessorList, logger, updateSession, dynamicModuleLoader, streamRegistry) => {
|
|
7
7
|
const prepared = prepareAiPromptCall(qpqConfig, payload, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry);
|
|
@@ -24,9 +24,8 @@ const getProcessAiPromptStream = (qpqConfig) => {
|
|
|
24
24
|
...promptOrMessages,
|
|
25
25
|
tools: prepared.tools,
|
|
26
26
|
providerOptions,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
stopWhen: stepCountIs(20),
|
|
27
|
+
stopWhen: buildAiStopConditions(payload),
|
|
28
|
+
maxOutputTokens: payload.maxOutputTokens,
|
|
30
29
|
// streamText swallows errors by default to keep the server alive; surface them to
|
|
31
30
|
// CloudWatch. The same error also reaches the consumer as an Error stream part.
|
|
32
31
|
onError: ({ error }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAiPromptStreamActionProcessor.js","sourceRoot":"","sources":["../../../../../src/getActionProcessor/core/ai/getAiPromptStreamActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,iBAAiB,EAEjB,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,GAGd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"getAiPromptStreamActionProcessor.js","sourceRoot":"","sources":["../../../../../src/getActionProcessor/core/ai/getAiPromptStreamActionProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n actionResult,\n actionResultError,\n AiActionType,\n askAiPromptStream,\n createActionProcessor,\n ErrorTypeEnum,\n ProcessorFor,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport { streamText } from 'ai';\n\nimport { randomGuid } from '../../../awsLambdaUtils';\nimport {\n buildAiStopConditions,\n createDriveFileResolver,\n mapAiStreamPart,\n prepareAiPromptCall,\n toCacheableMessages,\n toCacheableSystem,\n toErrorMessage,\n toSdkMessages,\n} from './logic';\n\nconst getProcessAiPromptStream = (qpqConfig: QPQConfig): ProcessorFor<typeof askAiPromptStream> => {\n return async (payload, session, actionProcessorList, logger, updateSession, dynamicModuleLoader, streamRegistry) => {\n const prepared = prepareAiPromptCall(qpqConfig, payload, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry);\n if ('error' in prepared) {\n return actionResultError(prepared.error.type, prepared.error.message);\n }\n\n try {\n const promptOrMessages = payload.messages\n ? {\n messages: toCacheableMessages(\n await toSdkMessages(\n payload.messages,\n createDriveFileResolver(qpqConfig, session, actionProcessorList, logger, dynamicModuleLoader, streamRegistry),\n ),\n payload.caching,\n ),\n }\n : { prompt: payload.prompt };\n\n // Extended thinking: thinking progress streams out as Reasoning* parts.\n const providerOptions = payload.reasoning\n ? { bedrock: { reasoningConfig: { type: 'enabled' as const, budgetTokens: payload.reasoning.budgetTokens ?? 4096 } } }\n : undefined;\n\n const { fullStream, finalStep } = streamText({\n model: prepared.model,\n system: toCacheableSystem(payload.system, payload.caching),\n ...promptOrMessages,\n tools: prepared.tools,\n providerOptions,\n stopWhen: buildAiStopConditions(payload),\n maxOutputTokens: payload.maxOutputTokens,\n // streamText swallows errors by default to keep the server alive; surface them to\n // CloudWatch. The same error also reaches the consumer as an Error stream part.\n onError: ({ error }) => {\n console.error('AI prompt stream error:', error);\n },\n });\n\n const streamId = `ai-prompt-${Date.now()}-${randomGuid()}`;\n\n async function* aiStreamIterator(): AsyncIterableIterator<string> {\n for await (const part of fullStream) {\n yield JSON.stringify(mapAiStreamPart(part));\n }\n\n if (payload.caching) {\n try {\n // The SDK's cross-provider usage breakdown, not providerMetadata.bedrock.usage; that\n // field never carries cacheReadInputTokens through on @ai-sdk/amazon-bedrock (5.0.11).\n const step = await finalStep;\n console.log('AI prompt cache usage:', step.usage?.inputTokenDetails);\n } catch (error) {\n // finalStep rejects (AI_NoOutputGeneratedError) when the stream errored before\n // completing a step. The error part has already been streamed to the consumer;\n // throwing here would replace that real error with the unhelpful wrapper.\n console.warn('AI prompt cache usage unavailable:', toErrorMessage(error));\n }\n }\n }\n\n streamRegistry.register(streamId, aiStreamIterator());\n\n return actionResult({ id: streamId, encoding: 'json' as const });\n } catch (error) {\n if (error instanceof Error) {\n return actionResultError(ErrorTypeEnum.GenericError, error.message);\n }\n\n return actionResultError(ErrorTypeEnum.GenericError, 'An error occurred during AI prompt stream.');\n }\n };\n};\n\nexport const getAiPromptStreamActionProcessor = createActionProcessor(askAiPromptStream, getProcessAiPromptStream);\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StopCondition, ToolSet } from 'ai';
|
|
2
|
+
export type AiStopLimits = {
|
|
3
|
+
maxSteps?: number;
|
|
4
|
+
maxDurationMs?: number;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* The `stopWhen` set for a prompt. The SDK defaults to a single step, so this always
|
|
8
|
+
* returns a list, even an empty one: with no limits the loop runs until the model stops
|
|
9
|
+
* on its own (a client-side tool call still halts it). Conditions only run between
|
|
10
|
+
* steps, so the time cap can overrun by one step; callers leave headroom. Its clock
|
|
11
|
+
* starts when this is built, which is just before the SDK call.
|
|
12
|
+
*/
|
|
13
|
+
export declare const buildAiStopConditions: ({ maxSteps, maxDurationMs }: AiStopLimits, now?: () => number) => StopCondition<ToolSet>[];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { stepCountIs } from 'ai';
|
|
2
|
+
/**
|
|
3
|
+
* The `stopWhen` set for a prompt. The SDK defaults to a single step, so this always
|
|
4
|
+
* returns a list, even an empty one: with no limits the loop runs until the model stops
|
|
5
|
+
* on its own (a client-side tool call still halts it). Conditions only run between
|
|
6
|
+
* steps, so the time cap can overrun by one step; callers leave headroom. Its clock
|
|
7
|
+
* starts when this is built, which is just before the SDK call.
|
|
8
|
+
*/
|
|
9
|
+
export const buildAiStopConditions = ({ maxSteps, maxDurationMs }, now = Date.now) => {
|
|
10
|
+
const conditions = [];
|
|
11
|
+
if (maxSteps !== undefined) {
|
|
12
|
+
conditions.push(stepCountIs(maxSteps));
|
|
13
|
+
}
|
|
14
|
+
if (maxDurationMs !== undefined) {
|
|
15
|
+
const startedAt = now();
|
|
16
|
+
conditions.push(() => now() - startedAt >= maxDurationMs);
|
|
17
|
+
}
|
|
18
|
+
return conditions;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=buildAiStopConditions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildAiStopConditions.js","sourceRoot":"","sources":["../../../../../../src/getActionProcessor/core/ai/logic/buildAiStopConditions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA0B,MAAM,IAAI,CAAC;AAOzD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAgB,EAAE,MAAoB,IAAI,CAAC,GAAG,EAA4B,EAAE;IACzI,MAAM,UAAU,GAA6B,EAAE,CAAC;IAEhD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;QACxB,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,aAAa,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { stepCountIs, StopCondition, ToolSet } from 'ai';\n\nexport type AiStopLimits = {\n maxSteps?: number;\n maxDurationMs?: number;\n};\n\n/**\n * The `stopWhen` set for a prompt. The SDK defaults to a single step, so this always\n * returns a list, even an empty one: with no limits the loop runs until the model stops\n * on its own (a client-side tool call still halts it). Conditions only run between\n * steps, so the time cap can overrun by one step; callers leave headroom. Its clock\n * starts when this is built, which is just before the SDK call.\n */\nexport const buildAiStopConditions = ({ maxSteps, maxDurationMs }: AiStopLimits, now: () => number = Date.now): StopCondition<ToolSet>[] => {\n const conditions: StopCondition<ToolSet>[] = [];\n\n if (maxSteps !== undefined) {\n conditions.push(stepCountIs(maxSteps));\n }\n\n if (maxDurationMs !== undefined) {\n const startedAt = now();\n conditions.push(() => now() - startedAt >= maxDurationMs);\n }\n\n return conditions;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/getActionProcessor/core/ai/logic/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC","sourcesContent":["export * from './aiStreamPartMappers';\nexport * from './createDriveFileResolver';\nexport * from './mapAiStreamAbort';\nexport * from './mapAiStreamCustom';\nexport * from './mapAiStreamError';\nexport * from './mapAiStreamFilePart';\nexport * from './mapAiStreamFinish';\nexport * from './mapAiStreamFinishStep';\nexport * from './mapAiStreamPart';\nexport * from './mapAiStreamRaw';\nexport * from './mapAiStreamReasoningDelta';\nexport * from './mapAiStreamReasoningEnd';\nexport * from './mapAiStreamReasoningFilePart';\nexport * from './mapAiStreamReasoningStart';\nexport * from './mapAiStreamSourcePart';\nexport * from './mapAiStreamStart';\nexport * from './mapAiStreamStartStep';\nexport * from './mapAiStreamTextDelta';\nexport * from './mapAiStreamTextEnd';\nexport * from './mapAiStreamTextStart';\nexport * from './mapAiStreamToolApprovalRequest';\nexport * from './mapAiStreamToolApprovalResponse';\nexport * from './mapAiStreamToolCall';\nexport * from './mapAiStreamToolError';\nexport * from './mapAiStreamToolInputDelta';\nexport * from './mapAiStreamToolInputEnd';\nexport * from './mapAiStreamToolInputStart';\nexport * from './mapAiStreamToolOutputDenied';\nexport * from './mapAiStreamToolResult';\nexport * from './prepareAiPromptCall';\nexport * from './toAiStreamFinishReason';\nexport * from './toAiStreamUsage';\nexport * from './toCacheableMessages';\nexport * from './toCacheableSystem';\nexport * from './toErrorMessage';\nexport * from './toSdkMessages';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/getActionProcessor/core/ai/logic/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC","sourcesContent":["export * from './aiStreamPartMappers';\nexport * from './buildAiStopConditions';\nexport * from './createDriveFileResolver';\nexport * from './mapAiStreamAbort';\nexport * from './mapAiStreamCustom';\nexport * from './mapAiStreamError';\nexport * from './mapAiStreamFilePart';\nexport * from './mapAiStreamFinish';\nexport * from './mapAiStreamFinishStep';\nexport * from './mapAiStreamPart';\nexport * from './mapAiStreamRaw';\nexport * from './mapAiStreamReasoningDelta';\nexport * from './mapAiStreamReasoningEnd';\nexport * from './mapAiStreamReasoningFilePart';\nexport * from './mapAiStreamReasoningStart';\nexport * from './mapAiStreamSourcePart';\nexport * from './mapAiStreamStart';\nexport * from './mapAiStreamStartStep';\nexport * from './mapAiStreamTextDelta';\nexport * from './mapAiStreamTextEnd';\nexport * from './mapAiStreamTextStart';\nexport * from './mapAiStreamToolApprovalRequest';\nexport * from './mapAiStreamToolApprovalResponse';\nexport * from './mapAiStreamToolCall';\nexport * from './mapAiStreamToolError';\nexport * from './mapAiStreamToolInputDelta';\nexport * from './mapAiStreamToolInputEnd';\nexport * from './mapAiStreamToolInputStart';\nexport * from './mapAiStreamToolOutputDenied';\nexport * from './mapAiStreamToolResult';\nexport * from './prepareAiPromptCall';\nexport * from './toAiStreamFinishReason';\nexport * from './toAiStreamUsage';\nexport * from './toCacheableMessages';\nexport * from './toCacheableSystem';\nexport * from './toErrorMessage';\nexport * from './toSdkMessages';\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActionProcessorList } from 'quidproquo-core';
|
|
2
|
+
import { Context } from 'aws-lambda';
|
|
3
|
+
/**
|
|
4
|
+
* Overrides the js "unlimited" GetRuntimeRemainingTime processor with the real lambda
|
|
5
|
+
* deadline. The context is per invocation, so this is built inside the handler and
|
|
6
|
+
* spread over the shared processor list on every invoke.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getLambdaRuntimeRemainingTimeActionProcessor: (context: Context) => ActionProcessorList;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { actionResult, SystemActionType } from 'quidproquo-core';
|
|
2
|
+
/**
|
|
3
|
+
* Overrides the js "unlimited" GetRuntimeRemainingTime processor with the real lambda
|
|
4
|
+
* deadline. The context is per invocation, so this is built inside the handler and
|
|
5
|
+
* spread over the shared processor list on every invoke.
|
|
6
|
+
*/
|
|
7
|
+
export const getLambdaRuntimeRemainingTimeActionProcessor = (context) => {
|
|
8
|
+
const processGetRuntimeRemainingTime = async () => actionResult(context.getRemainingTimeInMillis());
|
|
9
|
+
return {
|
|
10
|
+
[SystemActionType.GetRuntimeRemainingTime]: processGetRuntimeRemainingTime,
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=getLambdaRuntimeRemainingTimeActionProcessor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getLambdaRuntimeRemainingTimeActionProcessor.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/getLambdaRuntimeRemainingTimeActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,YAAY,EAA4C,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIhI;;;;GAIG;AACH,MAAM,CAAC,MAAM,4CAA4C,GAAG,CAAC,OAAgB,EAAuB,EAAE;IACpG,MAAM,8BAA8B,GAAoD,KAAK,IAAI,EAAE,CACjG,YAAY,CAAC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAEnD,OAAO;QACL,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,EAAE,8BAA8B;KAC3E,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { ActionProcessorList, actionResult, askGetRuntimeRemainingTime, ProcessorFor, SystemActionType } from 'quidproquo-core';\n\nimport { Context } from 'aws-lambda';\n\n/**\n * Overrides the js \"unlimited\" GetRuntimeRemainingTime processor with the real lambda\n * deadline. The context is per invocation, so this is built inside the handler and\n * spread over the shared processor list on every invoke.\n */\nexport const getLambdaRuntimeRemainingTimeActionProcessor = (context: Context): ActionProcessorList => {\n const processGetRuntimeRemainingTime: ProcessorFor<typeof askGetRuntimeRemainingTime> = async () =>\n actionResult(context.getRemainingTimeInMillis());\n\n return {\n [SystemActionType.GetRuntimeRemainingTime]: processGetRuntimeRemainingTime,\n };\n};\n"]}
|
|
@@ -2,6 +2,7 @@ import { getCustomActionActionProcessor } from 'quidproquo-actionprocessor-js';
|
|
|
2
2
|
import { askProcessEvent, createRuntime, } from 'quidproquo-core';
|
|
3
3
|
import { getAwsActionProcessors } from '../../getActionProcessor';
|
|
4
4
|
import { dynamicModuleLoaderWarmer } from './dynamicModuleLoaderWarmer';
|
|
5
|
+
import { getLambdaRuntimeRemainingTimeActionProcessor } from './getLambdaRuntimeRemainingTimeActionProcessor';
|
|
5
6
|
import { getLogger } from './getLogger';
|
|
6
7
|
import { getRuntimeCorrelation } from './getRuntimeCorrelation';
|
|
7
8
|
import { isSnsWarmerRecord } from './isSnsWarmerRecord';
|
|
@@ -20,16 +21,19 @@ const isSnsEvent = (event) => {
|
|
|
20
21
|
* short-circuits SNS warmer pings, runs the process-event story and ships logs.
|
|
21
22
|
*/
|
|
22
23
|
export const getQpqLambdaRuntimeForEvent = (runtimeType, getStorySession, getActionProcessorList, dynamicModuleLoader, qpqConfig, getProcessEventStory = () => askProcessEvent) => {
|
|
23
|
-
|
|
24
|
+
// Built per invoke: the lambda context (and so the execution deadline) is not
|
|
25
|
+
// known until the handler runs.
|
|
26
|
+
const getResolveActionProcessorList = (context) => async () => ({
|
|
24
27
|
...(await getAwsActionProcessors(qpqConfig, dynamicModuleLoader)),
|
|
25
28
|
...(await getActionProcessorList(qpqConfig, dynamicModuleLoader)),
|
|
29
|
+
...getLambdaRuntimeRemainingTimeActionProcessor(context),
|
|
26
30
|
// Always done last, so they can override the default ones if the user wants.
|
|
27
31
|
...(await getCustomActionActionProcessor(qpqConfig, dynamicModuleLoader)),
|
|
28
32
|
});
|
|
29
33
|
return async (event, context) => {
|
|
30
34
|
console.log('tick: ', JSON.stringify(event, null, 2));
|
|
31
35
|
const logger = getLogger(qpqConfig);
|
|
32
|
-
const resolveStory = createRuntime(qpqConfig, getStorySession(event),
|
|
36
|
+
const resolveStory = createRuntime(qpqConfig, getStorySession(event), getResolveActionProcessorList(context), () => new Date().toISOString(), logger, getRuntimeCorrelation(qpqConfig), runtimeType, dynamicModuleLoader);
|
|
33
37
|
const processEvent = async () => {
|
|
34
38
|
const result = await resolveStory(getProcessEventStory(), [event, context]);
|
|
35
39
|
await logger.waitToFinishWriting();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getQpqLambdaRuntimeForEvent.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/getQpqLambdaRuntimeForEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAGL,eAAe,EACf,aAAa,GAKd,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,gFAAgF;AAChF,gFAAgF;AAChF,iFAAiF;AACjF,MAAM,UAAU,GAAG,CAAI,KAAmC,EAAqB,EAAE;IAC/E,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,gBAAgB,GAAG,KAA4B,CAAC;QACtD,OAAO,gBAAgB,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CACzC,WAA2B,EAC3B,eAA2C,EAC3C,sBAAmD,EACnD,mBAAwC,EACxC,SAAoB,EACpB,uBAAqD,GAAG,EAAE,CAAC,eAAe,EAC1E,EAAE;IACF,MAAM,
|
|
1
|
+
{"version":3,"file":"getQpqLambdaRuntimeForEvent.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/getQpqLambdaRuntimeForEvent.ts"],"names":[],"mappings":"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","sourcesContent":["import { getCustomActionActionProcessor } from 'quidproquo-actionprocessor-js';\nimport {\n ActionProcessorList,\n ActionProcessorListResolver,\n askProcessEvent,\n createRuntime,\n DynamicModuleLoader,\n QPQConfig,\n QpqRuntimeType,\n StorySession,\n} from 'quidproquo-core';\n\nimport { Context, SNSEvent } from 'aws-lambda';\n\nimport { getAwsActionProcessors } from '../../getActionProcessor';\nimport { QpqFunctionExecutionEvent } from '../types';\nimport { dynamicModuleLoaderWarmer } from './dynamicModuleLoaderWarmer';\nimport { getLambdaRuntimeRemainingTimeActionProcessor } from './getLambdaRuntimeRemainingTimeActionProcessor';\nimport { getLogger } from './getLogger';\nimport { getRuntimeCorrelation } from './getRuntimeCorrelation';\nimport { isSnsWarmerRecord } from './isSnsWarmerRecord';\n\n// SQS/S3/CloudFront events also have a Records array, so this matches more than\n// real SNS events. That is harmless: the warmer scan below only acts on records\n// whose EventSource is 'aws:sns', everything else falls through to processEvent.\nconst isSnsEvent = <T>(event: QpqFunctionExecutionEvent<T>): event is SNSEvent => {\n if (event && typeof event === 'object') {\n const possibleSnsEvent = event as unknown as SNSEvent;\n return possibleSnsEvent.Records && Array.isArray(possibleSnsEvent.Records);\n }\n\n return false;\n};\n\n/**\n * Builds the shared lambda handler: wires a qpq runtime for the event type,\n * short-circuits SNS warmer pings, runs the process-event story and ships logs.\n */\nexport const getQpqLambdaRuntimeForEvent = <E extends QpqFunctionExecutionEvent<any>>(\n runtimeType: QpqRuntimeType,\n getStorySession: (event: E) => StorySession,\n getActionProcessorList: ActionProcessorListResolver,\n dynamicModuleLoader: DynamicModuleLoader,\n qpqConfig: QPQConfig,\n getProcessEventStory: () => typeof askProcessEvent = () => askProcessEvent,\n) => {\n // Built per invoke: the lambda context (and so the execution deadline) is not\n // known until the handler runs.\n const getResolveActionProcessorList = (context: Context) => async (): Promise<ActionProcessorList> => ({\n ...(await getAwsActionProcessors(qpqConfig, dynamicModuleLoader)),\n ...(await getActionProcessorList(qpqConfig, dynamicModuleLoader)),\n ...getLambdaRuntimeRemainingTimeActionProcessor(context),\n\n // Always done last, so they can override the default ones if the user wants.\n ...(await getCustomActionActionProcessor(qpqConfig, dynamicModuleLoader)),\n });\n\n return async (event: E, context: Context) => {\n console.log('tick: ', JSON.stringify(event, null, 2));\n\n const logger = getLogger(qpqConfig);\n\n const resolveStory = createRuntime(\n qpqConfig,\n getStorySession(event),\n getResolveActionProcessorList(context),\n () => new Date().toISOString(),\n logger,\n getRuntimeCorrelation(qpqConfig),\n runtimeType,\n dynamicModuleLoader,\n );\n\n const processEvent = async () => {\n const result = await resolveStory(getProcessEventStory(), [event, context]);\n await logger.waitToFinishWriting();\n\n if (result.error) {\n throw new Error(result.error.errorText);\n }\n\n console.log('Finished, returning: ', result.result);\n return result.result;\n };\n\n if (isSnsEvent(event)) {\n const recordsNoWarm = event.Records.filter((record) => !isSnsWarmerRecord(record));\n\n // A warmer ping arrives as its own single-record SNS event; any warmer\n // present means this invoke exists only to keep the sandbox warm.\n if (recordsNoWarm.length !== event.Records.length) {\n console.log('Found SNS warmer');\n\n // TODO: Warm qpq things with dynamic functions\n // federate in dynamic modules\n await dynamicModuleLoaderWarmer();\n\n // Might as well move the logs to permanent storage\n await logger.moveToPermanentStorage();\n\n return 'Warmed up!';\n }\n }\n\n return await processEvent();\n };\n};\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './dynamicModuleLoaderWarmer';
|
|
2
2
|
export * from './getBlankStorySession';
|
|
3
|
+
export * from './getLambdaRuntimeRemainingTimeActionProcessor';
|
|
3
4
|
export * from './getLogger';
|
|
4
5
|
export * from './getQpqLambdaRuntimeForEvent';
|
|
5
6
|
export * from './getRuntimeCorrelation';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './dynamicModuleLoaderWarmer';
|
|
2
2
|
export * from './getBlankStorySession';
|
|
3
|
+
export * from './getLambdaRuntimeRemainingTimeActionProcessor';
|
|
3
4
|
export * from './getLogger';
|
|
4
5
|
export * from './getQpqLambdaRuntimeForEvent';
|
|
5
6
|
export * from './getRuntimeCorrelation';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './dynamicModuleLoaderWarmer';\nexport * from './getBlankStorySession';\nexport * from './getLogger';\nexport * from './getQpqLambdaRuntimeForEvent';\nexport * from './getRuntimeCorrelation';\nexport * from './isSnsWarmerRecord';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lambdaHandlers/helpers/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,gDAAgD,CAAC;AAC/D,cAAc,aAAa,CAAC;AAC5B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './dynamicModuleLoaderWarmer';\nexport * from './getBlankStorySession';\nexport * from './getLambdaRuntimeRemainingTimeActionProcessor';\nexport * from './getLogger';\nexport * from './getQpqLambdaRuntimeForEvent';\nexport * from './getRuntimeCorrelation';\nexport * from './isSnsWarmerRecord';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quidproquo-actionprocessor-awslambda",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/esm/index.js",
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
"lodash": "^4.17.21",
|
|
67
67
|
"node-cache": "^5.1.2",
|
|
68
68
|
"node-match-path": "^0.6.3",
|
|
69
|
-
"quidproquo-actionprocessor-js": "0.1.
|
|
70
|
-
"quidproquo-actionprocessor-node": "0.1.
|
|
71
|
-
"quidproquo-config-aws": "0.1.
|
|
72
|
-
"quidproquo-core": "0.1.
|
|
73
|
-
"quidproquo-webserver": "0.1.
|
|
69
|
+
"quidproquo-actionprocessor-js": "0.1.25",
|
|
70
|
+
"quidproquo-actionprocessor-node": "0.1.25",
|
|
71
|
+
"quidproquo-config-aws": "0.1.25",
|
|
72
|
+
"quidproquo-core": "0.1.25",
|
|
73
|
+
"quidproquo-webserver": "0.1.25"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@types/busboy": "^1.5.0",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"@types/lodash": "^4.14.194",
|
|
79
79
|
"@types/node": "^22.13.13",
|
|
80
80
|
"esbuild": "^0.25.8",
|
|
81
|
-
"quidproquo-tsconfig": "0.1.
|
|
81
|
+
"quidproquo-tsconfig": "0.1.25",
|
|
82
82
|
"typescript": "^5.8.2"
|
|
83
83
|
}
|
|
84
84
|
}
|