File size: 2,991 Bytes
3cad23b
 
 
c07f594
 
3cad23b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c07f594
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import base64
import hashlib

import contextlib

from functools import wraps
from typing import Callable, Any
from inspect import signature, Parameter, Signature


def extract_substring(text, start_tag, end_tag):
    start_position = text.lower().find(start_tag.lower())
    end_position = text.lower().find(end_tag.lower())

    if start_position == -1 or end_position == -1:
        return None

    return text[start_position + len(start_tag):end_position].strip()

def compute_hash(s):
    # Hash a string using SHA-1 and return the base64 encoded result

    m = hashlib.sha1()
    m.update(s.encode())

    b = m.digest()

    return base64.b64encode(b).decode('ascii')

def add_params_and_annotations(name: str, description: str, params: dict, return_type: Any):
    """
    A decorator to add parameters and a return type annotation to a function.

    :param params: A dictionary where the keys are parameter names and values are their types.
    :param return_type: The return type to add to the function's signature.
    """
    def decorator(func: Callable):
        # Create new parameters based on the provided params dict
        new_params = [
            Parameter(name, Parameter.POSITIONAL_OR_KEYWORD, annotation=type_)
            for name, (type_, _) in params.items()
        ]
        
        # Get the existing signature and parameters
        original_sig = signature(func)
        original_params = list(original_sig.parameters.values())

        # Combine new parameters with the existing ones
        combined_params = new_params# + original_params

        # Create a new signature with updated parameters and return annotation
        new_sig = Signature(parameters=combined_params, return_annotation=return_type)
        
        # Define the wrapper function
        @wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)

        docstring = description

        if len(params) > 0:
            docstring += '\n\nArgs:'
            for param_name, (type_, param_description) in params.items():
                docstring += f'\n  {param_name}: {param_description}'
        
        docstring += f'\n\nReturns:\n  {return_type.__name__}'

        print('Input params:', params)


        # Set the new signature on the wrapper
        wrapper.__name__ = name
        wrapper.__signature__ = new_sig
        wrapper.__annotations__.update({ k: v[0] for k, v in params.items() })
        wrapper.__annotations__['return'] = return_type
        #wrapper.__annotations__['name'] = str
        wrapper.__doc__ = docstring

        print(docstring)

        return wrapper
    return decorator

_cost_tracker = {}

@contextlib.contextmanager
def use_cost_tracker():
    _cost_tracker.clear()
    _cost_tracker['conversation'] = 0
    _cost_tracker['negotiation'] = 0
    _cost_tracker['programming'] = 0
    yield

def register_cost(category, cost):
    _cost_tracker[category] += cost

def get_costs():
    return _cost_tracker