@outputai/llm 0.11.0 → 0.11.1-next.2223fa5.0
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/package.json +2 -2
- package/src/agent.js +105 -83
- package/src/agent.spec.js +312 -225
- package/src/ai_provider.js +2 -2
- package/src/ai_sdk_options.js +93 -39
- package/src/ai_sdk_options.spec.js +314 -154
- package/src/consts.js +6 -0
- package/src/generate.js +81 -0
- package/src/generate.spec.js +466 -0
- package/src/index.d.ts +222 -242
- package/src/index.js +3 -4
- package/src/prompt/content.js +70 -0
- package/src/prompt/content.spec.js +208 -0
- package/src/prompt/{escape.js → interpolations.js} +11 -18
- package/src/prompt/interpolations.spec.js +109 -0
- package/src/prompt/loader.full.spec.js +293 -0
- package/src/prompt/loader.js +45 -39
- package/src/prompt/loader.spec.js +186 -289
- package/src/prompt/markup/attributes.js +52 -0
- package/src/prompt/markup/attributes.spec.js +132 -0
- package/src/prompt/markup/nodes.js +71 -0
- package/src/prompt/markup/nodes.spec.js +333 -0
- package/src/prompt/markup/tokenizer.js +3 -0
- package/src/prompt/markup/tokenizer.spec.js +149 -0
- package/src/prompt/markup/tokens.js +26 -0
- package/src/prompt/markup/tokens.spec.js +250 -0
- package/src/prompt/validations.js +98 -67
- package/src/prompt/validations.spec.js +204 -47
- package/src/{prompt/load_content.js → utils/file.js} +12 -15
- package/src/utils/file.spec.js +89 -0
- package/src/utils/models.js +15 -0
- package/src/utils/models.spec.js +119 -0
- package/src/utils/skills.js +74 -0
- package/src/utils/skills.spec.js +168 -0
- package/src/utils/sources.js +48 -0
- package/src/utils/sources.spec.js +122 -0
- package/src/utils/stream.js +22 -0
- package/src/utils/stream.spec.js +55 -0
- package/src/utils/tools.js +47 -0
- package/src/utils/tools.spec.js +167 -0
- package/src/utils/wrap.js +148 -0
- package/src/utils/wrap.spec.js +359 -0
- package/src/validations.js +149 -27
- package/src/validations.spec.js +451 -53
- package/src/ai_model.js +0 -60
- package/src/ai_model.spec.js +0 -259
- package/src/ai_sdk.js +0 -92
- package/src/ai_sdk.spec.js +0 -564
- package/src/prompt/block_options.js +0 -58
- package/src/prompt/block_options.spec.js +0 -71
- package/src/prompt/blocks.js +0 -47
- package/src/prompt/blocks.spec.js +0 -63
- package/src/prompt/escape.spec.js +0 -159
- package/src/prompt/load_content.spec.js +0 -83
- package/src/prompt/loader_validation.spec.js +0 -128
- package/src/prompt/parser.js +0 -16
- package/src/prompt/parser.spec.js +0 -186
- package/src/prompt/prepare_text.js +0 -27
- package/src/prompt/prepare_text.spec.js +0 -141
- package/src/prompt/skill.js +0 -128
- package/src/prompt/skill.spec.js +0 -172
- package/src/utils/message.js +0 -3
- package/src/utils/message.spec.js +0 -29
- package/src/utils/response_wrappers.js +0 -100
- package/src/utils/response_wrappers.spec.js +0 -240
- package/src/utils/source_extraction.js +0 -53
- package/src/utils/source_extraction.spec.js +0 -194
- package/src/utils/trace.js +0 -19
- package/src/utils/trace.spec.js +0 -112
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outputai/llm",
|
|
3
|
-
"version": "0.11.0",
|
|
3
|
+
"version": "0.11.1-next.2223fa5.0",
|
|
4
4
|
"description": "Framework abstraction to interact with LLM models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"gray-matter": "4.0.3",
|
|
17
17
|
"liquidjs": "10.27.2",
|
|
18
18
|
"undici": "8.9.0",
|
|
19
|
-
"@outputai/core": "0.11.0"
|
|
19
|
+
"@outputai/core": "0.11.1-next.2223fa5.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@ai-sdk/amazon-bedrock": "4.0.138",
|
package/src/agent.js
CHANGED
|
@@ -1,112 +1,134 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Path } from '@outputai/core/sdk/helpers';
|
|
3
|
-
import { ToolLoopAgent as AIToolLoopAgent, stepCountIs } from 'ai';
|
|
1
|
+
import { ToolLoopAgent as AIToolLoopAgent } from 'ai';
|
|
4
2
|
import { loadAiSdkTextOptions } from './ai_sdk_options.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const messages = [];
|
|
13
|
-
return {
|
|
14
|
-
getMessages: () => messages,
|
|
15
|
-
addMessages: newMessages => messages.push( ...newMessages )
|
|
16
|
-
};
|
|
17
|
-
};
|
|
3
|
+
import { wrapGeneration, wrapStream } from './utils/wrap.js';
|
|
4
|
+
import { Role } from './consts.js';
|
|
5
|
+
import { drainStream } from './utils/stream.js';
|
|
6
|
+
import { loadPrompt } from './prompt/loader.js';
|
|
7
|
+
import { loadSkills } from './utils/skills.js';
|
|
8
|
+
import * as Validator from './validations.js';
|
|
9
|
+
import { Logger } from '@outputai/core';
|
|
18
10
|
|
|
19
11
|
export class Agent extends AIToolLoopAgent {
|
|
20
12
|
#prompt;
|
|
21
|
-
#modelId;
|
|
22
|
-
#providerId;
|
|
23
13
|
#initialMessages;
|
|
24
14
|
#store;
|
|
25
15
|
|
|
26
|
-
constructor( {
|
|
27
|
-
|
|
28
|
-
promptDir,
|
|
29
|
-
variables = {},
|
|
30
|
-
skills = [],
|
|
31
|
-
tools: toolsArg,
|
|
32
|
-
stopWhen,
|
|
33
|
-
maxSteps = 10,
|
|
34
|
-
conversationStore,
|
|
35
|
-
...rest
|
|
36
|
-
} ) {
|
|
37
|
-
if ( !prompt ) {
|
|
38
|
-
throw new ValidationError( 'Agent requires a prompt' );
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Must be captured synchronously — Temporal async activity execution
|
|
42
|
-
// breaks the call stack, so Path.resolveInvocationDir() fails if called lazily.
|
|
43
|
-
const resolvedPromptDir = promptDir ?? Path.resolveInvocationDir();
|
|
16
|
+
constructor( args ) {
|
|
17
|
+
const { promptFile, promptDir, variables, tools, output, stopWhen, messageStore } = Validator.parseAgentArgs( args );
|
|
44
18
|
|
|
45
|
-
const
|
|
19
|
+
const prompt = loadPrompt( promptFile, variables, promptDir );
|
|
20
|
+
const skills = loadSkills( prompt );
|
|
46
21
|
|
|
47
|
-
const { system, messages, ...
|
|
22
|
+
const { system, messages, ...aiOptions } = loadAiSdkTextOptions( { prompt, skills, tools, output, stopWhen } );
|
|
48
23
|
|
|
49
24
|
// loadAiSdkTextOptions routes system blocks to the `system` slot (preserving
|
|
50
25
|
// per-message providerOptions); pass them as the agent's `instructions`.
|
|
51
26
|
super( {
|
|
52
|
-
...
|
|
53
|
-
...( system.length > 0 ? { instructions: system } : {} )
|
|
54
|
-
...( tools ? { tools } : {} ),
|
|
55
|
-
stopWhen: stopWhen ?? stepCountIs( maxSteps ),
|
|
56
|
-
...rest
|
|
27
|
+
...aiOptions,
|
|
28
|
+
...( system.length > 0 ? { instructions: system } : {} )
|
|
57
29
|
} );
|
|
58
30
|
|
|
59
31
|
this.#prompt = prompt;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
this.#initialMessages = messages.filter( isRole( ROLE.USER ) );
|
|
65
|
-
this.#store = conversationStore ?? null;
|
|
32
|
+
// `messages` is system-free but may still hold authored <assistant> blocks;
|
|
33
|
+
// seed only <user> turns into each generate()/stream() call.
|
|
34
|
+
this.#initialMessages = messages.filter( m => m.role === Role.USER );
|
|
35
|
+
this.#store = messageStore ?? null;
|
|
66
36
|
}
|
|
67
37
|
|
|
68
|
-
async #
|
|
69
|
-
|
|
70
|
-
return [ ...this.#initialMessages, ...priorMessages, ...userMessages ];
|
|
38
|
+
async #combineWithPreviousMessages( messages ) {
|
|
39
|
+
return [ ...this.#initialMessages, ...( await this.#store?.getMessages() ?? [] ), ...messages ];
|
|
71
40
|
}
|
|
72
41
|
|
|
73
|
-
async #storeMessages(
|
|
42
|
+
async #storeMessages( messages ) {
|
|
74
43
|
if ( this.#store ) {
|
|
75
|
-
await this.#store.addMessages(
|
|
44
|
+
await this.#store.addMessages( messages );
|
|
76
45
|
}
|
|
77
46
|
}
|
|
78
47
|
|
|
79
|
-
async generate(
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
48
|
+
async generate( args ) {
|
|
49
|
+
const { messages, abortSignal, toolChoice } = Validator.parseAgentGenerateArgs( args );
|
|
50
|
+
const combinedMessages = await this.#combineWithPreviousMessages( messages );
|
|
51
|
+
|
|
52
|
+
return wrapGeneration( {
|
|
53
|
+
name: 'Agent.generate',
|
|
54
|
+
prompt: this.#prompt,
|
|
55
|
+
fn: async () => {
|
|
56
|
+
const response = await super.generate( {
|
|
57
|
+
messages: combinedMessages,
|
|
58
|
+
allowSystemInMessages: true,
|
|
59
|
+
...( abortSignal && { abortSignal } ),
|
|
60
|
+
...( toolChoice && { toolChoice } )
|
|
61
|
+
} );
|
|
62
|
+
await this.#storeMessages( messages.concat( response.response?.messages ?? [] ) );
|
|
63
|
+
return response;
|
|
64
|
+
}
|
|
65
|
+
} );
|
|
91
66
|
}
|
|
92
67
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Generates a completed agent response over streaming transport, invoking `onChunk` as parts arrive.
|
|
70
|
+
*/
|
|
71
|
+
async generateWithStreaming( args ) {
|
|
72
|
+
const { messages, abortSignal, toolChoice, onChunk } = Validator.parseAgentGenerateWithStreamingArgs( args );
|
|
73
|
+
const combinedMessages = await this.#combineWithPreviousMessages( messages );
|
|
74
|
+
|
|
75
|
+
return wrapGeneration( {
|
|
76
|
+
name: 'Agent.generateWithStreaming',
|
|
77
|
+
prompt: this.#prompt,
|
|
78
|
+
fn: async () => {
|
|
79
|
+
const state = { response: null };
|
|
80
|
+
const stream = await super.stream( {
|
|
81
|
+
messages: combinedMessages,
|
|
82
|
+
allowSystemInMessages: true,
|
|
83
|
+
...( onChunk && { onChunk } ),
|
|
84
|
+
...( abortSignal && { abortSignal } ),
|
|
85
|
+
...( toolChoice && { toolChoice } ),
|
|
86
|
+
onFinish: res => {
|
|
87
|
+
state.response = res;
|
|
88
|
+
},
|
|
89
|
+
onError: _ => {} // Suppress AI-SDK console printing
|
|
90
|
+
} );
|
|
91
|
+
|
|
92
|
+
await drainStream( stream, abortSignal );
|
|
93
|
+
|
|
94
|
+
if ( !state.response ) {
|
|
95
|
+
throw new Error( 'Agent streaming generation completed without a response.' );
|
|
105
96
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
97
|
+
|
|
98
|
+
state.response.output = await stream.output;
|
|
99
|
+
await this.#storeMessages( messages.concat( state.response.response?.messages ?? [] ) );
|
|
100
|
+
|
|
101
|
+
return state.response;
|
|
102
|
+
}
|
|
103
|
+
} );
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async stream( args ) {
|
|
107
|
+
const { messages, abortSignal, toolChoice, onChunk, onFinish, onError } = Validator.parseAgentStreamArgs( args );
|
|
108
|
+
const combinedMessages = await this.#combineWithPreviousMessages( messages );
|
|
109
|
+
|
|
110
|
+
return wrapStream( {
|
|
111
|
+
name: 'Agent.stream',
|
|
112
|
+
prompt: this.#prompt,
|
|
113
|
+
fn: ( { onFinishHook, onErrorHook } ) => super.stream( {
|
|
114
|
+
messages: combinedMessages,
|
|
115
|
+
allowSystemInMessages: true,
|
|
116
|
+
...( onChunk && { onChunk } ),
|
|
117
|
+
...( abortSignal && { abortSignal } ),
|
|
118
|
+
...( toolChoice && { toolChoice } ),
|
|
119
|
+
onFinish: response =>
|
|
120
|
+
onFinishHook( response, async parsedResponse => {
|
|
121
|
+
if ( response.finishReason !== 'error' ) {
|
|
122
|
+
await this.#storeMessages( messages.concat( response.response?.messages ?? [] ) )
|
|
123
|
+
.catch( error => Logger.error( 'Agent.stream message store persistence failed', {
|
|
124
|
+
namespace: 'LLM',
|
|
125
|
+
error: error instanceof Error ? error.message : String( error )
|
|
126
|
+
} ) );
|
|
127
|
+
}
|
|
128
|
+
await onFinish?.( parsedResponse );
|
|
129
|
+
} ),
|
|
130
|
+
onError: event => onErrorHook( event, error => onError?.( { ...event, error } ) )
|
|
131
|
+
} )
|
|
132
|
+
} );
|
|
111
133
|
}
|
|
112
134
|
}
|