services-as-software 0.1.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/README.md ADDED
@@ -0,0 +1,303 @@
1
+ # services-as-software
2
+
3
+ Define services with objectives, key results, and various pricing models for the agentic services architecture.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install services-as-software
9
+ # or
10
+ yarn add services-as-software
11
+ # or
12
+ pnpm add services-as-software
13
+ ```
14
+
15
+ ## Overview
16
+
17
+ The `services-as-software` package enables defining services with clear objectives, measurable key results, and support for multiple pricing models. It allows Functions, Workflows, and Agents to be offered as Services with appropriate pricing and business models.
18
+
19
+ ## Usage
20
+
21
+ ### Basic Service Definition
22
+
23
+ ```typescript
24
+ import { Service } from 'services-as-software'
25
+
26
+ const myService = Service({
27
+ name: 'Content Generation Service',
28
+ description: 'AI-powered content generation for marketing teams',
29
+ objective: {
30
+ description: 'Provide high-quality content generation that increases marketing efficiency',
31
+ keyResults: [],
32
+ },
33
+ keyResults: [
34
+ {
35
+ description: 'Reduce content creation time',
36
+ target: 50,
37
+ currentValue: 0,
38
+ unit: 'percent',
39
+ },
40
+ {
41
+ description: 'Maintain content quality score',
42
+ target: 8,
43
+ currentValue: 0,
44
+ unit: 'rating',
45
+ },
46
+ ],
47
+ pricing: {
48
+ model: 'cost-based',
49
+ costBase: 10,
50
+ fixedCosts: 5,
51
+ variableCosts: 2,
52
+ },
53
+ implementation: {
54
+ type: 'function',
55
+ id: 'content-generator-123',
56
+ },
57
+ })
58
+
59
+ // Register the service
60
+ const registeredService = await myService.register()
61
+
62
+ // Calculate price
63
+ const price = myService.calculatePrice({ quantity: 5 })
64
+
65
+ // Track progress towards key results
66
+ myService.trackProgress({
67
+ 'Reduce content creation time': 30,
68
+ 'Maintain content quality score': 9,
69
+ })
70
+
71
+ // Check if objective is achieved
72
+ const achieved = myService.isObjectiveAchieved()
73
+ ```
74
+
75
+ ### Pricing Models
76
+
77
+ The package supports four pricing models:
78
+
79
+ #### 1. Cost-based Pricing
80
+
81
+ ```typescript
82
+ const service = Service({
83
+ // ...other properties
84
+ pricing: {
85
+ model: 'cost-based',
86
+ costBase: 100,
87
+ fixedCosts: 50,
88
+ variableCosts: 10,
89
+ },
90
+ })
91
+
92
+ // Calculate price for 5 units
93
+ const price = service.calculatePrice({ quantity: 5 }) // 200 (100 + 50 + 10*5)
94
+ ```
95
+
96
+ #### 2. Margin-based Pricing
97
+
98
+ ```typescript
99
+ const service = Service({
100
+ // ...other properties
101
+ pricing: {
102
+ model: 'margin-based',
103
+ costBase: 100,
104
+ marginPercentage: 20,
105
+ },
106
+ })
107
+
108
+ // Calculate price for 2 units
109
+ const price = service.calculatePrice({ quantity: 2 }) // 240 (100*2 + 20% margin)
110
+ ```
111
+
112
+ #### 3. Activity-based Pricing
113
+
114
+ ```typescript
115
+ const service = Service({
116
+ // ...other properties
117
+ pricing: {
118
+ model: 'activity-based',
119
+ activities: [
120
+ { name: 'research', rate: 50 },
121
+ { name: 'writing', rate: 100 },
122
+ { name: 'editing', rate: 30 },
123
+ ],
124
+ },
125
+ })
126
+
127
+ // Calculate price based on activities performed
128
+ const price = service.calculatePrice({
129
+ activities: {
130
+ research: 2,
131
+ writing: 1,
132
+ editing: 3,
133
+ },
134
+ }) // 290 (50*2 + 100*1 + 30*3)
135
+ ```
136
+
137
+ #### 4. Outcome-based Pricing
138
+
139
+ ```typescript
140
+ const service = Service({
141
+ // ...other properties
142
+ pricing: {
143
+ model: 'outcome-based',
144
+ outcomes: [
145
+ { metric: 'conversion-rate', targetValue: 5, price: 500 },
146
+ { metric: 'engagement', targetValue: 10000, price: 300 },
147
+ ],
148
+ },
149
+ })
150
+
151
+ // Calculate price based on achieved outcomes
152
+ const price = service.calculatePrice({
153
+ outcomes: {
154
+ 'conversion-rate': 6.5,
155
+ engagement: 8000,
156
+ },
157
+ }) // 500 (only conversion-rate target was met)
158
+ ```
159
+
160
+ ### Offering Functions as Services
161
+
162
+ ```typescript
163
+ import { Service } from 'services-as-software'
164
+
165
+ const functionAsService = Service({
166
+ name: 'Text Summarization',
167
+ objective: {
168
+ description: 'Provide accurate text summarization',
169
+ keyResults: [],
170
+ },
171
+ keyResults: [
172
+ {
173
+ description: 'Summarization accuracy',
174
+ target: 90,
175
+ unit: 'percent',
176
+ },
177
+ ],
178
+ pricing: {
179
+ model: 'cost-based',
180
+ costBase: 5,
181
+ variableCosts: 0.01,
182
+ },
183
+ implementation: {
184
+ type: 'function',
185
+ id: 'text-summarizer-function',
186
+ },
187
+ })
188
+ ```
189
+
190
+ ### Offering Workflows as Services
191
+
192
+ ```typescript
193
+ import { Service } from 'services-as-software'
194
+
195
+ const workflowAsService = Service({
196
+ name: 'Content Production Pipeline',
197
+ objective: {
198
+ description: 'End-to-end content production',
199
+ keyResults: [],
200
+ },
201
+ keyResults: [
202
+ {
203
+ description: 'Average production time',
204
+ target: 24,
205
+ unit: 'hours',
206
+ },
207
+ ],
208
+ pricing: {
209
+ model: 'activity-based',
210
+ activities: [
211
+ { name: 'research', rate: 100 },
212
+ { name: 'writing', rate: 200 },
213
+ { name: 'editing', rate: 50 },
214
+ { name: 'publishing', rate: 30 },
215
+ ],
216
+ },
217
+ implementation: {
218
+ type: 'workflow',
219
+ id: 'content-production-workflow',
220
+ },
221
+ })
222
+ ```
223
+
224
+ ### Offering Agents as Services
225
+
226
+ ```typescript
227
+ import { Service } from 'services-as-software'
228
+
229
+ const agentAsService = Service({
230
+ name: 'Customer Support Agent',
231
+ objective: {
232
+ description: 'Provide excellent customer support',
233
+ keyResults: [],
234
+ },
235
+ keyResults: [
236
+ {
237
+ description: 'Customer satisfaction score',
238
+ target: 4.5,
239
+ unit: 'rating',
240
+ },
241
+ {
242
+ description: 'First response time',
243
+ target: 5,
244
+ unit: 'minutes',
245
+ },
246
+ ],
247
+ pricing: {
248
+ model: 'outcome-based',
249
+ outcomes: [
250
+ { metric: 'resolution-rate', targetValue: 95, price: 1000 },
251
+ { metric: 'satisfaction-score', targetValue: 4.8, price: 500 },
252
+ ],
253
+ },
254
+ implementation: {
255
+ type: 'agent',
256
+ id: 'customer-support-agent',
257
+ },
258
+ })
259
+ ```
260
+
261
+ ## API Reference
262
+
263
+ ### Service Function
264
+
265
+ ```typescript
266
+ function Service(definition: ServiceDefinition): ServiceObject
267
+ ```
268
+
269
+ Creates a service with the given definition.
270
+
271
+ ### ServiceDefinition
272
+
273
+ ```typescript
274
+ interface ServiceDefinition {
275
+ name: string
276
+ description?: string
277
+ objective: Objective
278
+ keyResults: KeyResult[]
279
+ pricing: ServicePricing
280
+ implementation: ImplementationDetails
281
+ metadata?: Record<string, any>
282
+ }
283
+ ```
284
+
285
+ ### Pricing Models
286
+
287
+ ```typescript
288
+ type PricingModel = 'cost-based' | 'margin-based' | 'activity-based' | 'outcome-based'
289
+
290
+ type ServicePricing = CostBasedPricing | MarginBasedPricing | ActivityBasedPricing | OutcomeBasedPricing
291
+ ```
292
+
293
+ ## Integration with Existing Services
294
+
295
+ The `services-as-software` package is designed to work with the existing services ecosystem:
296
+
297
+ - Integrates with the `services.do` SDK for service registration
298
+ - Extends the business model concepts from `Business-as-Code`
299
+ - Compatible with Functions, Workflows, and Agents collections
300
+
301
+ ## License
302
+
303
+ MIT
@@ -0,0 +1,216 @@
1
+ import { Objective as Objective$1, KeyResult as KeyResult$1 } from 'business-as-code';
2
+
3
+ /**
4
+ * Pricing model types for services
5
+ */
6
+ type PricingModel = 'cost-based' | 'margin-based' | 'activity-based' | 'outcome-based';
7
+ /**
8
+ * Cost-based pricing configuration
9
+ */
10
+ interface CostBasedPricing {
11
+ model: 'cost-based';
12
+ costBase: number;
13
+ fixedCosts?: number;
14
+ variableCosts?: number;
15
+ }
16
+ /**
17
+ * Margin-based pricing configuration
18
+ */
19
+ interface MarginBasedPricing {
20
+ model: 'margin-based';
21
+ costBase: number;
22
+ marginPercentage: number;
23
+ }
24
+ /**
25
+ * Activity-based pricing configuration
26
+ */
27
+ interface ActivityBasedPricing {
28
+ model: 'activity-based';
29
+ activities: {
30
+ name: string;
31
+ description?: string;
32
+ rate: number;
33
+ }[];
34
+ }
35
+ /**
36
+ * Outcome-based pricing configuration
37
+ */
38
+ interface OutcomeBasedPricing {
39
+ model: 'outcome-based';
40
+ outcomes: {
41
+ metric: string;
42
+ description?: string;
43
+ targetValue: number;
44
+ price: number;
45
+ unit?: string;
46
+ }[];
47
+ }
48
+ /**
49
+ * Union type for all pricing configurations
50
+ */
51
+ type ServicePricing = CostBasedPricing | MarginBasedPricing | ActivityBasedPricing | OutcomeBasedPricing;
52
+ /**
53
+ * Implementation types for services
54
+ */
55
+ type ImplementationType = 'function' | 'workflow' | 'agent';
56
+ /**
57
+ * Implementation details for a service
58
+ */
59
+ interface ImplementationDetails {
60
+ type: ImplementationType;
61
+ id: string;
62
+ version?: string;
63
+ configuration?: Record<string, any>;
64
+ }
65
+ /**
66
+ * Service definition with business model aspects
67
+ */
68
+ interface ServiceDefinition {
69
+ /**
70
+ * Service name
71
+ */
72
+ name: string;
73
+ /**
74
+ * Service description
75
+ */
76
+ description?: string;
77
+ /**
78
+ * Service objective
79
+ */
80
+ objective: Objective$1;
81
+ /**
82
+ * Key results for measuring service success
83
+ */
84
+ keyResults: KeyResult$1[];
85
+ /**
86
+ * Service pricing model
87
+ */
88
+ pricing: ServicePricing;
89
+ /**
90
+ * Implementation details
91
+ */
92
+ implementation: ImplementationDetails;
93
+ /**
94
+ * Additional metadata
95
+ */
96
+ metadata?: Record<string, any>;
97
+ }
98
+ /**
99
+ * Registered service with additional properties
100
+ */
101
+ interface RegisteredService extends ServiceDefinition {
102
+ /**
103
+ * Unique service identifier
104
+ */
105
+ id: string;
106
+ /**
107
+ * Service status
108
+ */
109
+ status: 'active' | 'inactive' | 'degraded';
110
+ /**
111
+ * Service endpoint URL
112
+ */
113
+ endpoint: string;
114
+ /**
115
+ * Creation timestamp
116
+ */
117
+ createdAt: string;
118
+ /**
119
+ * Last update timestamp
120
+ */
121
+ updatedAt: string;
122
+ }
123
+
124
+ interface Objective {
125
+ description: string;
126
+ keyResults: string[] | KeyResult[];
127
+ }
128
+ interface KeyResult {
129
+ description: string;
130
+ target?: number;
131
+ currentValue?: number;
132
+ unit?: string;
133
+ dueDate?: Date;
134
+ }
135
+
136
+ /**
137
+ * Calculate price for cost-based pricing model
138
+ * @param pricing Cost-based pricing configuration
139
+ * @param quantity Number of units
140
+ * @returns Calculated price
141
+ */
142
+ declare function calculateCostBasedPrice(pricing: CostBasedPricing, quantity?: number): number;
143
+ /**
144
+ * Calculate price for margin-based pricing model
145
+ * @param pricing Margin-based pricing configuration
146
+ * @param quantity Number of units
147
+ * @returns Calculated price
148
+ */
149
+ declare function calculateMarginBasedPrice(pricing: MarginBasedPricing, quantity?: number): number;
150
+ /**
151
+ * Calculate price for activity-based pricing model
152
+ * @param pricing Activity-based pricing configuration
153
+ * @param activities Record of activity names and their quantities
154
+ * @returns Calculated price
155
+ */
156
+ declare function calculateActivityBasedPrice(pricing: ActivityBasedPricing, activities: Record<string, number>): number;
157
+ /**
158
+ * Calculate price for outcome-based pricing model
159
+ * @param pricing Outcome-based pricing configuration
160
+ * @param outcomes Record of metric names and their achieved values
161
+ * @returns Calculated price
162
+ */
163
+ declare function calculateOutcomeBasedPrice(pricing: OutcomeBasedPricing, outcomes: Record<string, number>): number;
164
+ /**
165
+ * Calculate price based on the pricing model
166
+ * @param pricing Service pricing configuration
167
+ * @param params Additional parameters for price calculation
168
+ * @returns Calculated price
169
+ */
170
+ declare function calculatePrice(pricing: ServicePricing, params?: {
171
+ quantity?: number;
172
+ activities?: Record<string, number>;
173
+ outcomes?: Record<string, number>;
174
+ }): number;
175
+
176
+ /**
177
+ * Create a service with objectives, key results, and pricing models
178
+ * @param definition Service definition
179
+ * @returns Service object with additional methods
180
+ */
181
+ declare function Service(definition: ServiceDefinition): {
182
+ /**
183
+ * Calculate the price for this service
184
+ * @param params Parameters for price calculation
185
+ * @returns Calculated price
186
+ */
187
+ calculatePrice(params?: Parameters<typeof calculatePrice>[1]): number;
188
+ /**
189
+ * Register the service with the service registry
190
+ * @param options Optional configuration for service registration
191
+ * @returns Promise resolving to the registered service
192
+ */
193
+ register(options?: {
194
+ apiKey?: string;
195
+ baseUrl?: string;
196
+ }): Promise<RegisteredService>;
197
+ /**
198
+ * Track progress towards key results
199
+ * @param results Record of key result updates
200
+ */
201
+ trackProgress(results: Record<string, number>): void;
202
+ /**
203
+ * Check if all key results have been achieved
204
+ * @returns Whether all key results have been achieved
205
+ */
206
+ isObjectiveAchieved(): boolean;
207
+ name: string;
208
+ description?: string;
209
+ objective: Objective;
210
+ keyResults: KeyResult[];
211
+ pricing: ServicePricing;
212
+ implementation: ImplementationDetails;
213
+ metadata?: Record<string, any>;
214
+ };
215
+
216
+ export { type ActivityBasedPricing, type CostBasedPricing, type ImplementationDetails, type ImplementationType, type MarginBasedPricing, type OutcomeBasedPricing, type PricingModel, type RegisteredService, Service, type ServiceDefinition, type ServicePricing, calculateActivityBasedPrice, calculateCostBasedPrice, calculateMarginBasedPrice, calculateOutcomeBasedPrice, calculatePrice };
package/dist/index.js ADDED
@@ -0,0 +1,172 @@
1
+ // src/pricing/index.ts
2
+ function calculateCostBasedPrice(pricing, quantity = 1) {
3
+ const { costBase, fixedCosts = 0, variableCosts = 0 } = pricing;
4
+ return costBase + fixedCosts + variableCosts * quantity;
5
+ }
6
+ function calculateMarginBasedPrice(pricing, quantity = 1) {
7
+ const { costBase, marginPercentage } = pricing;
8
+ const cost = costBase * quantity;
9
+ const margin = cost * (marginPercentage / 100);
10
+ return cost + margin;
11
+ }
12
+ function calculateActivityBasedPrice(pricing, activities) {
13
+ return pricing.activities.reduce((total, activity) => {
14
+ const quantity = activities[activity.name] || 0;
15
+ return total + activity.rate * quantity;
16
+ }, 0);
17
+ }
18
+ function calculateOutcomeBasedPrice(pricing, outcomes) {
19
+ return pricing.outcomes.reduce((total, outcome) => {
20
+ const achievedValue = outcomes[outcome.metric] || 0;
21
+ if (achievedValue >= outcome.targetValue) {
22
+ return total + outcome.price;
23
+ }
24
+ return total;
25
+ }, 0);
26
+ }
27
+ function calculatePrice(pricing, params = {}) {
28
+ const { quantity = 1, activities = {}, outcomes = {} } = params;
29
+ switch (pricing.model) {
30
+ case "cost-based":
31
+ return calculateCostBasedPrice(pricing, quantity);
32
+ case "margin-based":
33
+ return calculateMarginBasedPrice(pricing, quantity);
34
+ case "activity-based":
35
+ return calculateActivityBasedPrice(pricing, activities);
36
+ case "outcome-based":
37
+ return calculateOutcomeBasedPrice(pricing, outcomes);
38
+ default:
39
+ throw new Error(`Unsupported pricing model: ${pricing.model}`);
40
+ }
41
+ }
42
+
43
+ // src/index.ts
44
+ function Service(definition) {
45
+ validateServiceDefinition(definition);
46
+ const service = {
47
+ ...definition,
48
+ /**
49
+ * Calculate the price for this service
50
+ * @param params Parameters for price calculation
51
+ * @returns Calculated price
52
+ */
53
+ calculatePrice(params) {
54
+ return calculatePrice(definition.pricing, params);
55
+ },
56
+ /**
57
+ * Register the service with the service registry
58
+ * @param options Optional configuration for service registration
59
+ * @returns Promise resolving to the registered service
60
+ */
61
+ async register(options) {
62
+ try {
63
+ const { Services } = await import("services.do");
64
+ const services = new Services(options);
65
+ const serviceDefinition = {
66
+ name: definition.name,
67
+ description: definition.description,
68
+ endpoint: `https://api.services.do/implementations/${definition.implementation.type}/${definition.implementation.id}`,
69
+ version: definition.implementation.version,
70
+ metadata: {
71
+ ...definition.metadata,
72
+ objective: definition.objective,
73
+ keyResults: definition.keyResults,
74
+ pricing: definition.pricing,
75
+ implementation: definition.implementation
76
+ }
77
+ };
78
+ const registeredService = await services.register(serviceDefinition);
79
+ return {
80
+ ...definition,
81
+ id: registeredService.id,
82
+ status: registeredService.status,
83
+ endpoint: registeredService.endpoint,
84
+ createdAt: registeredService.createdAt,
85
+ updatedAt: registeredService.updatedAt
86
+ };
87
+ } catch (error) {
88
+ console.warn("Failed to register with services.do, using mock implementation", error);
89
+ return {
90
+ ...definition,
91
+ id: generateId(),
92
+ status: "active",
93
+ endpoint: `https://api.services.do/services/${generateId()}`,
94
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
95
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
96
+ };
97
+ }
98
+ },
99
+ /**
100
+ * Track progress towards key results
101
+ * @param results Record of key result updates
102
+ */
103
+ trackProgress(results) {
104
+ definition.keyResults.forEach((kr) => {
105
+ if (kr.description in results) {
106
+ kr.currentValue = results[kr.description];
107
+ }
108
+ });
109
+ },
110
+ /**
111
+ * Check if all key results have been achieved
112
+ * @returns Whether all key results have been achieved
113
+ */
114
+ isObjectiveAchieved() {
115
+ return definition.keyResults.every((kr) => kr.currentValue !== void 0 && kr.target !== void 0 && kr.currentValue >= kr.target);
116
+ }
117
+ };
118
+ return service;
119
+ }
120
+ function validateServiceDefinition(definition) {
121
+ const { name, objective, keyResults, pricing, implementation } = definition;
122
+ if (!name) {
123
+ throw new Error("Service name is required");
124
+ }
125
+ if (!objective || !objective.description) {
126
+ throw new Error("Service objective with description is required");
127
+ }
128
+ if (!keyResults || !Array.isArray(keyResults) || keyResults.length === 0) {
129
+ throw new Error("At least one key result is required");
130
+ }
131
+ if (!pricing || !pricing.model) {
132
+ throw new Error("Service pricing model is required");
133
+ }
134
+ if (!implementation || !implementation.type || !implementation.id) {
135
+ throw new Error("Service implementation details are required");
136
+ }
137
+ switch (pricing.model) {
138
+ case "cost-based":
139
+ if (pricing.costBase === void 0) {
140
+ throw new Error("Cost base is required for cost-based pricing");
141
+ }
142
+ break;
143
+ case "margin-based":
144
+ if (pricing.costBase === void 0 || pricing.marginPercentage === void 0) {
145
+ throw new Error("Cost base and margin percentage are required for margin-based pricing");
146
+ }
147
+ break;
148
+ case "activity-based":
149
+ if (!pricing.activities || !Array.isArray(pricing.activities) || pricing.activities.length === 0) {
150
+ throw new Error("At least one activity is required for activity-based pricing");
151
+ }
152
+ break;
153
+ case "outcome-based":
154
+ if (!pricing.outcomes || !Array.isArray(pricing.outcomes) || pricing.outcomes.length === 0) {
155
+ throw new Error("At least one outcome is required for outcome-based pricing");
156
+ }
157
+ break;
158
+ default:
159
+ throw new Error(`Unsupported pricing model: ${pricing.model}`);
160
+ }
161
+ }
162
+ function generateId() {
163
+ return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
164
+ }
165
+ export {
166
+ Service,
167
+ calculateActivityBasedPrice,
168
+ calculateCostBasedPrice,
169
+ calculateMarginBasedPrice,
170
+ calculateOutcomeBasedPrice,
171
+ calculatePrice
172
+ };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "services-as-software",
3
+ "version": "0.1.0",
4
+ "description": "Define services with objectives, key results, and various pricing models",
5
+ "keywords": [
6
+ "services",
7
+ "business",
8
+ "pricing",
9
+ "objectives",
10
+ "key results",
11
+ "agentic"
12
+ ],
13
+ "homepage": "https://mdx.org.ai",
14
+ "type": "module",
15
+ "main": "dist/index.js",
16
+ "module": "dist/index.js",
17
+ "types": "dist/index.d.ts",
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsup src/index.ts --format esm --dts",
23
+ "dev": "tsup src/index.ts --format esm --dts --watch",
24
+ "lint": "eslint src --ext ts",
25
+ "clean": "rm -rf dist",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest"
28
+ },
29
+ "dependencies": {
30
+ "apis.do": "0.1.0",
31
+ "services.do": "workspace:*"
32
+ },
33
+ "devDependencies": {
34
+ "business-as-code": "0.0.2",
35
+ "tsup": "^8.0.1",
36
+ "typescript": "^5.2.2",
37
+ "vitest": "^0.34.6"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/drivly/ai.git",
42
+ "directory": "pkgs/services-as-software"
43
+ },
44
+ "bugs": {
45
+ "url": "https://github.com/drivly/ai/issues"
46
+ },
47
+ "author": "Drivly",
48
+ "license": "MIT"
49
+ }